diff --git a/.gitignore b/.gitignore index 62c8935..72bfe1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.idea/ \ No newline at end of file +.idea/ +.env \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 27fddf4..2711f8e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,43 +1,7 @@ - -networks: - laravel: - services: - nginx: - build: - context: ./nginx - dockerfile: dockerfiles/nginx.dockerfile - args: - - UID=${UID:-1000} - - GID=${GID:-1000} - ports: - - "80:80" - volumes: - - ./php/src:/var/www/html:delegated - depends_on: - - php - - redis - - mysql - - mailhog - networks: - - laravel - - php: - build: - context: ./php - dockerfile: dockerfiles/php.dockerfile - args: - - UID=${UID:-1000} - - GID=${GID:-1000} - ports: - - "9000:9000" - volumes: - - ./php/src:/var/www/html:delegated - networks: - - laravel - python: + container_name: get_discography_python build: context: ./python dockerfile: dockerfiles/python.dockerfile @@ -53,133 +17,103 @@ services: depends_on: - redis networks: - - laravel + - lan - redis: - image: redis:alpine - restart: unless-stopped + postgres: + container_name: get_discography_postgres + image: postgres:12 ports: - - "6379:6379" - networks: - - laravel - - composer: - build: - context: ./php - dockerfile: dockerfiles/php.dockerfile - args: - - UID=${UID:-1000} - - GID=${GID:-1000} - volumes: - - ./php/src:/var/www/html - depends_on: - - php - entrypoint: [ 'composer', '--ignore-platform-reqs' ] - networks: - - laravel - - npm: - image: node:current-alpine - volumes: - - ./php/src:/var/www/html - ports: - - "3000:3000" - - "3001:3001" - - "5173:5173" - working_dir: /var/www/html - entrypoint: [ 'npm' ] - networks: - - laravel - - mysql: - image: mariadb:10.6 - restart: unless-stopped - tty: true - ports: - - "3306:3306" + - "5432:5432" environment: - MYSQL_DATABASE: homestead - MYSQL_USER: homestead - MYSQL_PASSWORD: secret - MYSQL_ROOT_PASSWORD: secret - SERVICE_TAGS: dev - SERVICE_NAME: mysql + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=temp_pg_pass + - POSTGRES_USER=odoo + - PGDATA=/var/lib/postgresql/data/pgdata networks: - - laravel - - artisan: - build: - context: ./php - dockerfile: dockerfiles/php.dockerfile - args: - - UID=${UID:-1000} - - GID=${GID:-1000} + - lan volumes: - - ./php/src:/var/www/html:delegated - depends_on: - - mysql - entrypoint: [ 'php', '/var/www/html/artisan' ] - networks: - - laravel + - pg-data:/var/lib/postgresql/data/pgdata - mailhog: - image: mailhog/mailhog:latest + redis: + container_name: get_discography_redis + image: redis:alpine + restart: unless-stopped ports: - - "1025:1025" - - "8025:8025" + - "6379:6379" networks: - - laravel + - lan - chrome: - image: selenium/node-chrome:nightly - shm_size: 4gb - networks: - - laravel - depends_on: - - selenium-hub - environment: - - SE_EVENT_BUS_HOST=selenium-hub - - SE_EVENT_BUS_PUBLISH_PORT=4442 - - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 - - SE_NODE_MAX_SESSIONS=2 - - SE_NODE_MAX_SESSION=2 + # sqlite: + # image: hibitdev/sqlite:latest + # container_name: get_discography_sqlite + # hostname: sqlite.app + # ports: + # - "8191:8191" + # volumes: + # - ./sqlite:/db + # command: ["tail", "-f", "/dev/null"] + # networks: + # - lan -# edge: -# image: selenium/node-edge:nightly -# shm_size: 8gb +# chrome: +# container_name: get_discography_chrome +# image: selenium/node-chrome:nightly +# shm_size: 1gb # networks: -# - laravel +# - lan # depends_on: # - selenium-hub # environment: # - SE_EVENT_BUS_HOST=selenium-hub # - SE_EVENT_BUS_PUBLISH_PORT=4442 # - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 -# - SE_NODE_MAX_SESSIONS=5 -# - SE_NODE_MAX_SESSION=5 +# - SE_NODE_MAX_SESSIONS=2 +# - SE_NODE_MAX_SESSION=2 # -# firefox: -# image: selenium/node-firefox:nightly -# shm_size: 8gb +# edge: +# container_name: get_discography_edge +# image: selenium/node-edge:nightly +# shm_size: 1gb # networks: -# - laravel +# - lan # depends_on: # - selenium-hub # environment: # - SE_EVENT_BUS_HOST=selenium-hub # - SE_EVENT_BUS_PUBLISH_PORT=4442 # - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 -# - SE_NODE_MAX_SESSIONS=5 -# - SE_NODE_MAX_SESSION=5 +# - SE_NODE_MAX_SESSIONS=2 +# - SE_NODE_MAX_SESSION=2 +# + firefox: + container_name: get_discography_firefox + image: selenium/node-firefox:nightly + shm_size: 4gb + networks: + - lan + depends_on: + - selenium-hub + environment: + - SE_EVENT_BUS_HOST=selenium-hub + - SE_EVENT_BUS_PUBLISH_PORT=4442 + - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + - SE_NODE_MAX_SESSIONS=2 + - SE_NODE_MAX_SESSION=2 selenium-hub: + container_name: get_discography_selenium-hub image: selenium/hub:latest networks: - - laravel + - lan environment: JAVA_OPTS: "-Xmx4g -Xms2g" - container_name: selenium-hub ports: - "4442:4442" - "4443:4443" - "4444:4444" + +networks: + lan: + +volumes: + pg-data: {} \ No newline at end of file diff --git a/nginx/conf/default.conf b/nginx/conf/default.conf index 282633d..b7f0c58 100644 --- a/nginx/conf/default.conf +++ b/nginx/conf/default.conf @@ -1,20 +1,12 @@ server { listen 80; - index index.php index.html; server_name _; - root /var/www/html/public; location / { - try_files $uri $uri/ /index.php?$query_string; + proxy_pass http://python:5000/; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Prefix /; } - - location ~ \.php$ { - try_files $uri =404; - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass php:9000; - fastcgi_index index.php; - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - } -} +} \ No newline at end of file diff --git a/nginx/dockerfiles/nginx.dockerfile b/nginx/dockerfiles/nginx.dockerfile index 154328c..a3aeaf6 100644 --- a/nginx/dockerfiles/nginx.dockerfile +++ b/nginx/dockerfiles/nginx.dockerfile @@ -9,9 +9,9 @@ ENV GID=${GID} # MacOS staff group's gid is 20, so is the dialout group in alpine linux. We're not using it, let's just remove it. RUN delgroup dialout -RUN addgroup -g ${GID} --system laravel -RUN adduser -G laravel --system -D -s /bin/sh -u ${UID} laravel -RUN sed -i "s/user nginx/user laravel/g" /etc/nginx/nginx.conf +RUN addgroup -g ${GID} --system www +RUN adduser -G www --system -D -s /bin/sh -u ${UID} www +RUN sed -i "s/user nginx/user www/g" /etc/nginx/nginx.conf ADD /conf/default.conf /etc/nginx/conf.d/ diff --git a/php/src/resources/views/pages/main.blade.php b/php/src/resources/views/pages/main.blade.php index fbbb0c0..e2af517 100644 --- a/php/src/resources/views/pages/main.blade.php +++ b/php/src/resources/views/pages/main.blade.php @@ -30,7 +30,7 @@ -{{-- --}} + Search diff --git a/python/.env.example b/python/.env.example new file mode 100644 index 0000000..6cbbf8e --- /dev/null +++ b/python/.env.example @@ -0,0 +1,5 @@ +DB_HOST=localhost +DB_PORT=5432 +DB_NAME=postgres +DB_USER=postgres +DB_PASS=password \ No newline at end of file diff --git a/python/__init__.py b/python/__init__.py index 8b13789..cc7fcc2 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -1 +1,3 @@ - +from . import api +from . import utils +from . import models \ No newline at end of file diff --git a/python/api/__init__.py b/python/api/__init__.py new file mode 100644 index 0000000..bfb4ceb --- /dev/null +++ b/python/api/__init__.py @@ -0,0 +1 @@ +from . import process diff --git a/python/api/process.py b/python/api/process.py new file mode 100644 index 0000000..2ff1879 --- /dev/null +++ b/python/api/process.py @@ -0,0 +1,24 @@ +import requests +from utils.download import download_album +import json + + +def process_artist_queue(): + print('Running Artist Queue process..') + print('---') + requests.get('http://nginx/api/queue/artists/run') + return + + +def process_album_queue(): + print('Running Album Queue Process..') + print('---') + response = requests.get('http://nginx/api/album/queue') + data = response.json() + artist = data.get('artist', False) + album = data.get('album', False) + queue = data.get('queue') + if not queue == False and artist and album: + result = download_album(album, artist) + requests.post('http://nginx/api/album/queue/update/%s' % queue.get('id'), json=result) + return diff --git a/python/app.py b/python/app.py index 2e235a5..eef1f03 100644 --- a/python/app.py +++ b/python/app.py @@ -1,41 +1,34 @@ -import json -from apscheduler.schedulers.background import BackgroundScheduler -from flask import Flask +from flask import Flask, render_template, jsonify from redis import Redis -from utils.download import download_album +from utils.database import DB as db + +import os import requests import logging _logger = logging.getLogger(__name__) +TEMPLATE_DIR = os.path.abspath('./templates') +STATIC_DIR = os.path.abspath('./static') -app = Flask(__name__) +app = Flask(__name__, template_folder=TEMPLATE_DIR, static_folder=STATIC_DIR) redis = Redis(host='redis', port=6379) -def process_artist_queue(): - print('Running Artist Queue process..') - print('---') - requests.get('http://nginx/api/queue/artists/run') - return - -def process_album_queue(): - print('Running Album Queue Process..') - print('---') - response = requests.get('http://nginx/api/album/queue') - data = response.json() - artist = data.get('artist', False) - album = data.get('album', False) - queue = data.get('queue') - if not queue == False and artist and album: - result = download_album(album, artist) - requests.post('http://nginx/api/album/queue/update/%s' % queue.get('id'), json=result) - return - -cron = BackgroundScheduler({'apscheduler.job_defaults.max_instances': 1}, daemon=True) -cron.add_job(process_album_queue, 'interval', minutes=1) -cron.add_job(process_artist_queue, 'interval', minutes=1) -cron.start() +@app.route('/api/artists') +def api_artists(): + return jsonify(db.get_all('artists')) + + +@app.route('/api/queue') +def api_queue(): + return jsonify(db.get_all('albums', where="done != true")) + + +@app.route('/') +def index(): + return render_template('app.html') + if __name__ == "__main__": print('Starting App...') diff --git a/python/models/__init__.py b/python/models/__init__.py new file mode 100644 index 0000000..9186ee3 --- /dev/null +++ b/python/models/__init__.py @@ -0,0 +1 @@ +from . import model diff --git a/python/models/model.py b/python/models/model.py new file mode 100644 index 0000000..96457ba --- /dev/null +++ b/python/models/model.py @@ -0,0 +1,30 @@ +from database import DB as db + + +def init(): + db.create_table( + "artists", + [ + ("id", "SERIAL", "PRIMARY KEY"), + ("name", "TEXT", "NOT NULL"), + ("url", "TEXT", "UNIQUE"), + ("thumbnail", "BYTEA", ""), + ("json", "JSON", ""), + ], + primary_key="id", + ) + + db.create_table( + "albums", + [ + ("id", "SERIAL", "PRIMARY KEY"), + ("artist_id", "SERIAL", "REFERENCES artists(id) ON DELETE CASCADE"), + ("name", "TEXT", "NOT NULL"), + ("url", "TEXT", "UNIQUE"), + ("thumbnail", "BYTEA", ""), + ("done", "BOOLEAN", ""), + ("json", "JSON", ""), + ], + primary_key="id", + ) + return True diff --git a/python/requirements.txt b/python/requirements.txt index 12e1aac..ab18225 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1,31 +1,6 @@ -apscheduler==3.10.1 -async-timeout==4.0.2 -beautifulsoup4==4.12.2 -Brotli==1.0.9 -certifi==2023.5.7 -charset-normalizer==3.1.0 -click==8.1.3 -filelock==3.12.2 -Flask==2.2.5 -idna==3.4 -importlib-metadata==6.6.0 -itsdangerous==2.1.2 -Jinja2==3.1.2 -MarkupSafe==2.1.3 -mutagen==1.46.0 -pycryptodomex==3.18.0 -pysondb-v2==2.0.0 -redis==4.5.5 -requests==2.31.0 -requests-file==1.5.1 -schedule==1.2.0 -six==1.16.0 -soupsieve==2.4.1 -tldextract==3.4.4 -typing_extensions==4.6.3 -urllib3==1.26.2 -websockets==11.0.3 -Werkzeug==2.2.3 -wget==3.2 -yt-dlp==2023.10.13 -zipp==3.15.0 +Flask +mp3-tagger +psycopg2-binary +redis +requests +yt-dlp diff --git a/python/static/.htaccess b/python/static/.htaccess new file mode 100644 index 0000000..3aec5e2 --- /dev/null +++ b/python/static/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Send Requests To Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/python/static/LICENSE.txt b/python/static/LICENSE.txt new file mode 100755 index 0000000..263df3d --- /dev/null +++ b/python/static/LICENSE.txt @@ -0,0 +1 @@ +If you use the icons publicly, please link to https://icons8.com/line-awesome somewhere on your page or artwork, so that more creators could know about it and use it for free. \ No newline at end of file diff --git a/python/static/css/datatables.css b/python/static/css/datatables.css new file mode 100644 index 0000000..f08bc89 --- /dev/null +++ b/python/static/css/datatables.css @@ -0,0 +1,781 @@ +@charset "UTF-8"; +:root { + --dt-row-selected: 13, 110, 253; + --dt-row-selected-text: 255, 255, 255; + --dt-row-selected-link: 9, 10, 11; + --dt-row-stripe: 0, 0, 0; + --dt-row-hover: 0, 0, 0; + --dt-column-ordering: 0, 0, 0; + --dt-html-background: white; +} +:root.dark { + --dt-html-background: rgb(33, 37, 41); +} + +table.dataTable td.dt-control { + text-align: center; + cursor: pointer; +} +table.dataTable td.dt-control:before { + display: inline-block; + box-sizing: border-box; + content: ""; + border-top: 5px solid transparent; + border-left: 10px solid rgba(0, 0, 0, 0.5); + border-bottom: 5px solid transparent; + border-right: 0px solid transparent; +} +table.dataTable tr.dt-hasChild td.dt-control:before { + border-top: 10px solid rgba(0, 0, 0, 0.5); + border-left: 5px solid transparent; + border-bottom: 0px solid transparent; + border-right: 5px solid transparent; +} + +html.dark table.dataTable td.dt-control:before, +:root[data-bs-theme=dark] table.dataTable td.dt-control:before, +:root[data-theme=dark] table.dataTable td.dt-control:before { + border-left-color: rgba(255, 255, 255, 0.5); +} +html.dark table.dataTable tr.dt-hasChild td.dt-control:before, +:root[data-bs-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before, +:root[data-theme=dark] table.dataTable tr.dt-hasChild td.dt-control:before { + border-top-color: rgba(255, 255, 255, 0.5); + border-left-color: transparent; +} + +div.dt-scroll { + width: 100%; +} + +div.dt-scroll-body thead tr, +div.dt-scroll-body tfoot tr { + height: 0; +} +div.dt-scroll-body thead tr th, div.dt-scroll-body thead tr td, +div.dt-scroll-body tfoot tr th, +div.dt-scroll-body tfoot tr td { + height: 0 !important; + padding-top: 0px !important; + padding-bottom: 0px !important; + border-top-width: 0px !important; + border-bottom-width: 0px !important; +} +div.dt-scroll-body thead tr th div.dt-scroll-sizing, div.dt-scroll-body thead tr td div.dt-scroll-sizing, +div.dt-scroll-body tfoot tr th div.dt-scroll-sizing, +div.dt-scroll-body tfoot tr td div.dt-scroll-sizing { + height: 0 !important; + overflow: hidden !important; +} + +table.dataTable thead > tr > th:active, +table.dataTable thead > tr > td:active { + outline: none; +} +table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before { + position: absolute; + display: block; + bottom: 50%; + content: "▲"; + content: "▲"/""; +} +table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after { + position: absolute; + display: block; + top: 50%; + content: "▼"; + content: "▼"/""; +} +table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc, table.dataTable thead > tr > th.dt-ordering-asc, table.dataTable thead > tr > th.dt-ordering-desc, +table.dataTable thead > tr > td.dt-orderable-asc, +table.dataTable thead > tr > td.dt-orderable-desc, +table.dataTable thead > tr > td.dt-ordering-asc, +table.dataTable thead > tr > td.dt-ordering-desc { + position: relative; + padding-right: 30px; +} +table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order, +table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order, +table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order { + position: absolute; + right: 12px; + top: 0; + bottom: 0; + width: 12px; +} +table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-orderable-asc span.dt-column-order:after, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:before, table.dataTable thead > tr > th.dt-orderable-desc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:after, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-orderable-asc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-orderable-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after { + left: 0; + opacity: 0.125; + line-height: 9px; + font-size: 0.8em; +} +table.dataTable thead > tr > th.dt-orderable-asc, table.dataTable thead > tr > th.dt-orderable-desc, +table.dataTable thead > tr > td.dt-orderable-asc, +table.dataTable thead > tr > td.dt-orderable-desc { + cursor: pointer; +} +table.dataTable thead > tr > th.dt-orderable-asc:hover, table.dataTable thead > tr > th.dt-orderable-desc:hover, +table.dataTable thead > tr > td.dt-orderable-asc:hover, +table.dataTable thead > tr > td.dt-orderable-desc:hover { + outline: 2px solid rgba(0, 0, 0, 0.05); + outline-offset: -2px; +} +table.dataTable thead > tr > th.dt-ordering-asc span.dt-column-order:before, table.dataTable thead > tr > th.dt-ordering-desc span.dt-column-order:after, +table.dataTable thead > tr > td.dt-ordering-asc span.dt-column-order:before, +table.dataTable thead > tr > td.dt-ordering-desc span.dt-column-order:after { + opacity: 0.6; +} +table.dataTable thead > tr > th.sorting_desc_disabled span.dt-column-order:after, table.dataTable thead > tr > th.sorting_asc_disabled span.dt-column-order:before, +table.dataTable thead > tr > td.sorting_desc_disabled span.dt-column-order:after, +table.dataTable thead > tr > td.sorting_asc_disabled span.dt-column-order:before { + display: none; +} +table.dataTable thead > tr > th:active, +table.dataTable thead > tr > td:active { + outline: none; +} + +div.dt-scroll-body > table.dataTable > thead > tr > th, +div.dt-scroll-body > table.dataTable > thead > tr > td { + overflow: hidden; +} + +:root.dark table.dataTable thead > tr > th.dt-orderable-asc:hover, :root.dark table.dataTable thead > tr > th.dt-orderable-desc:hover, +:root.dark table.dataTable thead > tr > td.dt-orderable-asc:hover, +:root.dark table.dataTable thead > tr > td.dt-orderable-desc:hover, +:root[data-bs-theme=dark] table.dataTable thead > tr > th.dt-orderable-asc:hover, +:root[data-bs-theme=dark] table.dataTable thead > tr > th.dt-orderable-desc:hover, +:root[data-bs-theme=dark] table.dataTable thead > tr > td.dt-orderable-asc:hover, +:root[data-bs-theme=dark] table.dataTable thead > tr > td.dt-orderable-desc:hover { + outline: 2px solid rgba(255, 255, 255, 0.05); +} + +div.dt-processing { + position: absolute; + top: 50%; + left: 50%; + width: 200px; + margin-left: -100px; + margin-top: -22px; + text-align: center; + padding: 2px; + z-index: 10; +} +div.dt-processing > div:last-child { + position: relative; + width: 80px; + height: 15px; + margin: 1em auto; +} +div.dt-processing > div:last-child > div { + position: absolute; + top: 0; + width: 13px; + height: 13px; + border-radius: 50%; + background: rgb(13, 110, 253); + background: rgb(var(--dt-row-selected)); + animation-timing-function: cubic-bezier(0, 1, 1, 0); +} +div.dt-processing > div:last-child > div:nth-child(1) { + left: 8px; + animation: datatables-loader-1 0.6s infinite; +} +div.dt-processing > div:last-child > div:nth-child(2) { + left: 8px; + animation: datatables-loader-2 0.6s infinite; +} +div.dt-processing > div:last-child > div:nth-child(3) { + left: 32px; + animation: datatables-loader-2 0.6s infinite; +} +div.dt-processing > div:last-child > div:nth-child(4) { + left: 56px; + animation: datatables-loader-3 0.6s infinite; +} + +@keyframes datatables-loader-1 { + 0% { + transform: scale(0); + } + 100% { + transform: scale(1); + } +} +@keyframes datatables-loader-3 { + 0% { + transform: scale(1); + } + 100% { + transform: scale(0); + } +} +@keyframes datatables-loader-2 { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(24px, 0); + } +} +table.dataTable.nowrap th, table.dataTable.nowrap td { + white-space: nowrap; +} +table.dataTable th, +table.dataTable td { + box-sizing: border-box; +} +table.dataTable th.dt-left, +table.dataTable td.dt-left { + text-align: left; +} +table.dataTable th.dt-center, +table.dataTable td.dt-center { + text-align: center; +} +table.dataTable th.dt-right, +table.dataTable td.dt-right { + text-align: right; +} +table.dataTable th.dt-justify, +table.dataTable td.dt-justify { + text-align: justify; +} +table.dataTable th.dt-nowrap, +table.dataTable td.dt-nowrap { + white-space: nowrap; +} +table.dataTable th.dt-empty, +table.dataTable td.dt-empty { + text-align: center; + vertical-align: top; +} +table.dataTable th.dt-type-numeric, table.dataTable th.dt-type-date, +table.dataTable td.dt-type-numeric, +table.dataTable td.dt-type-date { + text-align: right; +} +table.dataTable thead th, +table.dataTable thead td, +table.dataTable tfoot th, +table.dataTable tfoot td { + text-align: left; +} +table.dataTable thead th.dt-head-left, +table.dataTable thead td.dt-head-left, +table.dataTable tfoot th.dt-head-left, +table.dataTable tfoot td.dt-head-left { + text-align: left; +} +table.dataTable thead th.dt-head-center, +table.dataTable thead td.dt-head-center, +table.dataTable tfoot th.dt-head-center, +table.dataTable tfoot td.dt-head-center { + text-align: center; +} +table.dataTable thead th.dt-head-right, +table.dataTable thead td.dt-head-right, +table.dataTable tfoot th.dt-head-right, +table.dataTable tfoot td.dt-head-right { + text-align: right; +} +table.dataTable thead th.dt-head-justify, +table.dataTable thead td.dt-head-justify, +table.dataTable tfoot th.dt-head-justify, +table.dataTable tfoot td.dt-head-justify { + text-align: justify; +} +table.dataTable thead th.dt-head-nowrap, +table.dataTable thead td.dt-head-nowrap, +table.dataTable tfoot th.dt-head-nowrap, +table.dataTable tfoot td.dt-head-nowrap { + white-space: nowrap; +} +table.dataTable tbody th.dt-body-left, +table.dataTable tbody td.dt-body-left { + text-align: left; +} +table.dataTable tbody th.dt-body-center, +table.dataTable tbody td.dt-body-center { + text-align: center; +} +table.dataTable tbody th.dt-body-right, +table.dataTable tbody td.dt-body-right { + text-align: right; +} +table.dataTable tbody th.dt-body-justify, +table.dataTable tbody td.dt-body-justify { + text-align: justify; +} +table.dataTable tbody th.dt-body-nowrap, +table.dataTable tbody td.dt-body-nowrap { + white-space: nowrap; +} + +/* + * Table styles + */ +table.dataTable { + width: 100%; + margin: 0 auto; + border-spacing: 0; + /* + * Header and footer styles + */ + /* + * Body styles + */ +} +table.dataTable thead th, +table.dataTable tfoot th { + font-weight: bold; +} +table.dataTable > thead > tr > th, +table.dataTable > thead > tr > td { + padding: 10px; + border-bottom: 1px solid rgba(0, 0, 0, 0.3); +} +table.dataTable > thead > tr > th:active, +table.dataTable > thead > tr > td:active { + outline: none; +} +table.dataTable > tfoot > tr > th, +table.dataTable > tfoot > tr > td { + border-top: 1px solid rgba(0, 0, 0, 0.3); + padding: 10px 10px 6px 10px; +} +table.dataTable > tbody > tr { + background-color: transparent; +} +table.dataTable > tbody > tr:first-child > * { + border-top: none; +} +table.dataTable > tbody > tr:last-child > * { + border-bottom: none; +} +table.dataTable > tbody > tr.selected > * { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.9); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.9); + color: rgb(255, 255, 255); + color: rgb(var(--dt-row-selected-text)); +} +table.dataTable > tbody > tr.selected a { + color: rgb(9, 10, 11); + color: rgb(var(--dt-row-selected-link)); +} +table.dataTable > tbody > tr > th, +table.dataTable > tbody > tr > td { + padding: 8px 10px; +} +table.dataTable.row-border > tbody > tr > *, table.dataTable.display > tbody > tr > * { + border-top: 1px solid rgba(0, 0, 0, 0.15); +} +table.dataTable.row-border > tbody > tr:first-child > *, table.dataTable.display > tbody > tr:first-child > * { + border-top: none; +} +table.dataTable.row-border > tbody > tr.selected + tr.selected > td, table.dataTable.display > tbody > tr.selected + tr.selected > td { + border-top-color: rgba(13, 110, 253, 0.65); + border-top-color: rgba(var(--dt-row-selected), 0.65); +} +table.dataTable.cell-border > tbody > tr > * { + border-top: 1px solid rgba(0, 0, 0, 0.15); + border-right: 1px solid rgba(0, 0, 0, 0.15); +} +table.dataTable.cell-border > tbody > tr > *:first-child { + border-left: 1px solid rgba(0, 0, 0, 0.15); +} +table.dataTable.cell-border > tbody > tr:first-child > * { + border-top: 1px solid rgba(0, 0, 0, 0.3); +} +table.dataTable.stripe > tbody > tr:nth-child(odd) > *, table.dataTable.display > tbody > tr:nth-child(odd) > * { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.023); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-stripe), 0.023); +} +table.dataTable.stripe > tbody > tr:nth-child(odd).selected > *, table.dataTable.display > tbody > tr:nth-child(odd).selected > * { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.923); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.923); +} +table.dataTable.hover > tbody > tr:hover > *, table.dataTable.display > tbody > tr:hover > * { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.035); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.035); +} +table.dataTable.hover > tbody > tr.selected:hover > *, table.dataTable.display > tbody > tr.selected:hover > * { + box-shadow: inset 0 0 0 9999px #0d6efd !important; + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 1) !important; +} +table.dataTable.order-column > tbody tr > .sorting_1, +table.dataTable.order-column > tbody tr > .sorting_2, +table.dataTable.order-column > tbody tr > .sorting_3, table.dataTable.display > tbody tr > .sorting_1, +table.dataTable.display > tbody tr > .sorting_2, +table.dataTable.display > tbody tr > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.019); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.019); +} +table.dataTable.order-column > tbody tr.selected > .sorting_1, +table.dataTable.order-column > tbody tr.selected > .sorting_2, +table.dataTable.order-column > tbody tr.selected > .sorting_3, table.dataTable.display > tbody tr.selected > .sorting_1, +table.dataTable.display > tbody tr.selected > .sorting_2, +table.dataTable.display > tbody tr.selected > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.919); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.919); +} +table.dataTable.display > tbody > tr:nth-child(odd) > .sorting_1, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd) > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.054); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.054); +} +table.dataTable.display > tbody > tr:nth-child(odd) > .sorting_2, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd) > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.047); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.047); +} +table.dataTable.display > tbody > tr:nth-child(odd) > .sorting_3, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd) > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.039); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.039); +} +table.dataTable.display > tbody > tr:nth-child(odd).selected > .sorting_1, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd).selected > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.954); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.954); +} +table.dataTable.display > tbody > tr:nth-child(odd).selected > .sorting_2, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd).selected > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.947); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.947); +} +table.dataTable.display > tbody > tr:nth-child(odd).selected > .sorting_3, table.dataTable.order-column.stripe > tbody > tr:nth-child(odd).selected > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.939); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.939); +} +table.dataTable.display > tbody > tr.even > .sorting_1, table.dataTable.order-column.stripe > tbody > tr.even > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.019); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.019); +} +table.dataTable.display > tbody > tr.even > .sorting_2, table.dataTable.order-column.stripe > tbody > tr.even > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.011); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.011); +} +table.dataTable.display > tbody > tr.even > .sorting_3, table.dataTable.order-column.stripe > tbody > tr.even > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.003); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-column-ordering), 0.003); +} +table.dataTable.display > tbody > tr.even.selected > .sorting_1, table.dataTable.order-column.stripe > tbody > tr.even.selected > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.919); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.919); +} +table.dataTable.display > tbody > tr.even.selected > .sorting_2, table.dataTable.order-column.stripe > tbody > tr.even.selected > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.911); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.911); +} +table.dataTable.display > tbody > tr.even.selected > .sorting_3, table.dataTable.order-column.stripe > tbody > tr.even.selected > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.903); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.903); +} +table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.082); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.082); +} +table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.074); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.074); +} +table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.062); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-hover), 0.062); +} +table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.982); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.982); +} +table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.974); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.974); +} +table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 { + box-shadow: inset 0 0 0 9999px rgba(13, 110, 253, 0.962); + box-shadow: inset 0 0 0 9999px rgba(var(--dt-row-selected), 0.962); +} +table.dataTable.compact thead th, +table.dataTable.compact thead td, +table.dataTable.compact tfoot th, +table.dataTable.compact tfoot td, +table.dataTable.compact tbody th, +table.dataTable.compact tbody td { + padding: 4px; +} + +div.dt-container div.dt-layout-row { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + margin: 0.75em 0; +} +div.dt-container div.dt-layout-row div.dt-layout-cell { + display: flex; + justify-content: space-between; + align-items: center; +} +div.dt-container div.dt-layout-row div.dt-layout-cell.dt-layout-start { + justify-content: flex-start; + margin-right: auto; +} +div.dt-container div.dt-layout-row div.dt-layout-cell.dt-layout-end { + justify-content: flex-end; + margin-left: auto; +} +div.dt-container div.dt-layout-row div.dt-layout-cell:empty { + display: none; +} + +@media screen and (max-width: 767px) { + div.dt-container div.dt-layout-row:not(.dt-layout-table) { + display: block; + } + div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell { + display: block; + text-align: center; + } + div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell > * { + margin: 0.5em 0; + } + div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell.dt-layout-start { + margin-right: 0; + } + div.dt-container div.dt-layout-row:not(.dt-layout-table) div.dt-layout-cell.dt-layout-end { + margin-left: 0; + } +} +div.dt-container div.dt-layout-start > *:not(:last-child) { + margin-right: 1em; +} +div.dt-container div.dt-layout-end > *:not(:first-child) { + margin-left: 1em; +} +div.dt-container div.dt-layout-full { + width: 100%; +} +div.dt-container div.dt-layout-full > *:only-child { + margin-left: auto; + margin-right: auto; +} +div.dt-container div.dt-layout-table > div { + display: block !important; +} + +@media screen and (max-width: 767px) { + div.dt-container div.dt-layout-start > *:not(:last-child) { + margin-right: 0; + } + div.dt-container div.dt-layout-end > *:not(:first-child) { + margin-left: 0; + } +} +/* + * Control feature layout + */ +div.dt-container { + position: relative; + clear: both; +} +div.dt-container .dt-search input { + border: 1px solid #aaa; + border-radius: 3px; + padding: 5px; + background-color: transparent; + color: inherit; + margin-left: 3px; +} +div.dt-container .dt-input { + border: 1px solid #aaa; + border-radius: 3px; + padding: 5px; + background-color: transparent; + color: inherit; +} +div.dt-container select.dt-input { + padding: 4px; +} +div.dt-container .dt-paging .dt-paging-button { + box-sizing: border-box; + display: inline-block; + min-width: 1.5em; + padding: 0.5em 1em; + margin-left: 2px; + text-align: center; + text-decoration: none !important; + cursor: pointer; + color: inherit !important; + border: 1px solid transparent; + border-radius: 2px; + background: transparent; +} +div.dt-container .dt-paging .dt-paging-button.current, div.dt-container .dt-paging .dt-paging-button.current:hover { + color: inherit !important; + border: 1px solid rgba(0, 0, 0, 0.3); + background-color: rgba(0, 0, 0, 0.05); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(230, 230, 230, 0.05)), color-stop(100%, rgba(0, 0, 0, 0.05))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* FF3.6+ */ + background: -ms-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* IE10+ */ + background: -o-linear-gradient(top, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* Opera 11.10+ */ + background: linear-gradient(to bottom, rgba(230, 230, 230, 0.05) 0%, rgba(0, 0, 0, 0.05) 100%); /* W3C */ +} +div.dt-container .dt-paging .dt-paging-button.disabled, div.dt-container .dt-paging .dt-paging-button.disabled:hover, div.dt-container .dt-paging .dt-paging-button.disabled:active { + cursor: default; + color: rgba(0, 0, 0, 0.5) !important; + border: 1px solid transparent; + background: transparent; + box-shadow: none; +} +div.dt-container .dt-paging .dt-paging-button:hover { + color: white !important; + border: 1px solid #111; + background-color: #111; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #585858 0%, #111 100%); /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, #585858 0%, #111 100%); /* FF3.6+ */ + background: -ms-linear-gradient(top, #585858 0%, #111 100%); /* IE10+ */ + background: -o-linear-gradient(top, #585858 0%, #111 100%); /* Opera 11.10+ */ + background: linear-gradient(to bottom, #585858 0%, #111 100%); /* W3C */ +} +div.dt-container .dt-paging .dt-paging-button:active { + outline: none; + background-color: #0c0c0c; + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* Chrome10+,Safari5.1+ */ + background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* FF3.6+ */ + background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* IE10+ */ + background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%); /* Opera 11.10+ */ + background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%); /* W3C */ + box-shadow: inset 0 0 3px #111; +} +div.dt-container .dt-paging .ellipsis { + padding: 0 1em; +} +div.dt-container .dt-length, +div.dt-container .dt-search, +div.dt-container .dt-info, +div.dt-container .dt-processing, +div.dt-container .dt-paging { + color: inherit; +} +div.dt-container .dataTables_scroll { + clear: both; +} +div.dt-container .dataTables_scroll div.dt-scroll-body { + -webkit-overflow-scrolling: touch; +} +div.dt-container .dataTables_scroll div.dt-scroll-body > table > thead > tr > th, div.dt-container .dataTables_scroll div.dt-scroll-body > table > thead > tr > td, div.dt-container .dataTables_scroll div.dt-scroll-body > table > tbody > tr > th, div.dt-container .dataTables_scroll div.dt-scroll-body > table > tbody > tr > td { + vertical-align: middle; +} +div.dt-container .dataTables_scroll div.dt-scroll-body > table > thead > tr > th > div.dataTables_sizing, +div.dt-container .dataTables_scroll div.dt-scroll-body > table > thead > tr > td > div.dataTables_sizing, div.dt-container .dataTables_scroll div.dt-scroll-body > table > tbody > tr > th > div.dataTables_sizing, +div.dt-container .dataTables_scroll div.dt-scroll-body > table > tbody > tr > td > div.dataTables_sizing { + height: 0; + overflow: hidden; + margin: 0 !important; + padding: 0 !important; +} +div.dt-container.dt-empty-footer tbody > tr:last-child > * { + border-bottom: 1px solid rgba(0, 0, 0, 0.3); +} +div.dt-container.dt-empty-footer .dt-scroll-body { + border-bottom: 1px solid rgba(0, 0, 0, 0.3); +} +div.dt-container.dt-empty-footer .dt-scroll-body tbody > tr:last-child > * { + border-bottom: none; +} + +html.dark { + --dt-row-hover: 255, 255, 255; + --dt-row-stripe: 255, 255, 255; + --dt-column-ordering: 255, 255, 255; +} +html.dark table.dataTable > thead > tr > th, +html.dark table.dataTable > thead > tr > td { + border-bottom: 1px solid rgb(89, 91, 94); +} +html.dark table.dataTable > thead > tr > th:active, +html.dark table.dataTable > thead > tr > td:active { + outline: none; +} +html.dark table.dataTable > tfoot > tr > th, +html.dark table.dataTable > tfoot > tr > td { + border-top: 1px solid rgb(89, 91, 94); +} +html.dark table.dataTable.row-border > tbody > tr > *, html.dark table.dataTable.display > tbody > tr > * { + border-top: 1px solid rgb(64, 67, 70); +} +html.dark table.dataTable.row-border > tbody > tr:first-child > *, html.dark table.dataTable.display > tbody > tr:first-child > * { + border-top: none; +} +html.dark table.dataTable.row-border > tbody > tr.selected + tr.selected > td, html.dark table.dataTable.display > tbody > tr.selected + tr.selected > td { + border-top-color: rgba(13, 110, 253, 0.65); + border-top-color: rgba(var(--dt-row-selected), 0.65); +} +html.dark table.dataTable.cell-border > tbody > tr > th, +html.dark table.dataTable.cell-border > tbody > tr > td { + border-top: 1px solid rgb(64, 67, 70); + border-right: 1px solid rgb(64, 67, 70); +} +html.dark table.dataTable.cell-border > tbody > tr > th:first-child, +html.dark table.dataTable.cell-border > tbody > tr > td:first-child { + border-left: 1px solid rgb(64, 67, 70); +} +html.dark .dt-container.dt-empty-footer table.dataTable { + border-bottom: 1px solid rgb(89, 91, 94); +} +html.dark .dt-container .dt-search input, +html.dark .dt-container .dt-length select { + border: 1px solid rgba(255, 255, 255, 0.2); + background-color: var(--dt-html-background); +} +html.dark .dt-container .dt-paging .dt-paging-button.current, html.dark .dt-container .dt-paging .dt-paging-button.current:hover { + border: 1px solid rgb(89, 91, 94); + background: rgba(255, 255, 255, 0.15); +} +html.dark .dt-container .dt-paging .dt-paging-button.disabled, html.dark .dt-container .dt-paging .dt-paging-button.disabled:hover, html.dark .dt-container .dt-paging .dt-paging-button.disabled:active { + color: #666 !important; +} +html.dark .dt-container .dt-paging .dt-paging-button:hover { + border: 1px solid rgb(53, 53, 53); + background: rgb(53, 53, 53); +} +html.dark .dt-container .dt-paging .dt-paging-button:active { + background: #3a3a3a; +} + +/* + * Overrides for RTL support + */ +*[dir=rtl] table.dataTable thead th, +*[dir=rtl] table.dataTable thead td, +*[dir=rtl] table.dataTable tfoot th, +*[dir=rtl] table.dataTable tfoot td { + text-align: right; +} +*[dir=rtl] table.dataTable th.dt-type-numeric, *[dir=rtl] table.dataTable th.dt-type-date, +*[dir=rtl] table.dataTable td.dt-type-numeric, +*[dir=rtl] table.dataTable td.dt-type-date { + text-align: left; +} +*[dir=rtl] div.dt-container div.dt-layout-cell.dt-start { + text-align: right; +} +*[dir=rtl] div.dt-container div.dt-layout-cell.dt-end { + text-align: left; +} +*[dir=rtl] div.dt-container div.dt-search input { + margin: 0 3px 0 0; +} diff --git a/python/static/css/line-awesome.css b/python/static/css/line-awesome.css new file mode 100644 index 0000000..3e9d858 --- /dev/null +++ b/python/static/css/line-awesome.css @@ -0,0 +1,6582 @@ +.la, +.las, +.lar, +.lal, +.lad, +.lab { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: inline-block; + font-style: normal; + font-variant: normal; + text-rendering: auto; + line-height: 1; } + +.la-lg { + font-size: 1.33333em; + line-height: 0.75em; + vertical-align: -.0667em; } + +.la-xs { + font-size: .75em; } + +.la-sm { + font-size: .875em; } + +.la-1x { + font-size: 1em; } + +.la-2x { + font-size: 2em; } + +.la-3x { + font-size: 3em; } + +.la-4x { + font-size: 4em; } + +.la-5x { + font-size: 5em; } + +.la-6x { + font-size: 6em; } + +.la-7x { + font-size: 7em; } + +.la-8x { + font-size: 8em; } + +.la-9x { + font-size: 9em; } + +.la-10x { + font-size: 10em; } + +.la-fw { + text-align: center; + width: 1.25em; } + +.la-ul { + list-style-type: none; + margin-left: 2.5em; + padding-left: 0; } + .la-ul > li { + position: relative; } + +.la-li { + left: -2em; + position: absolute; + text-align: center; + width: 2em; + line-height: inherit; } + +.la-border { + border: solid 0.08em #eee; + border-radius: .1em; + padding: .2em .25em .15em; } + +.la-pull-left { + float: left; } + +.la-pull-right { + float: right; } + +.la.la-pull-left, +.las.la-pull-left, +.lar.la-pull-left, +.lal.la-pull-left, +.lab.la-pull-left { + margin-right: .3em; } + +.la.la-pull-right, +.las.la-pull-right, +.lar.la-pull-right, +.lal.la-pull-right, +.lab.la-pull-right { + margin-left: .3em; } + +.la-spin { + -webkit-animation: la-spin 2s infinite linear; + animation: la-spin 2s infinite linear; } + +.la-pulse { + -webkit-animation: la-spin 1s infinite steps(8); + animation: la-spin 1s infinite steps(8); } + +@-webkit-keyframes la-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes la-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +.la-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); } + +.la-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + +.la-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + transform: rotate(270deg); } + +.la-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); } + +.la-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + transform: scale(1, -1); } + +.la-flip-both, .la-flip-horizontal.la-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(-1, -1); + transform: scale(-1, -1); } + +:root .la-rotate-90, +:root .la-rotate-180, +:root .la-rotate-270, +:root .la-flip-horizontal, +:root .la-flip-vertical, +:root .la-flip-both { + -webkit-filter: none; + filter: none; } + +.la-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: middle; + width: 2.5em; } + +.la-stack-1x, +.la-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; } + +.la-stack-1x { + line-height: inherit; } + +.la-stack-2x { + font-size: 2em; } + +.la-inverse { + color: #fff; } + +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ +.la-500px:before { + content: "\f26e"; } + +.la-accessible-icon:before { + content: "\f368"; } + +.la-accusoft:before { + content: "\f369"; } + +.la-acquisitions-incorporated:before { + content: "\f6af"; } + +.la-ad:before { + content: "\f641"; } + +.la-address-book:before { + content: "\f2b9"; } + +.la-address-card:before { + content: "\f2bb"; } + +.la-adjust:before { + content: "\f042"; } + +.la-adn:before { + content: "\f170"; } + +.la-adobe:before { + content: "\f778"; } + +.la-adversal:before { + content: "\f36a"; } + +.la-affiliatetheme:before { + content: "\f36b"; } + +.la-air-freshener:before { + content: "\f5d0"; } + +.la-airbnb:before { + content: "\f834"; } + +.la-algolia:before { + content: "\f36c"; } + +.la-align-center:before { + content: "\f037"; } + +.la-align-justify:before { + content: "\f039"; } + +.la-align-left:before { + content: "\f036"; } + +.la-align-right:before { + content: "\f038"; } + +.la-alipay:before { + content: "\f642"; } + +.la-allergies:before { + content: "\f461"; } + +.la-amazon:before { + content: "\f270"; } + +.la-amazon-pay:before { + content: "\f42c"; } + +.la-ambulance:before { + content: "\f0f9"; } + +.la-american-sign-language-interpreting:before { + content: "\f2a3"; } + +.la-amilia:before { + content: "\f36d"; } + +.la-anchor:before { + content: "\f13d"; } + +.la-android:before { + content: "\f17b"; } + +.la-angellist:before { + content: "\f209"; } + +.la-angle-double-down:before { + content: "\f103"; } + +.la-angle-double-left:before { + content: "\f100"; } + +.la-angle-double-right:before { + content: "\f101"; } + +.la-angle-double-up:before { + content: "\f102"; } + +.la-angle-down:before { + content: "\f107"; } + +.la-angle-left:before { + content: "\f104"; } + +.la-angle-right:before { + content: "\f105"; } + +.la-angle-up:before { + content: "\f106"; } + +.la-angry:before { + content: "\f556"; } + +.la-angrycreative:before { + content: "\f36e"; } + +.la-angular:before { + content: "\f420"; } + +.la-ankh:before { + content: "\f644"; } + +.la-app-store:before { + content: "\f36f"; } + +.la-app-store-ios:before { + content: "\f370"; } + +.la-apper:before { + content: "\f371"; } + +.la-apple:before { + content: "\f179"; } + +.la-apple-alt:before { + content: "\f5d1"; } + +.la-apple-pay:before { + content: "\f415"; } + +.la-archive:before { + content: "\f187"; } + +.la-archway:before { + content: "\f557"; } + +.la-arrow-alt-circle-down:before { + content: "\f358"; } + +.la-arrow-alt-circle-left:before { + content: "\f359"; } + +.la-arrow-alt-circle-right:before { + content: "\f35a"; } + +.la-arrow-alt-circle-up:before { + content: "\f35b"; } + +.la-arrow-circle-down:before { + content: "\f0ab"; } + +.la-arrow-circle-left:before { + content: "\f0a8"; } + +.la-arrow-circle-right:before { + content: "\f0a9"; } + +.la-arrow-circle-up:before { + content: "\f0aa"; } + +.la-arrow-down:before { + content: "\f063"; } + +.la-arrow-left:before { + content: "\f060"; } + +.la-arrow-right:before { + content: "\f061"; } + +.la-arrow-up:before { + content: "\f062"; } + +.la-arrows-alt:before { + content: "\f0b2"; } + +.la-arrows-alt-h:before { + content: "\f337"; } + +.la-arrows-alt-v:before { + content: "\f338"; } + +.la-artstation:before { + content: "\f77a"; } + +.la-assistive-listening-systems:before { + content: "\f2a2"; } + +.la-asterisk:before { + content: "\f069"; } + +.la-asymmetrik:before { + content: "\f372"; } + +.la-at:before { + content: "\f1fa"; } + +.la-atlas:before { + content: "\f558"; } + +.la-atlassian:before { + content: "\f77b"; } + +.la-atom:before { + content: "\f5d2"; } + +.la-audible:before { + content: "\f373"; } + +.la-audio-description:before { + content: "\f29e"; } + +.la-autoprefixer:before { + content: "\f41c"; } + +.la-avianex:before { + content: "\f374"; } + +.la-aviato:before { + content: "\f421"; } + +.la-award:before { + content: "\f559"; } + +.la-aws:before { + content: "\f375"; } + +.la-baby:before { + content: "\f77c"; } + +.la-baby-carriage:before { + content: "\f77d"; } + +.la-backspace:before { + content: "\f55a"; } + +.la-backward:before { + content: "\f04a"; } + +.la-bacon:before { + content: "\f7e5"; } + +.la-balance-scale:before { + content: "\f24e"; } + +.la-balance-scale-left:before { + content: "\f515"; } + +.la-balance-scale-right:before { + content: "\f516"; } + +.la-ban:before { + content: "\f05e"; } + +.la-band-aid:before { + content: "\f462"; } + +.la-bandcamp:before { + content: "\f2d5"; } + +.la-barcode:before { + content: "\f02a"; } + +.la-bars:before { + content: "\f0c9"; } + +.la-baseball-ball:before { + content: "\f433"; } + +.la-basketball-ball:before { + content: "\f434"; } + +.la-bath:before { + content: "\f2cd"; } + +.la-battery-empty:before { + content: "\f244"; } + +.la-battery-full:before { + content: "\f240"; } + +.la-battery-half:before { + content: "\f242"; } + +.la-battery-quarter:before { + content: "\f243"; } + +.la-battery-three-quarters:before { + content: "\f241"; } + +.la-battle-net:before { + content: "\f835"; } + +.la-bed:before { + content: "\f236"; } + +.la-beer:before { + content: "\f0fc"; } + +.la-behance:before { + content: "\f1b4"; } + +.la-behance-square:before { + content: "\f1b5"; } + +.la-bell:before { + content: "\f0f3"; } + +.la-bell-slash:before { + content: "\f1f6"; } + +.la-bezier-curve:before { + content: "\f55b"; } + +.la-bible:before { + content: "\f647"; } + +.la-bicycle:before { + content: "\f206"; } + +.la-biking:before { + content: "\f84a"; } + +.la-bimobject:before { + content: "\f378"; } + +.la-binoculars:before { + content: "\f1e5"; } + +.la-biohazard:before { + content: "\f780"; } + +.la-birthday-cake:before { + content: "\f1fd"; } + +.la-bitbucket:before { + content: "\f171"; } + +.la-bitcoin:before { + content: "\f379"; } + +.la-bity:before { + content: "\f37a"; } + +.la-black-tie:before { + content: "\f27e"; } + +.la-blackberry:before { + content: "\f37b"; } + +.la-blender:before { + content: "\f517"; } + +.la-blender-phone:before { + content: "\f6b6"; } + +.la-blind:before { + content: "\f29d"; } + +.la-blog:before { + content: "\f781"; } + +.la-blogger:before { + content: "\f37c"; } + +.la-blogger-b:before { + content: "\f37d"; } + +.la-bluetooth:before { + content: "\f293"; } + +.la-bluetooth-b:before { + content: "\f294"; } + +.la-bold:before { + content: "\f032"; } + +.la-bolt:before { + content: "\f0e7"; } + +.la-bomb:before { + content: "\f1e2"; } + +.la-bone:before { + content: "\f5d7"; } + +.la-bong:before { + content: "\f55c"; } + +.la-book:before { + content: "\f02d"; } + +.la-book-dead:before { + content: "\f6b7"; } + +.la-book-medical:before { + content: "\f7e6"; } + +.la-book-open:before { + content: "\f518"; } + +.la-book-reader:before { + content: "\f5da"; } + +.la-bookmark:before { + content: "\f02e"; } + +.la-bootstrap:before { + content: "\f836"; } + +.la-border-all:before { + content: "\f84c"; } + +.la-border-none:before { + content: "\f850"; } + +.la-border-style:before { + content: "\f853"; } + +.la-bowling-ball:before { + content: "\f436"; } + +.la-box:before { + content: "\f466"; } + +.la-box-open:before { + content: "\f49e"; } + +.la-boxes:before { + content: "\f468"; } + +.la-braille:before { + content: "\f2a1"; } + +.la-brain:before { + content: "\f5dc"; } + +.la-bread-slice:before { + content: "\f7ec"; } + +.la-briefcase:before { + content: "\f0b1"; } + +.la-briefcase-medical:before { + content: "\f469"; } + +.la-broadcast-tower:before { + content: "\f519"; } + +.la-broom:before { + content: "\f51a"; } + +.la-brush:before { + content: "\f55d"; } + +.la-btc:before { + content: "\f15a"; } + +.la-buffer:before { + content: "\f837"; } + +.la-bug:before { + content: "\f188"; } + +.la-building:before { + content: "\f1ad"; } + +.la-bullhorn:before { + content: "\f0a1"; } + +.la-bullseye:before { + content: "\f140"; } + +.la-burn:before { + content: "\f46a"; } + +.la-buromobelexperte:before { + content: "\f37f"; } + +.la-bus:before { + content: "\f207"; } + +.la-bus-alt:before { + content: "\f55e"; } + +.la-business-time:before { + content: "\f64a"; } + +.la-buy-n-large:before { + content: "\f8a6"; } + +.la-buysellads:before { + content: "\f20d"; } + +.la-calculator:before { + content: "\f1ec"; } + +.la-calendar:before { + content: "\f133"; } + +.la-calendar-alt:before { + content: "\f073"; } + +.la-calendar-check:before { + content: "\f274"; } + +.la-calendar-day:before { + content: "\f783"; } + +.la-calendar-minus:before { + content: "\f272"; } + +.la-calendar-plus:before { + content: "\f271"; } + +.la-calendar-times:before { + content: "\f273"; } + +.la-calendar-week:before { + content: "\f784"; } + +.la-camera:before { + content: "\f030"; } + +.la-camera-retro:before { + content: "\f083"; } + +.la-campground:before { + content: "\f6bb"; } + +.la-canadian-maple-leaf:before { + content: "\f785"; } + +.la-candy-cane:before { + content: "\f786"; } + +.la-cannabis:before { + content: "\f55f"; } + +.la-capsules:before { + content: "\f46b"; } + +.la-car:before { + content: "\f1b9"; } + +.la-car-alt:before { + content: "\f5de"; } + +.la-car-battery:before { + content: "\f5df"; } + +.la-car-crash:before { + content: "\f5e1"; } + +.la-car-side:before { + content: "\f5e4"; } + +.la-caret-down:before { + content: "\f0d7"; } + +.la-caret-left:before { + content: "\f0d9"; } + +.la-caret-right:before { + content: "\f0da"; } + +.la-caret-square-down:before { + content: "\f150"; } + +.la-caret-square-left:before { + content: "\f191"; } + +.la-caret-square-right:before { + content: "\f152"; } + +.la-caret-square-up:before { + content: "\f151"; } + +.la-caret-up:before { + content: "\f0d8"; } + +.la-carrot:before { + content: "\f787"; } + +.la-cart-arrow-down:before { + content: "\f218"; } + +.la-cart-plus:before { + content: "\f217"; } + +.la-cash-register:before { + content: "\f788"; } + +.la-cat:before { + content: "\f6be"; } + +.la-cc-amazon-pay:before { + content: "\f42d"; } + +.la-cc-amex:before { + content: "\f1f3"; } + +.la-cc-apple-pay:before { + content: "\f416"; } + +.la-cc-diners-club:before { + content: "\f24c"; } + +.la-cc-discover:before { + content: "\f1f2"; } + +.la-cc-jcb:before { + content: "\f24b"; } + +.la-cc-mastercard:before { + content: "\f1f1"; } + +.la-cc-paypal:before { + content: "\f1f4"; } + +.la-cc-stripe:before { + content: "\f1f5"; } + +.la-cc-visa:before { + content: "\f1f0"; } + +.la-centercode:before { + content: "\f380"; } + +.la-centos:before { + content: "\f789"; } + +.la-certificate:before { + content: "\f0a3"; } + +.la-chair:before { + content: "\f6c0"; } + +.la-chalkboard:before { + content: "\f51b"; } + +.la-chalkboard-teacher:before { + content: "\f51c"; } + +.la-charging-station:before { + content: "\f5e7"; } + +.la-chart-area:before { + content: "\f1fe"; } + +.la-chart-bar:before { + content: "\f080"; } + +.la-chart-line:before { + content: "\f201"; } + +.la-chart-pie:before { + content: "\f200"; } + +.la-check:before { + content: "\f00c"; } + +.la-check-circle:before { + content: "\f058"; } + +.la-check-double:before { + content: "\f560"; } + +.la-check-square:before { + content: "\f14a"; } + +.la-cheese:before { + content: "\f7ef"; } + +.la-chess:before { + content: "\f439"; } + +.la-chess-bishop:before { + content: "\f43a"; } + +.la-chess-board:before { + content: "\f43c"; } + +.la-chess-king:before { + content: "\f43f"; } + +.la-chess-knight:before { + content: "\f441"; } + +.la-chess-pawn:before { + content: "\f443"; } + +.la-chess-queen:before { + content: "\f445"; } + +.la-chess-rook:before { + content: "\f447"; } + +.la-chevron-circle-down:before { + content: "\f13a"; } + +.la-chevron-circle-left:before { + content: "\f137"; } + +.la-chevron-circle-right:before { + content: "\f138"; } + +.la-chevron-circle-up:before { + content: "\f139"; } + +.la-chevron-down:before { + content: "\f078"; } + +.la-chevron-left:before { + content: "\f053"; } + +.la-chevron-right:before { + content: "\f054"; } + +.la-chevron-up:before { + content: "\f077"; } + +.la-child:before { + content: "\f1ae"; } + +.la-chrome:before { + content: "\f268"; } + +.la-chromecast:before { + content: "\f838"; } + +.la-church:before { + content: "\f51d"; } + +.la-circle:before { + content: "\f111"; } + +.la-circle-notch:before { + content: "\f1ce"; } + +.la-city:before { + content: "\f64f"; } + +.la-clinic-medical:before { + content: "\f7f2"; } + +.la-clipboard:before { + content: "\f328"; } + +.la-clipboard-check:before { + content: "\f46c"; } + +.la-clipboard-list:before { + content: "\f46d"; } + +.la-clock:before { + content: "\f017"; } + +.la-clone:before { + content: "\f24d"; } + +.la-closed-captioning:before { + content: "\f20a"; } + +.la-cloud:before { + content: "\f0c2"; } + +.la-cloud-download-alt:before { + content: "\f381"; } + +.la-cloud-meatball:before { + content: "\f73b"; } + +.la-cloud-moon:before { + content: "\f6c3"; } + +.la-cloud-moon-rain:before { + content: "\f73c"; } + +.la-cloud-rain:before { + content: "\f73d"; } + +.la-cloud-showers-heavy:before { + content: "\f740"; } + +.la-cloud-sun:before { + content: "\f6c4"; } + +.la-cloud-sun-rain:before { + content: "\f743"; } + +.la-cloud-upload-alt:before { + content: "\f382"; } + +.la-cloudscale:before { + content: "\f383"; } + +.la-cloudsmith:before { + content: "\f384"; } + +.la-cloudversify:before { + content: "\f385"; } + +.la-cocktail:before { + content: "\f561"; } + +.la-code:before { + content: "\f121"; } + +.la-code-branch:before { + content: "\f126"; } + +.la-codepen:before { + content: "\f1cb"; } + +.la-codiepie:before { + content: "\f284"; } + +.la-coffee:before { + content: "\f0f4"; } + +.la-cog:before { + content: "\f013"; } + +.la-cogs:before { + content: "\f085"; } + +.la-coins:before { + content: "\f51e"; } + +.la-columns:before { + content: "\f0db"; } + +.la-comment:before { + content: "\f075"; } + +.la-comment-alt:before { + content: "\f27a"; } + +.la-comment-dollar:before { + content: "\f651"; } + +.la-comment-dots:before { + content: "\f4ad"; } + +.la-comment-medical:before { + content: "\f7f5"; } + +.la-comment-slash:before { + content: "\f4b3"; } + +.la-comments:before { + content: "\f086"; } + +.la-comments-dollar:before { + content: "\f653"; } + +.la-compact-disc:before { + content: "\f51f"; } + +.la-compass:before { + content: "\f14e"; } + +.la-compress:before { + content: "\f066"; } + +.la-compress-arrows-alt:before { + content: "\f78c"; } + +.la-concierge-bell:before { + content: "\f562"; } + +.la-confluence:before { + content: "\f78d"; } + +.la-connectdevelop:before { + content: "\f20e"; } + +.la-contao:before { + content: "\f26d"; } + +.la-cookie:before { + content: "\f563"; } + +.la-cookie-bite:before { + content: "\f564"; } + +.la-copy:before { + content: "\f0c5"; } + +.la-copyright:before { + content: "\f1f9"; } + +.la-cotton-bureau:before { + content: "\f89e"; } + +.la-couch:before { + content: "\f4b8"; } + +.la-cpanel:before { + content: "\f388"; } + +.la-creative-commons:before { + content: "\f25e"; } + +.la-creative-commons-by:before { + content: "\f4e7"; } + +.la-creative-commons-nc:before { + content: "\f4e8"; } + +.la-creative-commons-nc-eu:before { + content: "\f4e9"; } + +.la-creative-commons-nc-jp:before { + content: "\f4ea"; } + +.la-creative-commons-nd:before { + content: "\f4eb"; } + +.la-creative-commons-pd:before { + content: "\f4ec"; } + +.la-creative-commons-pd-alt:before { + content: "\f4ed"; } + +.la-creative-commons-remix:before { + content: "\f4ee"; } + +.la-creative-commons-sa:before { + content: "\f4ef"; } + +.la-creative-commons-sampling:before { + content: "\f4f0"; } + +.la-creative-commons-sampling-plus:before { + content: "\f4f1"; } + +.la-creative-commons-share:before { + content: "\f4f2"; } + +.la-creative-commons-zero:before { + content: "\f4f3"; } + +.la-credit-card:before { + content: "\f09d"; } + +.la-critical-role:before { + content: "\f6c9"; } + +.la-crop:before { + content: "\f125"; } + +.la-crop-alt:before { + content: "\f565"; } + +.la-cross:before { + content: "\f654"; } + +.la-crosshairs:before { + content: "\f05b"; } + +.la-crow:before { + content: "\f520"; } + +.la-crown:before { + content: "\f521"; } + +.la-crutch:before { + content: "\f7f7"; } + +.la-css3:before { + content: "\f13c"; } + +.la-css3-alt:before { + content: "\f38b"; } + +.la-cube:before { + content: "\f1b2"; } + +.la-cubes:before { + content: "\f1b3"; } + +.la-cut:before { + content: "\f0c4"; } + +.la-cuttlefish:before { + content: "\f38c"; } + +.la-d-and-d:before { + content: "\f38d"; } + +.la-d-and-d-beyond:before { + content: "\f6ca"; } + +.la-dashcube:before { + content: "\f210"; } + +.la-database:before { + content: "\f1c0"; } + +.la-deaf:before { + content: "\f2a4"; } + +.la-delicious:before { + content: "\f1a5"; } + +.la-democrat:before { + content: "\f747"; } + +.la-deploydog:before { + content: "\f38e"; } + +.la-deskpro:before { + content: "\f38f"; } + +.la-desktop:before { + content: "\f108"; } + +.la-dev:before { + content: "\f6cc"; } + +.la-deviantart:before { + content: "\f1bd"; } + +.la-dharmachakra:before { + content: "\f655"; } + +.la-dhl:before { + content: "\f790"; } + +.la-diagnoses:before { + content: "\f470"; } + +.la-diaspora:before { + content: "\f791"; } + +.la-dice:before { + content: "\f522"; } + +.la-dice-d20:before { + content: "\f6cf"; } + +.la-dice-d6:before { + content: "\f6d1"; } + +.la-dice-five:before { + content: "\f523"; } + +.la-dice-four:before { + content: "\f524"; } + +.la-dice-one:before { + content: "\f525"; } + +.la-dice-six:before { + content: "\f526"; } + +.la-dice-three:before { + content: "\f527"; } + +.la-dice-two:before { + content: "\f528"; } + +.la-digg:before { + content: "\f1a6"; } + +.la-digital-ocean:before { + content: "\f391"; } + +.la-digital-tachograph:before { + content: "\f566"; } + +.la-directions:before { + content: "\f5eb"; } + +.la-discord:before { + content: "\f392"; } + +.la-discourse:before { + content: "\f393"; } + +.la-divide:before { + content: "\f529"; } + +.la-dizzy:before { + content: "\f567"; } + +.la-dna:before { + content: "\f471"; } + +.la-dochub:before { + content: "\f394"; } + +.la-docker:before { + content: "\f395"; } + +.la-dog:before { + content: "\f6d3"; } + +.la-dollar-sign:before { + content: "\f155"; } + +.la-dolly:before { + content: "\f472"; } + +.la-dolly-flatbed:before { + content: "\f474"; } + +.la-donate:before { + content: "\f4b9"; } + +.la-door-closed:before { + content: "\f52a"; } + +.la-door-open:before { + content: "\f52b"; } + +.la-dot-circle:before { + content: "\f192"; } + +.la-dove:before { + content: "\f4ba"; } + +.la-download:before { + content: "\f019"; } + +.la-draft2digital:before { + content: "\f396"; } + +.la-drafting-compass:before { + content: "\f568"; } + +.la-dragon:before { + content: "\f6d5"; } + +.la-draw-polygon:before { + content: "\f5ee"; } + +.la-dribbble:before { + content: "\f17d"; } + +.la-dribbble-square:before { + content: "\f397"; } + +.la-dropbox:before { + content: "\f16b"; } + +.la-drum:before { + content: "\f569"; } + +.la-drum-steelpan:before { + content: "\f56a"; } + +.la-drumstick-bite:before { + content: "\f6d7"; } + +.la-drupal:before { + content: "\f1a9"; } + +.la-dumbbell:before { + content: "\f44b"; } + +.la-dumpster:before { + content: "\f793"; } + +.la-dumpster-fire:before { + content: "\f794"; } + +.la-dungeon:before { + content: "\f6d9"; } + +.la-dyalog:before { + content: "\f399"; } + +.la-earlybirds:before { + content: "\f39a"; } + +.la-ebay:before { + content: "\f4f4"; } + +.la-edge:before { + content: "\f282"; } + +.la-edit:before { + content: "\f044"; } + +.la-egg:before { + content: "\f7fb"; } + +.la-eject:before { + content: "\f052"; } + +.la-elementor:before { + content: "\f430"; } + +.la-ellipsis-h:before { + content: "\f141"; } + +.la-ellipsis-v:before { + content: "\f142"; } + +.la-ello:before { + content: "\f5f1"; } + +.la-ember:before { + content: "\f423"; } + +.la-empire:before { + content: "\f1d1"; } + +.la-envelope:before { + content: "\f0e0"; } + +.la-envelope-open:before { + content: "\f2b6"; } + +.la-envelope-open-text:before { + content: "\f658"; } + +.la-envelope-square:before { + content: "\f199"; } + +.la-envira:before { + content: "\f299"; } + +.la-equals:before { + content: "\f52c"; } + +.la-eraser:before { + content: "\f12d"; } + +.la-erlang:before { + content: "\f39d"; } + +.la-ethereum:before { + content: "\f42e"; } + +.la-ethernet:before { + content: "\f796"; } + +.la-etsy:before { + content: "\f2d7"; } + +.la-euro-sign:before { + content: "\f153"; } + +.la-evernote:before { + content: "\f839"; } + +.la-exchange-alt:before { + content: "\f362"; } + +.la-exclamation:before { + content: "\f12a"; } + +.la-exclamation-circle:before { + content: "\f06a"; } + +.la-exclamation-triangle:before { + content: "\f071"; } + +.la-expand:before { + content: "\f065"; } + +.la-expand-arrows-alt:before { + content: "\f31e"; } + +.la-expeditedssl:before { + content: "\f23e"; } + +.la-external-link-alt:before { + content: "\f35d"; } + +.la-external-link-square-alt:before { + content: "\f360"; } + +.la-eye:before { + content: "\f06e"; } + +.la-eye-dropper:before { + content: "\f1fb"; } + +.la-eye-slash:before { + content: "\f070"; } + +.la-facebook:before { + content: "\f09a"; } + +.la-facebook-f:before { + content: "\f39e"; } + +.la-facebook-messenger:before { + content: "\f39f"; } + +.la-facebook-square:before { + content: "\f082"; } + +.la-fan:before { + content: "\f863"; } + +.la-fantasy-flight-games:before { + content: "\f6dc"; } + +.la-fast-backward:before { + content: "\f049"; } + +.la-fast-forward:before { + content: "\f050"; } + +.la-fax:before { + content: "\f1ac"; } + +.la-feather:before { + content: "\f52d"; } + +.la-feather-alt:before { + content: "\f56b"; } + +.la-fedex:before { + content: "\f797"; } + +.la-fedora:before { + content: "\f798"; } + +.la-female:before { + content: "\f182"; } + +.la-fighter-jet:before { + content: "\f0fb"; } + +.la-figma:before { + content: "\f799"; } + +.la-file:before { + content: "\f15b"; } + +.la-file-alt:before { + content: "\f15c"; } + +.la-file-archive:before { + content: "\f1c6"; } + +.la-file-audio:before { + content: "\f1c7"; } + +.la-file-code:before { + content: "\f1c9"; } + +.la-file-contract:before { + content: "\f56c"; } + +.la-file-csv:before { + content: "\f6dd"; } + +.la-file-download:before { + content: "\f56d"; } + +.la-file-excel:before { + content: "\f1c3"; } + +.la-file-export:before { + content: "\f56e"; } + +.la-file-image:before { + content: "\f1c5"; } + +.la-file-import:before { + content: "\f56f"; } + +.la-file-invoice:before { + content: "\f570"; } + +.la-file-invoice-dollar:before { + content: "\f571"; } + +.la-file-medical:before { + content: "\f477"; } + +.la-file-medical-alt:before { + content: "\f478"; } + +.la-file-pdf:before { + content: "\f1c1"; } + +.la-file-powerpoint:before { + content: "\f1c4"; } + +.la-file-prescription:before { + content: "\f572"; } + +.la-file-signature:before { + content: "\f573"; } + +.la-file-upload:before { + content: "\f574"; } + +.la-file-video:before { + content: "\f1c8"; } + +.la-file-word:before { + content: "\f1c2"; } + +.la-fill:before { + content: "\f575"; } + +.la-fill-drip:before { + content: "\f576"; } + +.la-film:before { + content: "\f008"; } + +.la-filter:before { + content: "\f0b0"; } + +.la-fingerprint:before { + content: "\f577"; } + +.la-fire:before { + content: "\f06d"; } + +.la-fire-alt:before { + content: "\f7e4"; } + +.la-fire-extinguisher:before { + content: "\f134"; } + +.la-firefox:before { + content: "\f269"; } + +.la-first-aid:before { + content: "\f479"; } + +.la-first-order:before { + content: "\f2b0"; } + +.la-first-order-alt:before { + content: "\f50a"; } + +.la-firstdraft:before { + content: "\f3a1"; } + +.la-fish:before { + content: "\f578"; } + +.la-fist-raised:before { + content: "\f6de"; } + +.la-flag:before { + content: "\f024"; } + +.la-flag-checkered:before { + content: "\f11e"; } + +.la-flag-usa:before { + content: "\f74d"; } + +.la-flask:before { + content: "\f0c3"; } + +.la-flickr:before { + content: "\f16e"; } + +.la-flipboard:before { + content: "\f44d"; } + +.la-flushed:before { + content: "\f579"; } + +.la-fly:before { + content: "\f417"; } + +.la-folder:before { + content: "\f07b"; } + +.la-folder-minus:before { + content: "\f65d"; } + +.la-folder-open:before { + content: "\f07c"; } + +.la-folder-plus:before { + content: "\f65e"; } + +.la-font:before { + content: "\f031"; } + +.la-font-awesome:before { + content: "\f2b4"; } + +.la-font-awesome-alt:before { + content: "\f35c"; } + +.la-font-awesome-flag:before { + content: "\f425"; } + +.la-font-awesome-logo-full:before { + content: "\f4e6"; } + +.la-fonticons:before { + content: "\f280"; } + +.la-fonticons-fi:before { + content: "\f3a2"; } + +.la-football-ball:before { + content: "\f44e"; } + +.la-fort-awesome:before { + content: "\f286"; } + +.la-fort-awesome-alt:before { + content: "\f3a3"; } + +.la-forumbee:before { + content: "\f211"; } + +.la-forward:before { + content: "\f04e"; } + +.la-foursquare:before { + content: "\f180"; } + +.la-free-code-camp:before { + content: "\f2c5"; } + +.la-freebsd:before { + content: "\f3a4"; } + +.la-frog:before { + content: "\f52e"; } + +.la-frown:before { + content: "\f119"; } + +.la-frown-open:before { + content: "\f57a"; } + +.la-fulcrum:before { + content: "\f50b"; } + +.la-funnel-dollar:before { + content: "\f662"; } + +.la-futbol:before { + content: "\f1e3"; } + +.la-galactic-republic:before { + content: "\f50c"; } + +.la-galactic-senate:before { + content: "\f50d"; } + +.la-gamepad:before { + content: "\f11b"; } + +.la-gas-pump:before { + content: "\f52f"; } + +.la-gavel:before { + content: "\f0e3"; } + +.la-gem:before { + content: "\f3a5"; } + +.la-genderless:before { + content: "\f22d"; } + +.la-get-pocket:before { + content: "\f265"; } + +.la-gg:before { + content: "\f260"; } + +.la-gg-circle:before { + content: "\f261"; } + +.la-ghost:before { + content: "\f6e2"; } + +.la-gift:before { + content: "\f06b"; } + +.la-gifts:before { + content: "\f79c"; } + +.la-git:before { + content: "\f1d3"; } + +.la-git-alt:before { + content: "\f841"; } + +.la-git-square:before { + content: "\f1d2"; } + +.la-github:before { + content: "\f09b"; } + +.la-github-alt:before { + content: "\f113"; } + +.la-github-square:before { + content: "\f092"; } + +.la-gitkraken:before { + content: "\f3a6"; } + +.la-gitlab:before { + content: "\f296"; } + +.la-gitter:before { + content: "\f426"; } + +.la-glass-cheers:before { + content: "\f79f"; } + +.la-glass-martini:before { + content: "\f000"; } + +.la-glass-martini-alt:before { + content: "\f57b"; } + +.la-glass-whiskey:before { + content: "\f7a0"; } + +.la-glasses:before { + content: "\f530"; } + +.la-glide:before { + content: "\f2a5"; } + +.la-glide-g:before { + content: "\f2a6"; } + +.la-globe:before { + content: "\f0ac"; } + +.la-globe-africa:before { + content: "\f57c"; } + +.la-globe-americas:before { + content: "\f57d"; } + +.la-globe-asia:before { + content: "\f57e"; } + +.la-globe-europe:before { + content: "\f7a2"; } + +.la-gofore:before { + content: "\f3a7"; } + +.la-golf-ball:before { + content: "\f450"; } + +.la-goodreads:before { + content: "\f3a8"; } + +.la-goodreads-g:before { + content: "\f3a9"; } + +.la-google:before { + content: "\f1a0"; } + +.la-google-drive:before { + content: "\f3aa"; } + +.la-google-play:before { + content: "\f3ab"; } + +.la-google-plus:before { + content: "\f2b3"; } + +.la-google-plus-g:before { + content: "\f0d5"; } + +.la-google-plus-square:before { + content: "\f0d4"; } + +.la-google-wallet:before { + content: "\f1ee"; } + +.la-gopuram:before { + content: "\f664"; } + +.la-graduation-cap:before { + content: "\f19d"; } + +.la-gratipay:before { + content: "\f184"; } + +.la-grav:before { + content: "\f2d6"; } + +.la-greater-than:before { + content: "\f531"; } + +.la-greater-than-equal:before { + content: "\f532"; } + +.la-grimace:before { + content: "\f57f"; } + +.la-grin:before { + content: "\f580"; } + +.la-grin-alt:before { + content: "\f581"; } + +.la-grin-beam:before { + content: "\f582"; } + +.la-grin-beam-sweat:before { + content: "\f583"; } + +.la-grin-hearts:before { + content: "\f584"; } + +.la-grin-squint:before { + content: "\f585"; } + +.la-grin-squint-tears:before { + content: "\f586"; } + +.la-grin-stars:before { + content: "\f587"; } + +.la-grin-tears:before { + content: "\f588"; } + +.la-grin-tongue:before { + content: "\f589"; } + +.la-grin-tongue-squint:before { + content: "\f58a"; } + +.la-grin-tongue-wink:before { + content: "\f58b"; } + +.la-grin-wink:before { + content: "\f58c"; } + +.la-grip-horizontal:before { + content: "\f58d"; } + +.la-grip-lines:before { + content: "\f7a4"; } + +.la-grip-lines-vertical:before { + content: "\f7a5"; } + +.la-grip-vertical:before { + content: "\f58e"; } + +.la-gripfire:before { + content: "\f3ac"; } + +.la-grunt:before { + content: "\f3ad"; } + +.la-guitar:before { + content: "\f7a6"; } + +.la-gulp:before { + content: "\f3ae"; } + +.la-h-square:before { + content: "\f0fd"; } + +.la-hacker-news:before { + content: "\f1d4"; } + +.la-hacker-news-square:before { + content: "\f3af"; } + +.la-hackerrank:before { + content: "\f5f7"; } + +.la-hamburger:before { + content: "\f805"; } + +.la-hammer:before { + content: "\f6e3"; } + +.la-hamsa:before { + content: "\f665"; } + +.la-hand-holding:before { + content: "\f4bd"; } + +.la-hand-holding-heart:before { + content: "\f4be"; } + +.la-hand-holding-usd:before { + content: "\f4c0"; } + +.la-hand-lizard:before { + content: "\f258"; } + +.la-hand-middle-finger:before { + content: "\f806"; } + +.la-hand-paper:before { + content: "\f256"; } + +.la-hand-peace:before { + content: "\f25b"; } + +.la-hand-point-down:before { + content: "\f0a7"; } + +.la-hand-point-left:before { + content: "\f0a5"; } + +.la-hand-point-right:before { + content: "\f0a4"; } + +.la-hand-point-up:before { + content: "\f0a6"; } + +.la-hand-pointer:before { + content: "\f25a"; } + +.la-hand-rock:before { + content: "\f255"; } + +.la-hand-scissors:before { + content: "\f257"; } + +.la-hand-spock:before { + content: "\f259"; } + +.la-hands:before { + content: "\f4c2"; } + +.la-hands-helping:before { + content: "\f4c4"; } + +.la-handshake:before { + content: "\f2b5"; } + +.la-hanukiah:before { + content: "\f6e6"; } + +.la-hard-hat:before { + content: "\f807"; } + +.la-hashtag:before { + content: "\f292"; } + +.la-hat-cowboy:before { + content: "\f8c0"; } + +.la-hat-cowboy-side:before { + content: "\f8c1"; } + +.la-hat-wizard:before { + content: "\f6e8"; } + +.la-haykal:before { + content: "\f666"; } + +.la-hdd:before { + content: "\f0a0"; } + +.la-heading:before { + content: "\f1dc"; } + +.la-headphones:before { + content: "\f025"; } + +.la-headphones-alt:before { + content: "\f58f"; } + +.la-headset:before { + content: "\f590"; } + +.la-heart:before { + content: "\f004"; } + +.la-heart-broken:before { + content: "\f7a9"; } + +.la-heartbeat:before { + content: "\f21e"; } + +.la-helicopter:before { + content: "\f533"; } + +.la-highlighter:before { + content: "\f591"; } + +.la-hiking:before { + content: "\f6ec"; } + +.la-hippo:before { + content: "\f6ed"; } + +.la-hips:before { + content: "\f452"; } + +.la-hire-a-helper:before { + content: "\f3b0"; } + +.la-history:before { + content: "\f1da"; } + +.la-hockey-puck:before { + content: "\f453"; } + +.la-holly-berry:before { + content: "\f7aa"; } + +.la-home:before { + content: "\f015"; } + +.la-hooli:before { + content: "\f427"; } + +.la-hornbill:before { + content: "\f592"; } + +.la-horse:before { + content: "\f6f0"; } + +.la-horse-head:before { + content: "\f7ab"; } + +.la-hospital:before { + content: "\f0f8"; } + +.la-hospital-alt:before { + content: "\f47d"; } + +.la-hospital-symbol:before { + content: "\f47e"; } + +.la-hot-tub:before { + content: "\f593"; } + +.la-hotdog:before { + content: "\f80f"; } + +.la-hotel:before { + content: "\f594"; } + +.la-hotjar:before { + content: "\f3b1"; } + +.la-hourglass:before { + content: "\f254"; } + +.la-hourglass-end:before { + content: "\f253"; } + +.la-hourglass-half:before { + content: "\f252"; } + +.la-hourglass-start:before { + content: "\f251"; } + +.la-house-damage:before { + content: "\f6f1"; } + +.la-houzz:before { + content: "\f27c"; } + +.la-hryvnia:before { + content: "\f6f2"; } + +.la-html5:before { + content: "\f13b"; } + +.la-hubspot:before { + content: "\f3b2"; } + +.la-i-cursor:before { + content: "\f246"; } + +.la-ice-cream:before { + content: "\f810"; } + +.la-icicles:before { + content: "\f7ad"; } + +.la-icons:before { + content: "\f86d"; } + +.la-id-badge:before { + content: "\f2c1"; } + +.la-id-card:before { + content: "\f2c2"; } + +.la-id-card-alt:before { + content: "\f47f"; } + +.la-igloo:before { + content: "\f7ae"; } + +.la-image:before { + content: "\f03e"; } + +.la-images:before { + content: "\f302"; } + +.la-imdb:before { + content: "\f2d8"; } + +.la-inbox:before { + content: "\f01c"; } + +.la-indent:before { + content: "\f03c"; } + +.la-industry:before { + content: "\f275"; } + +.la-infinity:before { + content: "\f534"; } + +.la-info:before { + content: "\f129"; } + +.la-info-circle:before { + content: "\f05a"; } + +.la-instagram:before { + content: "\f16d"; } + +.la-intercom:before { + content: "\f7af"; } + +.la-internet-explorer:before { + content: "\f26b"; } + +.la-invision:before { + content: "\f7b0"; } + +.la-ioxhost:before { + content: "\f208"; } + +.la-italic:before { + content: "\f033"; } + +.la-itch-io:before { + content: "\f83a"; } + +.la-itunes:before { + content: "\f3b4"; } + +.la-itunes-note:before { + content: "\f3b5"; } + +.la-java:before { + content: "\f4e4"; } + +.la-jedi:before { + content: "\f669"; } + +.la-jedi-order:before { + content: "\f50e"; } + +.la-jenkins:before { + content: "\f3b6"; } + +.la-jira:before { + content: "\f7b1"; } + +.la-joget:before { + content: "\f3b7"; } + +.la-joint:before { + content: "\f595"; } + +.la-joomla:before { + content: "\f1aa"; } + +.la-journal-whills:before { + content: "\f66a"; } + +.la-js:before { + content: "\f3b8"; } + +.la-js-square:before { + content: "\f3b9"; } + +.la-jsfiddle:before { + content: "\f1cc"; } + +.la-kaaba:before { + content: "\f66b"; } + +.la-kaggle:before { + content: "\f5fa"; } + +.la-key:before { + content: "\f084"; } + +.la-keybase:before { + content: "\f4f5"; } + +.la-keyboard:before { + content: "\f11c"; } + +.la-keycdn:before { + content: "\f3ba"; } + +.la-khanda:before { + content: "\f66d"; } + +.la-kickstarter:before { + content: "\f3bb"; } + +.la-kickstarter-k:before { + content: "\f3bc"; } + +.la-kiss:before { + content: "\f596"; } + +.la-kiss-beam:before { + content: "\f597"; } + +.la-kiss-wink-heart:before { + content: "\f598"; } + +.la-kiwi-bird:before { + content: "\f535"; } + +.la-korvue:before { + content: "\f42f"; } + +.la-landmark:before { + content: "\f66f"; } + +.la-language:before { + content: "\f1ab"; } + +.la-laptop:before { + content: "\f109"; } + +.la-laptop-code:before { + content: "\f5fc"; } + +.la-laptop-medical:before { + content: "\f812"; } + +.la-laravel:before { + content: "\f3bd"; } + +.la-lastfm:before { + content: "\f202"; } + +.la-lastfm-square:before { + content: "\f203"; } + +.la-laugh:before { + content: "\f599"; } + +.la-laugh-beam:before { + content: "\f59a"; } + +.la-laugh-squint:before { + content: "\f59b"; } + +.la-laugh-wink:before { + content: "\f59c"; } + +.la-layer-group:before { + content: "\f5fd"; } + +.la-leaf:before { + content: "\f06c"; } + +.la-leanpub:before { + content: "\f212"; } + +.la-lemon:before { + content: "\f094"; } + +.la-less:before { + content: "\f41d"; } + +.la-less-than:before { + content: "\f536"; } + +.la-less-than-equal:before { + content: "\f537"; } + +.la-level-down-alt:before { + content: "\f3be"; } + +.la-level-up-alt:before { + content: "\f3bf"; } + +.la-life-ring:before { + content: "\f1cd"; } + +.la-lightbulb:before { + content: "\f0eb"; } + +.la-line:before { + content: "\f3c0"; } + +.la-link:before { + content: "\f0c1"; } + +.la-linkedin:before { + content: "\f08c"; } + +.la-linkedin-in:before { + content: "\f0e1"; } + +.la-linode:before { + content: "\f2b8"; } + +.la-linux:before { + content: "\f17c"; } + +.la-lira-sign:before { + content: "\f195"; } + +.la-list:before { + content: "\f03a"; } + +.la-list-alt:before { + content: "\f022"; } + +.la-list-ol:before { + content: "\f0cb"; } + +.la-list-ul:before { + content: "\f0ca"; } + +.la-location-arrow:before { + content: "\f124"; } + +.la-lock:before { + content: "\f023"; } + +.la-lock-open:before { + content: "\f3c1"; } + +.la-long-arrow-alt-down:before { + content: "\f309"; } + +.la-long-arrow-alt-left:before { + content: "\f30a"; } + +.la-long-arrow-alt-right:before { + content: "\f30b"; } + +.la-long-arrow-alt-up:before { + content: "\f30c"; } + +.la-low-vision:before { + content: "\f2a8"; } + +.la-luggage-cart:before { + content: "\f59d"; } + +.la-lyft:before { + content: "\f3c3"; } + +.la-magento:before { + content: "\f3c4"; } + +.la-magic:before { + content: "\f0d0"; } + +.la-magnet:before { + content: "\f076"; } + +.la-mail-bulk:before { + content: "\f674"; } + +.la-mailchimp:before { + content: "\f59e"; } + +.la-male:before { + content: "\f183"; } + +.la-mandalorian:before { + content: "\f50f"; } + +.la-map:before { + content: "\f279"; } + +.la-map-marked:before { + content: "\f59f"; } + +.la-map-marked-alt:before { + content: "\f5a0"; } + +.la-map-marker:before { + content: "\f041"; } + +.la-map-marker-alt:before { + content: "\f3c5"; } + +.la-map-pin:before { + content: "\f276"; } + +.la-map-signs:before { + content: "\f277"; } + +.la-markdown:before { + content: "\f60f"; } + +.la-marker:before { + content: "\f5a1"; } + +.la-mars:before { + content: "\f222"; } + +.la-mars-double:before { + content: "\f227"; } + +.la-mars-stroke:before { + content: "\f229"; } + +.la-mars-stroke-h:before { + content: "\f22b"; } + +.la-mars-stroke-v:before { + content: "\f22a"; } + +.la-mask:before { + content: "\f6fa"; } + +.la-mastodon:before { + content: "\f4f6"; } + +.la-maxcdn:before { + content: "\f136"; } + +.la-mdb:before { + content: "\f8ca"; } + +.la-medal:before { + content: "\f5a2"; } + +.la-medapps:before { + content: "\f3c6"; } + +.la-medium:before { + content: "\f23a"; } + +.la-medium-m:before { + content: "\f3c7"; } + +.la-medkit:before { + content: "\f0fa"; } + +.la-medrt:before { + content: "\f3c8"; } + +.la-meetup:before { + content: "\f2e0"; } + +.la-megaport:before { + content: "\f5a3"; } + +.la-meh:before { + content: "\f11a"; } + +.la-meh-blank:before { + content: "\f5a4"; } + +.la-meh-rolling-eyes:before { + content: "\f5a5"; } + +.la-memory:before { + content: "\f538"; } + +.la-mendeley:before { + content: "\f7b3"; } + +.la-menorah:before { + content: "\f676"; } + +.la-mercury:before { + content: "\f223"; } + +.la-meteor:before { + content: "\f753"; } + +.la-microchip:before { + content: "\f2db"; } + +.la-microphone:before { + content: "\f130"; } + +.la-microphone-alt:before { + content: "\f3c9"; } + +.la-microphone-alt-slash:before { + content: "\f539"; } + +.la-microphone-slash:before { + content: "\f131"; } + +.la-microscope:before { + content: "\f610"; } + +.la-microsoft:before { + content: "\f3ca"; } + +.la-minus:before { + content: "\f068"; } + +.la-minus-circle:before { + content: "\f056"; } + +.la-minus-square:before { + content: "\f146"; } + +.la-mitten:before { + content: "\f7b5"; } + +.la-mix:before { + content: "\f3cb"; } + +.la-mixcloud:before { + content: "\f289"; } + +.la-mizuni:before { + content: "\f3cc"; } + +.la-mobile:before { + content: "\f10b"; } + +.la-mobile-alt:before { + content: "\f3cd"; } + +.la-modx:before { + content: "\f285"; } + +.la-monero:before { + content: "\f3d0"; } + +.la-money-bill:before { + content: "\f0d6"; } + +.la-money-bill-alt:before { + content: "\f3d1"; } + +.la-money-bill-wave:before { + content: "\f53a"; } + +.la-money-bill-wave-alt:before { + content: "\f53b"; } + +.la-money-check:before { + content: "\f53c"; } + +.la-money-check-alt:before { + content: "\f53d"; } + +.la-monument:before { + content: "\f5a6"; } + +.la-moon:before { + content: "\f186"; } + +.la-mortar-pestle:before { + content: "\f5a7"; } + +.la-mosque:before { + content: "\f678"; } + +.la-motorcycle:before { + content: "\f21c"; } + +.la-mountain:before { + content: "\f6fc"; } + +.la-mouse:before { + content: "\f8cc"; } + +.la-mouse-pointer:before { + content: "\f245"; } + +.la-mug-hot:before { + content: "\f7b6"; } + +.la-music:before { + content: "\f001"; } + +.la-napster:before { + content: "\f3d2"; } + +.la-neos:before { + content: "\f612"; } + +.la-network-wired:before { + content: "\f6ff"; } + +.la-neuter:before { + content: "\f22c"; } + +.la-newspaper:before { + content: "\f1ea"; } + +.la-nimblr:before { + content: "\f5a8"; } + +.la-node:before { + content: "\f419"; } + +.la-node-js:before { + content: "\f3d3"; } + +.la-not-equal:before { + content: "\f53e"; } + +.la-notes-medical:before { + content: "\f481"; } + +.la-npm:before { + content: "\f3d4"; } + +.la-ns8:before { + content: "\f3d5"; } + +.la-nutritionix:before { + content: "\f3d6"; } + +.la-object-group:before { + content: "\f247"; } + +.la-object-ungroup:before { + content: "\f248"; } + +.la-odnoklassniki:before { + content: "\f263"; } + +.la-odnoklassniki-square:before { + content: "\f264"; } + +.la-oil-can:before { + content: "\f613"; } + +.la-old-republic:before { + content: "\f510"; } + +.la-om:before { + content: "\f679"; } + +.la-opencart:before { + content: "\f23d"; } + +.la-openid:before { + content: "\f19b"; } + +.la-opera:before { + content: "\f26a"; } + +.la-optin-monster:before { + content: "\f23c"; } + +.la-orcid:before { + content: "\f8d2"; } + +.la-osi:before { + content: "\f41a"; } + +.la-otter:before { + content: "\f700"; } + +.la-outdent:before { + content: "\f03b"; } + +.la-page4:before { + content: "\f3d7"; } + +.la-pagelines:before { + content: "\f18c"; } + +.la-pager:before { + content: "\f815"; } + +.la-paint-brush:before { + content: "\f1fc"; } + +.la-paint-roller:before { + content: "\f5aa"; } + +.la-palette:before { + content: "\f53f"; } + +.la-palfed:before { + content: "\f3d8"; } + +.la-pallet:before { + content: "\f482"; } + +.la-paper-plane:before { + content: "\f1d8"; } + +.la-paperclip:before { + content: "\f0c6"; } + +.la-parachute-box:before { + content: "\f4cd"; } + +.la-paragraph:before { + content: "\f1dd"; } + +.la-parking:before { + content: "\f540"; } + +.la-passport:before { + content: "\f5ab"; } + +.la-pastafarianism:before { + content: "\f67b"; } + +.la-paste:before { + content: "\f0ea"; } + +.la-patreon:before { + content: "\f3d9"; } + +.la-pause:before { + content: "\f04c"; } + +.la-pause-circle:before { + content: "\f28b"; } + +.la-paw:before { + content: "\f1b0"; } + +.la-paypal:before { + content: "\f1ed"; } + +.la-peace:before { + content: "\f67c"; } + +.la-pen:before { + content: "\f304"; } + +.la-pen-alt:before { + content: "\f305"; } + +.la-pen-fancy:before { + content: "\f5ac"; } + +.la-pen-nib:before { + content: "\f5ad"; } + +.la-pen-square:before { + content: "\f14b"; } + +.la-pencil-alt:before { + content: "\f303"; } + +.la-pencil-ruler:before { + content: "\f5ae"; } + +.la-penny-arcade:before { + content: "\f704"; } + +.la-people-carry:before { + content: "\f4ce"; } + +.la-pepper-hot:before { + content: "\f816"; } + +.la-percent:before { + content: "\f295"; } + +.la-percentage:before { + content: "\f541"; } + +.la-periscope:before { + content: "\f3da"; } + +.la-person-booth:before { + content: "\f756"; } + +.la-phabricator:before { + content: "\f3db"; } + +.la-phoenix-framework:before { + content: "\f3dc"; } + +.la-phoenix-squadron:before { + content: "\f511"; } + +.la-phone:before { + content: "\f095"; } + +.la-phone-alt:before { + content: "\f879"; } + +.la-phone-slash:before { + content: "\f3dd"; } + +.la-phone-square:before { + content: "\f098"; } + +.la-phone-square-alt:before { + content: "\f87b"; } + +.la-phone-volume:before { + content: "\f2a0"; } + +.la-photo-video:before { + content: "\f87c"; } + +.la-php:before { + content: "\f457"; } + +.la-pied-piper:before { + content: "\f2ae"; } + +.la-pied-piper-alt:before { + content: "\f1a8"; } + +.la-pied-piper-hat:before { + content: "\f4e5"; } + +.la-pied-piper-pp:before { + content: "\f1a7"; } + +.la-piggy-bank:before { + content: "\f4d3"; } + +.la-pills:before { + content: "\f484"; } + +.la-pinterest:before { + content: "\f0d2"; } + +.la-pinterest-p:before { + content: "\f231"; } + +.la-pinterest-square:before { + content: "\f0d3"; } + +.la-pizza-slice:before { + content: "\f818"; } + +.la-place-of-worship:before { + content: "\f67f"; } + +.la-plane:before { + content: "\f072"; } + +.la-plane-arrival:before { + content: "\f5af"; } + +.la-plane-departure:before { + content: "\f5b0"; } + +.la-play:before { + content: "\f04b"; } + +.la-play-circle:before { + content: "\f144"; } + +.la-playstation:before { + content: "\f3df"; } + +.la-plug:before { + content: "\f1e6"; } + +.la-plus:before { + content: "\f067"; } + +.la-plus-circle:before { + content: "\f055"; } + +.la-plus-square:before { + content: "\f0fe"; } + +.la-podcast:before { + content: "\f2ce"; } + +.la-poll:before { + content: "\f681"; } + +.la-poll-h:before { + content: "\f682"; } + +.la-poo:before { + content: "\f2fe"; } + +.la-poo-storm:before { + content: "\f75a"; } + +.la-poop:before { + content: "\f619"; } + +.la-portrait:before { + content: "\f3e0"; } + +.la-pound-sign:before { + content: "\f154"; } + +.la-power-off:before { + content: "\f011"; } + +.la-pray:before { + content: "\f683"; } + +.la-praying-hands:before { + content: "\f684"; } + +.la-prescription:before { + content: "\f5b1"; } + +.la-prescription-bottle:before { + content: "\f485"; } + +.la-prescription-bottle-alt:before { + content: "\f486"; } + +.la-print:before { + content: "\f02f"; } + +.la-procedures:before { + content: "\f487"; } + +.la-product-hunt:before { + content: "\f288"; } + +.la-project-diagram:before { + content: "\f542"; } + +.la-pushed:before { + content: "\f3e1"; } + +.la-puzzle-piece:before { + content: "\f12e"; } + +.la-python:before { + content: "\f3e2"; } + +.la-qq:before { + content: "\f1d6"; } + +.la-qrcode:before { + content: "\f029"; } + +.la-question:before { + content: "\f128"; } + +.la-question-circle:before { + content: "\f059"; } + +.la-quidditch:before { + content: "\f458"; } + +.la-quinscape:before { + content: "\f459"; } + +.la-quora:before { + content: "\f2c4"; } + +.la-quote-left:before { + content: "\f10d"; } + +.la-quote-right:before { + content: "\f10e"; } + +.la-quran:before { + content: "\f687"; } + +.la-r-project:before { + content: "\f4f7"; } + +.la-radiation:before { + content: "\f7b9"; } + +.la-radiation-alt:before { + content: "\f7ba"; } + +.la-rainbow:before { + content: "\f75b"; } + +.la-random:before { + content: "\f074"; } + +.la-raspberry-pi:before { + content: "\f7bb"; } + +.la-ravelry:before { + content: "\f2d9"; } + +.la-react:before { + content: "\f41b"; } + +.la-reacteurope:before { + content: "\f75d"; } + +.la-readme:before { + content: "\f4d5"; } + +.la-rebel:before { + content: "\f1d0"; } + +.la-receipt:before { + content: "\f543"; } + +.la-record-vinyl:before { + content: "\f8d9"; } + +.la-recycle:before { + content: "\f1b8"; } + +.la-red-river:before { + content: "\f3e3"; } + +.la-reddit:before { + content: "\f1a1"; } + +.la-reddit-alien:before { + content: "\f281"; } + +.la-reddit-square:before { + content: "\f1a2"; } + +.la-redhat:before { + content: "\f7bc"; } + +.la-redo:before { + content: "\f01e"; } + +.la-redo-alt:before { + content: "\f2f9"; } + +.la-registered:before { + content: "\f25d"; } + +.la-remove-format:before { + content: "\f87d"; } + +.la-renren:before { + content: "\f18b"; } + +.la-reply:before { + content: "\f3e5"; } + +.la-reply-all:before { + content: "\f122"; } + +.la-replyd:before { + content: "\f3e6"; } + +.la-republican:before { + content: "\f75e"; } + +.la-researchgate:before { + content: "\f4f8"; } + +.la-resolving:before { + content: "\f3e7"; } + +.la-restroom:before { + content: "\f7bd"; } + +.la-retweet:before { + content: "\f079"; } + +.la-rev:before { + content: "\f5b2"; } + +.la-ribbon:before { + content: "\f4d6"; } + +.la-ring:before { + content: "\f70b"; } + +.la-road:before { + content: "\f018"; } + +.la-robot:before { + content: "\f544"; } + +.la-rocket:before { + content: "\f135"; } + +.la-rocketchat:before { + content: "\f3e8"; } + +.la-rockrms:before { + content: "\f3e9"; } + +.la-route:before { + content: "\f4d7"; } + +.la-rss:before { + content: "\f09e"; } + +.la-rss-square:before { + content: "\f143"; } + +.la-ruble-sign:before { + content: "\f158"; } + +.la-ruler:before { + content: "\f545"; } + +.la-ruler-combined:before { + content: "\f546"; } + +.la-ruler-horizontal:before { + content: "\f547"; } + +.la-ruler-vertical:before { + content: "\f548"; } + +.la-running:before { + content: "\f70c"; } + +.la-rupee-sign:before { + content: "\f156"; } + +.la-sad-cry:before { + content: "\f5b3"; } + +.la-sad-tear:before { + content: "\f5b4"; } + +.la-safari:before { + content: "\f267"; } + +.la-salesforce:before { + content: "\f83b"; } + +.la-sass:before { + content: "\f41e"; } + +.la-satellite:before { + content: "\f7bf"; } + +.la-satellite-dish:before { + content: "\f7c0"; } + +.la-save:before { + content: "\f0c7"; } + +.la-schlix:before { + content: "\f3ea"; } + +.la-school:before { + content: "\f549"; } + +.la-screwdriver:before { + content: "\f54a"; } + +.la-scribd:before { + content: "\f28a"; } + +.la-scroll:before { + content: "\f70e"; } + +.la-sd-card:before { + content: "\f7c2"; } + +.la-search:before { + content: "\f002"; } + +.la-search-dollar:before { + content: "\f688"; } + +.la-search-location:before { + content: "\f689"; } + +.la-search-minus:before { + content: "\f010"; } + +.la-search-plus:before { + content: "\f00e"; } + +.la-searchengin:before { + content: "\f3eb"; } + +.la-seedling:before { + content: "\f4d8"; } + +.la-sellcast:before { + content: "\f2da"; } + +.la-sellsy:before { + content: "\f213"; } + +.la-server:before { + content: "\f233"; } + +.la-servicestack:before { + content: "\f3ec"; } + +.la-shapes:before { + content: "\f61f"; } + +.la-share:before { + content: "\f064"; } + +.la-share-alt:before { + content: "\f1e0"; } + +.la-share-alt-square:before { + content: "\f1e1"; } + +.la-share-square:before { + content: "\f14d"; } + +.la-shekel-sign:before { + content: "\f20b"; } + +.la-shield-alt:before { + content: "\f3ed"; } + +.la-ship:before { + content: "\f21a"; } + +.la-shipping-fast:before { + content: "\f48b"; } + +.la-shirtsinbulk:before { + content: "\f214"; } + +.la-shoe-prints:before { + content: "\f54b"; } + +.la-shopping-bag:before { + content: "\f290"; } + +.la-shopping-basket:before { + content: "\f291"; } + +.la-shopping-cart:before { + content: "\f07a"; } + +.la-shopware:before { + content: "\f5b5"; } + +.la-shower:before { + content: "\f2cc"; } + +.la-shuttle-van:before { + content: "\f5b6"; } + +.la-sign:before { + content: "\f4d9"; } + +.la-sign-in-alt:before { + content: "\f2f6"; } + +.la-sign-language:before { + content: "\f2a7"; } + +.la-sign-out-alt:before { + content: "\f2f5"; } + +.la-signal:before { + content: "\f012"; } + +.la-signature:before { + content: "\f5b7"; } + +.la-sim-card:before { + content: "\f7c4"; } + +.la-simplybuilt:before { + content: "\f215"; } + +.la-sistrix:before { + content: "\f3ee"; } + +.la-sitemap:before { + content: "\f0e8"; } + +.la-sith:before { + content: "\f512"; } + +.la-skating:before { + content: "\f7c5"; } + +.la-sketch:before { + content: "\f7c6"; } + +.la-skiing:before { + content: "\f7c9"; } + +.la-skiing-nordic:before { + content: "\f7ca"; } + +.la-skull:before { + content: "\f54c"; } + +.la-skull-crossbones:before { + content: "\f714"; } + +.la-skyatlas:before { + content: "\f216"; } + +.la-skype:before { + content: "\f17e"; } + +.la-slack:before { + content: "\f198"; } + +.la-slack-hash:before { + content: "\f3ef"; } + +.la-slash:before { + content: "\f715"; } + +.la-sleigh:before { + content: "\f7cc"; } + +.la-sliders-h:before { + content: "\f1de"; } + +.la-slideshare:before { + content: "\f1e7"; } + +.la-smile:before { + content: "\f118"; } + +.la-smile-beam:before { + content: "\f5b8"; } + +.la-smile-wink:before { + content: "\f4da"; } + +.la-smog:before { + content: "\f75f"; } + +.la-smoking:before { + content: "\f48d"; } + +.la-smoking-ban:before { + content: "\f54d"; } + +.la-sms:before { + content: "\f7cd"; } + +.la-snapchat:before { + content: "\f2ab"; } + +.la-snapchat-ghost:before { + content: "\f2ac"; } + +.la-snapchat-square:before { + content: "\f2ad"; } + +.la-snowboarding:before { + content: "\f7ce"; } + +.la-snowflake:before { + content: "\f2dc"; } + +.la-snowman:before { + content: "\f7d0"; } + +.la-snowplow:before { + content: "\f7d2"; } + +.la-socks:before { + content: "\f696"; } + +.la-solar-panel:before { + content: "\f5ba"; } + +.la-sort:before { + content: "\f0dc"; } + +.la-sort-alpha-down:before { + content: "\f15d"; } + +.la-sort-alpha-down-alt:before { + content: "\f881"; } + +.la-sort-alpha-up:before { + content: "\f15e"; } + +.la-sort-alpha-up-alt:before { + content: "\f882"; } + +.la-sort-amount-down:before { + content: "\f160"; } + +.la-sort-amount-down-alt:before { + content: "\f884"; } + +.la-sort-amount-up:before { + content: "\f161"; } + +.la-sort-amount-up-alt:before { + content: "\f885"; } + +.la-sort-down:before { + content: "\f0dd"; } + +.la-sort-numeric-down:before { + content: "\f162"; } + +.la-sort-numeric-down-alt:before { + content: "\f886"; } + +.la-sort-numeric-up:before { + content: "\f163"; } + +.la-sort-numeric-up-alt:before { + content: "\f887"; } + +.la-sort-up:before { + content: "\f0de"; } + +.la-soundcloud:before { + content: "\f1be"; } + +.la-sourcetree:before { + content: "\f7d3"; } + +.la-spa:before { + content: "\f5bb"; } + +.la-space-shuttle:before { + content: "\f197"; } + +.la-speakap:before { + content: "\f3f3"; } + +.la-speaker-deck:before { + content: "\f83c"; } + +.la-spell-check:before { + content: "\f891"; } + +.la-spider:before { + content: "\f717"; } + +.la-spinner:before { + content: "\f110"; } + +.la-splotch:before { + content: "\f5bc"; } + +.la-spotify:before { + content: "\f1bc"; } + +.la-spray-can:before { + content: "\f5bd"; } + +.la-square:before { + content: "\f0c8"; } + +.la-square-full:before { + content: "\f45c"; } + +.la-square-root-alt:before { + content: "\f698"; } + +.la-squarespace:before { + content: "\f5be"; } + +.la-stack-exchange:before { + content: "\f18d"; } + +.la-stack-overflow:before { + content: "\f16c"; } + +.la-stackpath:before { + content: "\f842"; } + +.la-stamp:before { + content: "\f5bf"; } + +.la-star:before { + content: "\f005"; } + +.la-star-and-crescent:before { + content: "\f699"; } + +.la-star-half:before { + content: "\f089"; } + +.la-star-half-alt:before { + content: "\f5c0"; } + +.la-star-of-david:before { + content: "\f69a"; } + +.la-star-of-life:before { + content: "\f621"; } + +.la-staylinked:before { + content: "\f3f5"; } + +.la-steam:before { + content: "\f1b6"; } + +.la-steam-square:before { + content: "\f1b7"; } + +.la-steam-symbol:before { + content: "\f3f6"; } + +.la-step-backward:before { + content: "\f048"; } + +.la-step-forward:before { + content: "\f051"; } + +.la-stethoscope:before { + content: "\f0f1"; } + +.la-sticker-mule:before { + content: "\f3f7"; } + +.la-sticky-note:before { + content: "\f249"; } + +.la-stop:before { + content: "\f04d"; } + +.la-stop-circle:before { + content: "\f28d"; } + +.la-stopwatch:before { + content: "\f2f2"; } + +.la-store:before { + content: "\f54e"; } + +.la-store-alt:before { + content: "\f54f"; } + +.la-strava:before { + content: "\f428"; } + +.la-stream:before { + content: "\f550"; } + +.la-street-view:before { + content: "\f21d"; } + +.la-strikethrough:before { + content: "\f0cc"; } + +.la-stripe:before { + content: "\f429"; } + +.la-stripe-s:before { + content: "\f42a"; } + +.la-stroopwafel:before { + content: "\f551"; } + +.la-studiovinari:before { + content: "\f3f8"; } + +.la-stumbleupon:before { + content: "\f1a4"; } + +.la-stumbleupon-circle:before { + content: "\f1a3"; } + +.la-subscript:before { + content: "\f12c"; } + +.la-subway:before { + content: "\f239"; } + +.la-suitcase:before { + content: "\f0f2"; } + +.la-suitcase-rolling:before { + content: "\f5c1"; } + +.la-sun:before { + content: "\f185"; } + +.la-superpowers:before { + content: "\f2dd"; } + +.la-superscript:before { + content: "\f12b"; } + +.la-supple:before { + content: "\f3f9"; } + +.la-surprise:before { + content: "\f5c2"; } + +.la-suse:before { + content: "\f7d6"; } + +.la-swatchbook:before { + content: "\f5c3"; } + +.la-swift:before { + content: "\f8e1"; } + +.la-swimmer:before { + content: "\f5c4"; } + +.la-swimming-pool:before { + content: "\f5c5"; } + +.la-symfony:before { + content: "\f83d"; } + +.la-synagogue:before { + content: "\f69b"; } + +.la-sync:before { + content: "\f021"; } + +.la-sync-alt:before { + content: "\f2f1"; } + +.la-syringe:before { + content: "\f48e"; } + +.la-table:before { + content: "\f0ce"; } + +.la-table-tennis:before { + content: "\f45d"; } + +.la-tablet:before { + content: "\f10a"; } + +.la-tablet-alt:before { + content: "\f3fa"; } + +.la-tablets:before { + content: "\f490"; } + +.la-tachometer-alt:before { + content: "\f3fd"; } + +.la-tag:before { + content: "\f02b"; } + +.la-tags:before { + content: "\f02c"; } + +.la-tape:before { + content: "\f4db"; } + +.la-tasks:before { + content: "\f0ae"; } + +.la-taxi:before { + content: "\f1ba"; } + +.la-teamspeak:before { + content: "\f4f9"; } + +.la-teeth:before { + content: "\f62e"; } + +.la-teeth-open:before { + content: "\f62f"; } + +.la-telegram:before { + content: "\f2c6"; } + +.la-telegram-plane:before { + content: "\f3fe"; } + +.la-temperature-high:before { + content: "\f769"; } + +.la-temperature-low:before { + content: "\f76b"; } + +.la-tencent-weibo:before { + content: "\f1d5"; } + +.la-tenge:before { + content: "\f7d7"; } + +.la-terminal:before { + content: "\f120"; } + +.la-text-height:before { + content: "\f034"; } + +.la-text-width:before { + content: "\f035"; } + +.la-th:before { + content: "\f00a"; } + +.la-th-large:before { + content: "\f009"; } + +.la-th-list:before { + content: "\f00b"; } + +.la-the-red-yeti:before { + content: "\f69d"; } + +.la-theater-masks:before { + content: "\f630"; } + +.la-themeco:before { + content: "\f5c6"; } + +.la-themeisle:before { + content: "\f2b2"; } + +.la-thermometer:before { + content: "\f491"; } + +.la-thermometer-empty:before { + content: "\f2cb"; } + +.la-thermometer-full:before { + content: "\f2c7"; } + +.la-thermometer-half:before { + content: "\f2c9"; } + +.la-thermometer-quarter:before { + content: "\f2ca"; } + +.la-thermometer-three-quarters:before { + content: "\f2c8"; } + +.la-think-peaks:before { + content: "\f731"; } + +.la-thumbs-down:before { + content: "\f165"; } + +.la-thumbs-up:before { + content: "\f164"; } + +.la-thumbtack:before { + content: "\f08d"; } + +.la-ticket-alt:before { + content: "\f3ff"; } + +.la-times:before { + content: "\f00d"; } + +.la-times-circle:before { + content: "\f057"; } + +.la-tint:before { + content: "\f043"; } + +.la-tint-slash:before { + content: "\f5c7"; } + +.la-tired:before { + content: "\f5c8"; } + +.la-toggle-off:before { + content: "\f204"; } + +.la-toggle-on:before { + content: "\f205"; } + +.la-toilet:before { + content: "\f7d8"; } + +.la-toilet-paper:before { + content: "\f71e"; } + +.la-toolbox:before { + content: "\f552"; } + +.la-tools:before { + content: "\f7d9"; } + +.la-tooth:before { + content: "\f5c9"; } + +.la-torah:before { + content: "\f6a0"; } + +.la-torii-gate:before { + content: "\f6a1"; } + +.la-tractor:before { + content: "\f722"; } + +.la-trade-federation:before { + content: "\f513"; } + +.la-trademark:before { + content: "\f25c"; } + +.la-traffic-light:before { + content: "\f637"; } + +.la-train:before { + content: "\f238"; } + +.la-tram:before { + content: "\f7da"; } + +.la-transgender:before { + content: "\f224"; } + +.la-transgender-alt:before { + content: "\f225"; } + +.la-trash:before { + content: "\f1f8"; } + +.la-trash-alt:before { + content: "\f2ed"; } + +.la-trash-restore:before { + content: "\f829"; } + +.la-trash-restore-alt:before { + content: "\f82a"; } + +.la-tree:before { + content: "\f1bb"; } + +.la-trello:before { + content: "\f181"; } + +.la-tripadvisor:before { + content: "\f262"; } + +.la-trophy:before { + content: "\f091"; } + +.la-truck:before { + content: "\f0d1"; } + +.la-truck-loading:before { + content: "\f4de"; } + +.la-truck-monster:before { + content: "\f63b"; } + +.la-truck-moving:before { + content: "\f4df"; } + +.la-truck-pickup:before { + content: "\f63c"; } + +.la-tshirt:before { + content: "\f553"; } + +.la-tty:before { + content: "\f1e4"; } + +.la-tumblr:before { + content: "\f173"; } + +.la-tumblr-square:before { + content: "\f174"; } + +.la-tv:before { + content: "\f26c"; } + +.la-twitch:before { + content: "\f1e8"; } + +.la-twitter:before { + content: "\f099"; } + +.la-twitter-square:before { + content: "\f081"; } + +.la-typo3:before { + content: "\f42b"; } + +.la-uber:before { + content: "\f402"; } + +.la-ubuntu:before { + content: "\f7df"; } + +.la-uikit:before { + content: "\f403"; } + +.la-umbraco:before { + content: "\f8e8"; } + +.la-umbrella:before { + content: "\f0e9"; } + +.la-umbrella-beach:before { + content: "\f5ca"; } + +.la-underline:before { + content: "\f0cd"; } + +.la-undo:before { + content: "\f0e2"; } + +.la-undo-alt:before { + content: "\f2ea"; } + +.la-uniregistry:before { + content: "\f404"; } + +.la-universal-access:before { + content: "\f29a"; } + +.la-university:before { + content: "\f19c"; } + +.la-unlink:before { + content: "\f127"; } + +.la-unlock:before { + content: "\f09c"; } + +.la-unlock-alt:before { + content: "\f13e"; } + +.la-untappd:before { + content: "\f405"; } + +.la-upload:before { + content: "\f093"; } + +.la-ups:before { + content: "\f7e0"; } + +.la-usb:before { + content: "\f287"; } + +.la-user:before { + content: "\f007"; } + +.la-user-alt:before { + content: "\f406"; } + +.la-user-alt-slash:before { + content: "\f4fa"; } + +.la-user-astronaut:before { + content: "\f4fb"; } + +.la-user-check:before { + content: "\f4fc"; } + +.la-user-circle:before { + content: "\f2bd"; } + +.la-user-clock:before { + content: "\f4fd"; } + +.la-user-cog:before { + content: "\f4fe"; } + +.la-user-edit:before { + content: "\f4ff"; } + +.la-user-friends:before { + content: "\f500"; } + +.la-user-graduate:before { + content: "\f501"; } + +.la-user-injured:before { + content: "\f728"; } + +.la-user-lock:before { + content: "\f502"; } + +.la-user-md:before { + content: "\f0f0"; } + +.la-user-minus:before { + content: "\f503"; } + +.la-user-ninja:before { + content: "\f504"; } + +.la-user-nurse:before { + content: "\f82f"; } + +.la-user-plus:before { + content: "\f234"; } + +.la-user-secret:before { + content: "\f21b"; } + +.la-user-shield:before { + content: "\f505"; } + +.la-user-slash:before { + content: "\f506"; } + +.la-user-tag:before { + content: "\f507"; } + +.la-user-tie:before { + content: "\f508"; } + +.la-user-times:before { + content: "\f235"; } + +.la-users:before { + content: "\f0c0"; } + +.la-users-cog:before { + content: "\f509"; } + +.la-usps:before { + content: "\f7e1"; } + +.la-ussunnah:before { + content: "\f407"; } + +.la-utensil-spoon:before { + content: "\f2e5"; } + +.la-utensils:before { + content: "\f2e7"; } + +.la-vaadin:before { + content: "\f408"; } + +.la-vector-square:before { + content: "\f5cb"; } + +.la-venus:before { + content: "\f221"; } + +.la-venus-double:before { + content: "\f226"; } + +.la-venus-mars:before { + content: "\f228"; } + +.la-viacoin:before { + content: "\f237"; } + +.la-viadeo:before { + content: "\f2a9"; } + +.la-viadeo-square:before { + content: "\f2aa"; } + +.la-vial:before { + content: "\f492"; } + +.la-vials:before { + content: "\f493"; } + +.la-viber:before { + content: "\f409"; } + +.la-video:before { + content: "\f03d"; } + +.la-video-slash:before { + content: "\f4e2"; } + +.la-vihara:before { + content: "\f6a7"; } + +.la-vimeo:before { + content: "\f40a"; } + +.la-vimeo-square:before { + content: "\f194"; } + +.la-vimeo-v:before { + content: "\f27d"; } + +.la-vine:before { + content: "\f1ca"; } + +.la-vk:before { + content: "\f189"; } + +.la-vnv:before { + content: "\f40b"; } + +.la-voicemail:before { + content: "\f897"; } + +.la-volleyball-ball:before { + content: "\f45f"; } + +.la-volume-down:before { + content: "\f027"; } + +.la-volume-mute:before { + content: "\f6a9"; } + +.la-volume-off:before { + content: "\f026"; } + +.la-volume-up:before { + content: "\f028"; } + +.la-vote-yea:before { + content: "\f772"; } + +.la-vr-cardboard:before { + content: "\f729"; } + +.la-vuejs:before { + content: "\f41f"; } + +.la-walking:before { + content: "\f554"; } + +.la-wallet:before { + content: "\f555"; } + +.la-warehouse:before { + content: "\f494"; } + +.la-water:before { + content: "\f773"; } + +.la-wave-square:before { + content: "\f83e"; } + +.la-waze:before { + content: "\f83f"; } + +.la-weebly:before { + content: "\f5cc"; } + +.la-weibo:before { + content: "\f18a"; } + +.la-weight:before { + content: "\f496"; } + +.la-weight-hanging:before { + content: "\f5cd"; } + +.la-weixin:before { + content: "\f1d7"; } + +.la-whatsapp:before { + content: "\f232"; } + +.la-whatsapp-square:before { + content: "\f40c"; } + +.la-wheelchair:before { + content: "\f193"; } + +.la-whmcs:before { + content: "\f40d"; } + +.la-wifi:before { + content: "\f1eb"; } + +.la-wikipedia-w:before { + content: "\f266"; } + +.la-wind:before { + content: "\f72e"; } + +.la-window-close:before { + content: "\f410"; } + +.la-window-maximize:before { + content: "\f2d0"; } + +.la-window-minimize:before { + content: "\f2d1"; } + +.la-window-restore:before { + content: "\f2d2"; } + +.la-windows:before { + content: "\f17a"; } + +.la-wine-bottle:before { + content: "\f72f"; } + +.la-wine-glass:before { + content: "\f4e3"; } + +.la-wine-glass-alt:before { + content: "\f5ce"; } + +.la-wix:before { + content: "\f5cf"; } + +.la-wizards-of-the-coast:before { + content: "\f730"; } + +.la-wolf-pack-battalion:before { + content: "\f514"; } + +.la-won-sign:before { + content: "\f159"; } + +.la-wordpress:before { + content: "\f19a"; } + +.la-wordpress-simple:before { + content: "\f411"; } + +.la-wpbeginner:before { + content: "\f297"; } + +.la-wpexplorer:before { + content: "\f2de"; } + +.la-wpforms:before { + content: "\f298"; } + +.la-wpressr:before { + content: "\f3e4"; } + +.la-wrench:before { + content: "\f0ad"; } + +.la-x-ray:before { + content: "\f497"; } + +.la-xbox:before { + content: "\f412"; } + +.la-xing:before { + content: "\f168"; } + +.la-xing-square:before { + content: "\f169"; } + +.la-y-combinator:before { + content: "\f23b"; } + +.la-yahoo:before { + content: "\f19e"; } + +.la-yammer:before { + content: "\f840"; } + +.la-yandex:before { + content: "\f413"; } + +.la-yandex-international:before { + content: "\f414"; } + +.la-yarn:before { + content: "\f7e3"; } + +.la-yelp:before { + content: "\f1e9"; } + +.la-yen-sign:before { + content: "\f157"; } + +.la-yin-yang:before { + content: "\f6ad"; } + +.la-yoast:before { + content: "\f2b1"; } + +.la-youtube:before { + content: "\f167"; } + +.la-youtube-square:before { + content: "\f431"; } + +.la-zhihu:before { + content: "\f63f"; } + +.sr-only { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } + +.sr-only-focusable:active, .sr-only-focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + width: auto; } +@font-face { + font-family: 'Line Awesome Brands'; + font-style: normal; + font-weight: normal; + font-display: auto; + src: url("../fonts/la-brands-400.eot"); + src: url("../fonts/la-brands-400.eot?#iefix") format("embedded-opentype"), url("../fonts/la-brands-400.woff2") format("woff2"), url("../fonts/la-brands-400.woff") format("woff"), url("../fonts/la-brands-400.ttf") format("truetype"), url("../fonts/la-brands-400.svg#lineawesome") format("svg"); } + +.lab { + font-family: 'Line Awesome Brands'; } +@font-face { + font-family: 'Line Awesome Free'; + font-style: normal; + font-weight: 400; + font-display: auto; + src: url("../fonts/la-regular-400.eot"); + src: url("../fonts/la-regular-400.eot?#iefix") format("embedded-opentype"), url("../fonts/la-regular-400.woff2") format("woff2"), url("../fonts/la-regular-400.woff") format("woff"), url("../fonts/la-regular-400.ttf") format("truetype"), url("../fonts/la-regular-400.svg#lineawesome") format("svg"); } + +.lar { + font-family: 'Line Awesome Free'; + font-weight: 400; } +@font-face { + font-family: 'Line Awesome Free'; + font-style: normal; + font-weight: 900; + font-display: auto; + src: url("../fonts/la-solid-900.eot"); + src: url("../fonts/la-solid-900.eot?#iefix") format("embedded-opentype"), url("../fonts/la-solid-900.woff2") format("woff2"), url("../fonts/la-solid-900.woff") format("woff"), url("../fonts/la-solid-900.ttf") format("truetype"), url("../fonts/la-solid-900.svg#lineawesome") format("svg"); } + +.la, +.las { + font-family: 'Line Awesome Free'; + font-weight: 900; } + +.la.la-glass:before { + content: "\f000"; } + +.la.la-meetup { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-star-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-star-o:before { + content: "\f005"; } + +.la.la-remove:before { + content: "\f00d"; } + +.la.la-close:before { + content: "\f00d"; } + +.la.la-gear:before { + content: "\f013"; } + +.la.la-trash-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-trash-o:before { + content: "\f2ed"; } + +.la.la-file-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-o:before { + content: "\f15b"; } + +.la.la-clock-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-clock-o:before { + content: "\f017"; } + +.la.la-arrow-circle-o-down { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-arrow-circle-o-down:before { + content: "\f358"; } + +.la.la-arrow-circle-o-up { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-arrow-circle-o-up:before { + content: "\f35b"; } + +.la.la-play-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-play-circle-o:before { + content: "\f144"; } + +.la.la-repeat:before { + content: "\f01e"; } + +.la.la-rotate-right:before { + content: "\f01e"; } + +.la.la-refresh:before { + content: "\f021"; } + +.la.la-list-alt { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-dedent:before { + content: "\f03b"; } + +.la.la-video-camera:before { + content: "\f03d"; } + +.la.la-picture-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-picture-o:before { + content: "\f03e"; } + +.la.la-photo { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-photo:before { + content: "\f03e"; } + +.la.la-image { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-image:before { + content: "\f03e"; } + +.la.la-pencil:before { + content: "\f303"; } + +.la.la-map-marker:before { + content: "\f3c5"; } + +.la.la-pencil-square-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-pencil-square-o:before { + content: "\f044"; } + +.la.la-share-square-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-share-square-o:before { + content: "\f14d"; } + +.la.la-check-square-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-check-square-o:before { + content: "\f14a"; } + +.la.la-arrows:before { + content: "\f0b2"; } + +.la.la-times-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-times-circle-o:before { + content: "\f057"; } + +.la.la-check-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-check-circle-o:before { + content: "\f058"; } + +.la.la-mail-forward:before { + content: "\f064"; } + +.la.la-eye { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-eye-slash { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-warning:before { + content: "\f071"; } + +.la.la-calendar:before { + content: "\f073"; } + +.la.la-arrows-v:before { + content: "\f338"; } + +.la.la-arrows-h:before { + content: "\f337"; } + +.la.la-bar-chart { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-bar-chart:before { + content: "\f080"; } + +.la.la-bar-chart-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-bar-chart-o:before { + content: "\f080"; } + +.la.la-twitter-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-facebook-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-gears:before { + content: "\f085"; } + +.la.la-thumbs-o-up { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-thumbs-o-up:before { + content: "\f164"; } + +.la.la-thumbs-o-down { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-thumbs-o-down:before { + content: "\f165"; } + +.la.la-heart-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-heart-o:before { + content: "\f004"; } + +.la.la-sign-out:before { + content: "\f2f5"; } + +.la.la-linkedin-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-linkedin-square:before { + content: "\f08c"; } + +.la.la-thumb-tack:before { + content: "\f08d"; } + +.la.la-external-link:before { + content: "\f35d"; } + +.la.la-sign-in:before { + content: "\f2f6"; } + +.la.la-github-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-lemon-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-lemon-o:before { + content: "\f094"; } + +.la.la-square-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-square-o:before { + content: "\f0c8"; } + +.la.la-bookmark-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-bookmark-o:before { + content: "\f02e"; } + +.la.la-twitter { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-facebook { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-facebook:before { + content: "\f39e"; } + +.la.la-facebook-f { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-facebook-f:before { + content: "\f39e"; } + +.la.la-github { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-credit-card { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-feed:before { + content: "\f09e"; } + +.la.la-hdd-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hdd-o:before { + content: "\f0a0"; } + +.la.la-hand-o-right { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-o-right:before { + content: "\f0a4"; } + +.la.la-hand-o-left { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-o-left:before { + content: "\f0a5"; } + +.la.la-hand-o-up { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-o-up:before { + content: "\f0a6"; } + +.la.la-hand-o-down { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-o-down:before { + content: "\f0a7"; } + +.la.la-arrows-alt:before { + content: "\f31e"; } + +.la.la-group:before { + content: "\f0c0"; } + +.la.la-chain:before { + content: "\f0c1"; } + +.la.la-scissors:before { + content: "\f0c4"; } + +.la.la-files-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-files-o:before { + content: "\f0c5"; } + +.la.la-floppy-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-floppy-o:before { + content: "\f0c7"; } + +.la.la-navicon:before { + content: "\f0c9"; } + +.la.la-reorder:before { + content: "\f0c9"; } + +.la.la-pinterest { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-pinterest-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-google-plus-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-google-plus { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-google-plus:before { + content: "\f0d5"; } + +.la.la-money { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-money:before { + content: "\f3d1"; } + +.la.la-unsorted:before { + content: "\f0dc"; } + +.la.la-sort-desc:before { + content: "\f0dd"; } + +.la.la-sort-asc:before { + content: "\f0de"; } + +.la.la-linkedin { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-linkedin:before { + content: "\f0e1"; } + +.la.la-rotate-left:before { + content: "\f0e2"; } + +.la.la-legal:before { + content: "\f0e3"; } + +.la.la-tachometer:before { + content: "\f3fd"; } + +.la.la-dashboard:before { + content: "\f3fd"; } + +.la.la-comment-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-comment-o:before { + content: "\f075"; } + +.la.la-comments-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-comments-o:before { + content: "\f086"; } + +.la.la-flash:before { + content: "\f0e7"; } + +.la.la-clipboard { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-paste { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-paste:before { + content: "\f328"; } + +.la.la-lightbulb-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-lightbulb-o:before { + content: "\f0eb"; } + +.la.la-exchange:before { + content: "\f362"; } + +.la.la-cloud-download:before { + content: "\f381"; } + +.la.la-cloud-upload:before { + content: "\f382"; } + +.la.la-bell-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-bell-o:before { + content: "\f0f3"; } + +.la.la-cutlery:before { + content: "\f2e7"; } + +.la.la-file-text-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-text-o:before { + content: "\f15c"; } + +.la.la-building-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-building-o:before { + content: "\f1ad"; } + +.la.la-hospital-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hospital-o:before { + content: "\f0f8"; } + +.la.la-tablet:before { + content: "\f3fa"; } + +.la.la-mobile:before { + content: "\f3cd"; } + +.la.la-mobile-phone:before { + content: "\f3cd"; } + +.la.la-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-circle-o:before { + content: "\f111"; } + +.la.la-mail-reply:before { + content: "\f3e5"; } + +.la.la-github-alt { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-folder-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-folder-o:before { + content: "\f07b"; } + +.la.la-folder-open-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-folder-open-o:before { + content: "\f07c"; } + +.la.la-smile-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-smile-o:before { + content: "\f118"; } + +.la.la-frown-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-frown-o:before { + content: "\f119"; } + +.la.la-meh-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-meh-o:before { + content: "\f11a"; } + +.la.la-keyboard-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-keyboard-o:before { + content: "\f11c"; } + +.la.la-flag-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-flag-o:before { + content: "\f024"; } + +.la.la-mail-reply-all:before { + content: "\f122"; } + +.la.la-star-half-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-star-half-o:before { + content: "\f089"; } + +.la.la-star-half-empty { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-star-half-empty:before { + content: "\f089"; } + +.la.la-star-half-full { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-star-half-full:before { + content: "\f089"; } + +.la.la-code-fork:before { + content: "\f126"; } + +.la.la-chain-broken:before { + content: "\f127"; } + +.la.la-shield:before { + content: "\f3ed"; } + +.la.la-calendar-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-calendar-o:before { + content: "\f133"; } + +.la.la-maxcdn { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-html5 { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-css3 { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-ticket:before { + content: "\f3ff"; } + +.la.la-minus-square-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-minus-square-o:before { + content: "\f146"; } + +.la.la-level-up:before { + content: "\f3bf"; } + +.la.la-level-down:before { + content: "\f3be"; } + +.la.la-pencil-square:before { + content: "\f14b"; } + +.la.la-external-link-square:before { + content: "\f360"; } + +.la.la-compass { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-caret-square-o-down { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-caret-square-o-down:before { + content: "\f150"; } + +.la.la-toggle-down { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-toggle-down:before { + content: "\f150"; } + +.la.la-caret-square-o-up { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-caret-square-o-up:before { + content: "\f151"; } + +.la.la-toggle-up { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-toggle-up:before { + content: "\f151"; } + +.la.la-caret-square-o-right { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-caret-square-o-right:before { + content: "\f152"; } + +.la.la-toggle-right { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-toggle-right:before { + content: "\f152"; } + +.la.la-eur:before { + content: "\f153"; } + +.la.la-euro:before { + content: "\f153"; } + +.la.la-gbp:before { + content: "\f154"; } + +.la.la-usd:before { + content: "\f155"; } + +.la.la-dollar:before { + content: "\f155"; } + +.la.la-inr:before { + content: "\f156"; } + +.la.la-rupee:before { + content: "\f156"; } + +.la.la-jpy:before { + content: "\f157"; } + +.la.la-cny:before { + content: "\f157"; } + +.la.la-rmb:before { + content: "\f157"; } + +.la.la-yen:before { + content: "\f157"; } + +.la.la-rub:before { + content: "\f158"; } + +.la.la-ruble:before { + content: "\f158"; } + +.la.la-rouble:before { + content: "\f158"; } + +.la.la-krw:before { + content: "\f159"; } + +.la.la-won:before { + content: "\f159"; } + +.la.la-btc { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-bitcoin { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-bitcoin:before { + content: "\f15a"; } + +.la.la-file-text:before { + content: "\f15c"; } + +.la.la-sort-alpha-asc:before { + content: "\f15d"; } + +.la.la-sort-alpha-desc:before { + content: "\f881"; } + +.la.la-sort-amount-asc:before { + content: "\f160"; } + +.la.la-sort-amount-desc:before { + content: "\f884"; } + +.la.la-sort-numeric-asc:before { + content: "\f162"; } + +.la.la-sort-numeric-desc:before { + content: "\f886"; } + +.la.la-youtube-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-youtube { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-xing { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-xing-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-youtube-play { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-youtube-play:before { + content: "\f167"; } + +.la.la-dropbox { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-stack-overflow { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-instagram { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-flickr { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-adn { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-bitbucket { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-bitbucket-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-bitbucket-square:before { + content: "\f171"; } + +.la.la-tumblr { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-tumblr-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-long-arrow-down:before { + content: "\f309"; } + +.la.la-long-arrow-up:before { + content: "\f30c"; } + +.la.la-long-arrow-left:before { + content: "\f30a"; } + +.la.la-long-arrow-right:before { + content: "\f30b"; } + +.la.la-apple { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-windows { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-android { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-linux { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-dribbble { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-skype { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-foursquare { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-trello { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-gratipay { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-gittip { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-gittip:before { + content: "\f184"; } + +.la.la-sun-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-sun-o:before { + content: "\f185"; } + +.la.la-moon-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-moon-o:before { + content: "\f186"; } + +.la.la-vk { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-weibo { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-renren { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-pagelines { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-stack-exchange { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-arrow-circle-o-right { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-arrow-circle-o-right:before { + content: "\f35a"; } + +.la.la-arrow-circle-o-left { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-arrow-circle-o-left:before { + content: "\f359"; } + +.la.la-caret-square-o-left { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-caret-square-o-left:before { + content: "\f191"; } + +.la.la-toggle-left { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-toggle-left:before { + content: "\f191"; } + +.la.la-dot-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-dot-circle-o:before { + content: "\f192"; } + +.la.la-vimeo-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-try:before { + content: "\f195"; } + +.la.la-turkish-lira:before { + content: "\f195"; } + +.la.la-plus-square-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-plus-square-o:before { + content: "\f0fe"; } + +.la.la-slack { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wordpress { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-openid { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-institution:before { + content: "\f19c"; } + +.la.la-bank:before { + content: "\f19c"; } + +.la.la-mortar-board:before { + content: "\f19d"; } + +.la.la-yahoo { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-google { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-reddit { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-reddit-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-stumbleupon-circle { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-stumbleupon { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-delicious { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-digg { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-pied-piper-pp { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-pied-piper-alt { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-drupal { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-joomla { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-spoon:before { + content: "\f2e5"; } + +.la.la-behance { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-behance-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-steam { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-steam-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-automobile:before { + content: "\f1b9"; } + +.la.la-cab:before { + content: "\f1ba"; } + +.la.la-envelope-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-envelope-o:before { + content: "\f0e0"; } + +.la.la-deviantart { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-soundcloud { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-file-pdf-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-pdf-o:before { + content: "\f1c1"; } + +.la.la-file-word-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-word-o:before { + content: "\f1c2"; } + +.la.la-file-excel-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-excel-o:before { + content: "\f1c3"; } + +.la.la-file-powerpoint-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-powerpoint-o:before { + content: "\f1c4"; } + +.la.la-file-image-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-image-o:before { + content: "\f1c5"; } + +.la.la-file-photo-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-photo-o:before { + content: "\f1c5"; } + +.la.la-file-picture-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-picture-o:before { + content: "\f1c5"; } + +.la.la-file-archive-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-archive-o:before { + content: "\f1c6"; } + +.la.la-file-zip-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-zip-o:before { + content: "\f1c6"; } + +.la.la-file-audio-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-audio-o:before { + content: "\f1c7"; } + +.la.la-file-sound-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-sound-o:before { + content: "\f1c7"; } + +.la.la-file-video-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-video-o:before { + content: "\f1c8"; } + +.la.la-file-movie-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-movie-o:before { + content: "\f1c8"; } + +.la.la-file-code-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-file-code-o:before { + content: "\f1c9"; } + +.la.la-vine { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-codepen { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-jsfiddle { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-life-ring { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-life-bouy { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-life-bouy:before { + content: "\f1cd"; } + +.la.la-life-buoy { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-life-buoy:before { + content: "\f1cd"; } + +.la.la-life-saver { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-life-saver:before { + content: "\f1cd"; } + +.la.la-support { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-support:before { + content: "\f1cd"; } + +.la.la-circle-o-notch:before { + content: "\f1ce"; } + +.la.la-rebel { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-ra { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-ra:before { + content: "\f1d0"; } + +.la.la-resistance { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-resistance:before { + content: "\f1d0"; } + +.la.la-empire { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-ge { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-ge:before { + content: "\f1d1"; } + +.la.la-git-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-git { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-hacker-news { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-y-combinator-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-y-combinator-square:before { + content: "\f1d4"; } + +.la.la-yc-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-yc-square:before { + content: "\f1d4"; } + +.la.la-tencent-weibo { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-qq { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-weixin { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wechat { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wechat:before { + content: "\f1d7"; } + +.la.la-send:before { + content: "\f1d8"; } + +.la.la-paper-plane-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-paper-plane-o:before { + content: "\f1d8"; } + +.la.la-send-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-send-o:before { + content: "\f1d8"; } + +.la.la-circle-thin { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-circle-thin:before { + content: "\f111"; } + +.la.la-header:before { + content: "\f1dc"; } + +.la.la-sliders:before { + content: "\f1de"; } + +.la.la-futbol-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-futbol-o:before { + content: "\f1e3"; } + +.la.la-soccer-ball-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-soccer-ball-o:before { + content: "\f1e3"; } + +.la.la-slideshare { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-twitch { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-yelp { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-newspaper-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-newspaper-o:before { + content: "\f1ea"; } + +.la.la-paypal { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-google-wallet { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-cc-visa { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-cc-mastercard { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-cc-discover { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-cc-amex { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-cc-paypal { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-cc-stripe { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-bell-slash-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-bell-slash-o:before { + content: "\f1f6"; } + +.la.la-trash:before { + content: "\f2ed"; } + +.la.la-copyright { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-eyedropper:before { + content: "\f1fb"; } + +.la.la-area-chart:before { + content: "\f1fe"; } + +.la.la-pie-chart:before { + content: "\f200"; } + +.la.la-line-chart:before { + content: "\f201"; } + +.la.la-lastfm { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-lastfm-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-ioxhost { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-angellist { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-cc { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-cc:before { + content: "\f20a"; } + +.la.la-ils:before { + content: "\f20b"; } + +.la.la-shekel:before { + content: "\f20b"; } + +.la.la-sheqel:before { + content: "\f20b"; } + +.la.la-meanpath { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-meanpath:before { + content: "\f2b4"; } + +.la.la-buysellads { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-connectdevelop { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-dashcube { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-forumbee { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-leanpub { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-sellsy { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-shirtsinbulk { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-simplybuilt { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-skyatlas { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-diamond { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-diamond:before { + content: "\f3a5"; } + +.la.la-intersex:before { + content: "\f224"; } + +.la.la-facebook-official { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-facebook-official:before { + content: "\f09a"; } + +.la.la-pinterest-p { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-whatsapp { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-hotel:before { + content: "\f236"; } + +.la.la-viacoin { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-medium { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-y-combinator { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-yc { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-yc:before { + content: "\f23b"; } + +.la.la-optin-monster { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-opencart { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-expeditedssl { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-battery-4:before { + content: "\f240"; } + +.la.la-battery:before { + content: "\f240"; } + +.la.la-battery-3:before { + content: "\f241"; } + +.la.la-battery-2:before { + content: "\f242"; } + +.la.la-battery-1:before { + content: "\f243"; } + +.la.la-battery-0:before { + content: "\f244"; } + +.la.la-object-group { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-object-ungroup { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-sticky-note-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-sticky-note-o:before { + content: "\f249"; } + +.la.la-cc-jcb { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-cc-diners-club { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-clone { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hourglass-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hourglass-o:before { + content: "\f254"; } + +.la.la-hourglass-1:before { + content: "\f251"; } + +.la.la-hourglass-2:before { + content: "\f252"; } + +.la.la-hourglass-3:before { + content: "\f253"; } + +.la.la-hand-rock-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-rock-o:before { + content: "\f255"; } + +.la.la-hand-grab-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-grab-o:before { + content: "\f255"; } + +.la.la-hand-paper-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-paper-o:before { + content: "\f256"; } + +.la.la-hand-stop-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-stop-o:before { + content: "\f256"; } + +.la.la-hand-scissors-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-scissors-o:before { + content: "\f257"; } + +.la.la-hand-lizard-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-lizard-o:before { + content: "\f258"; } + +.la.la-hand-spock-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-spock-o:before { + content: "\f259"; } + +.la.la-hand-pointer-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-pointer-o:before { + content: "\f25a"; } + +.la.la-hand-peace-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-hand-peace-o:before { + content: "\f25b"; } + +.la.la-registered { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-creative-commons { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-gg { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-gg-circle { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-tripadvisor { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-odnoklassniki { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-odnoklassniki-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-get-pocket { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wikipedia-w { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-safari { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-chrome { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-firefox { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-opera { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-internet-explorer { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-television:before { + content: "\f26c"; } + +.la.la-contao { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-500px { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-amazon { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-calendar-plus-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-calendar-plus-o:before { + content: "\f271"; } + +.la.la-calendar-minus-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-calendar-minus-o:before { + content: "\f272"; } + +.la.la-calendar-times-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-calendar-times-o:before { + content: "\f273"; } + +.la.la-calendar-check-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-calendar-check-o:before { + content: "\f274"; } + +.la.la-map-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-map-o:before { + content: "\f279"; } + +.la.la-commenting:before { + content: "\f4ad"; } + +.la.la-commenting-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-commenting-o:before { + content: "\f4ad"; } + +.la.la-houzz { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-vimeo { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-vimeo:before { + content: "\f27d"; } + +.la.la-black-tie { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-fonticons { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-reddit-alien { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-edge { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-credit-card-alt:before { + content: "\f09d"; } + +.la.la-codiepie { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-modx { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-fort-awesome { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-usb { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-product-hunt { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-mixcloud { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-scribd { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-pause-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-pause-circle-o:before { + content: "\f28b"; } + +.la.la-stop-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-stop-circle-o:before { + content: "\f28d"; } + +.la.la-bluetooth { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-bluetooth-b { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-gitlab { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wpbeginner { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wpforms { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-envira { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wheelchair-alt { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wheelchair-alt:before { + content: "\f368"; } + +.la.la-question-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-question-circle-o:before { + content: "\f059"; } + +.la.la-volume-control-phone:before { + content: "\f2a0"; } + +.la.la-asl-interpreting:before { + content: "\f2a3"; } + +.la.la-deafness:before { + content: "\f2a4"; } + +.la.la-hard-of-hearing:before { + content: "\f2a4"; } + +.la.la-glide { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-glide-g { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-signing:before { + content: "\f2a7"; } + +.la.la-viadeo { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-viadeo-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-snapchat { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-snapchat-ghost { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-snapchat-square { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-pied-piper { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-first-order { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-yoast { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-themeisle { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-google-plus-official { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-google-plus-official:before { + content: "\f2b3"; } + +.la.la-google-plus-circle { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-google-plus-circle:before { + content: "\f2b3"; } + +.la.la-font-awesome { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-fa { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-fa:before { + content: "\f2b4"; } + +.la.la-handshake-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-handshake-o:before { + content: "\f2b5"; } + +.la.la-envelope-open-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-envelope-open-o:before { + content: "\f2b6"; } + +.la.la-linode { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-address-book-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-address-book-o:before { + content: "\f2b9"; } + +.la.la-vcard:before { + content: "\f2bb"; } + +.la.la-address-card-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-address-card-o:before { + content: "\f2bb"; } + +.la.la-vcard-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-vcard-o:before { + content: "\f2bb"; } + +.la.la-user-circle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-user-circle-o:before { + content: "\f2bd"; } + +.la.la-user-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-user-o:before { + content: "\f007"; } + +.la.la-id-badge { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-drivers-license:before { + content: "\f2c2"; } + +.la.la-id-card-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-id-card-o:before { + content: "\f2c2"; } + +.la.la-drivers-license-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-drivers-license-o:before { + content: "\f2c2"; } + +.la.la-quora { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-free-code-camp { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-telegram { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-thermometer-4:before { + content: "\f2c7"; } + +.la.la-thermometer:before { + content: "\f2c7"; } + +.la.la-thermometer-3:before { + content: "\f2c8"; } + +.la.la-thermometer-2:before { + content: "\f2c9"; } + +.la.la-thermometer-1:before { + content: "\f2ca"; } + +.la.la-thermometer-0:before { + content: "\f2cb"; } + +.la.la-bathtub:before { + content: "\f2cd"; } + +.la.la-s15:before { + content: "\f2cd"; } + +.la.la-window-maximize { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-window-restore { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-times-rectangle:before { + content: "\f410"; } + +.la.la-window-close-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-window-close-o:before { + content: "\f410"; } + +.la.la-times-rectangle-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-times-rectangle-o:before { + content: "\f410"; } + +.la.la-bandcamp { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-grav { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-etsy { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-imdb { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-ravelry { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-eercast { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-eercast:before { + content: "\f2da"; } + +.la.la-snowflake-o { + font-family: 'Line Awesome Free'; + font-weight: 400; } + +.la.la-snowflake-o:before { + content: "\f2dc"; } + +.la.la-superpowers { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-wpexplorer { + font-family: 'Line Awesome Brands'; + font-weight: 400; } + +.la.la-spotify { + font-family: 'Line Awesome Brands'; + font-weight: 400; } diff --git a/python/static/css/line-awesome.min.css b/python/static/css/line-awesome.min.css new file mode 100644 index 0000000..5636d52 --- /dev/null +++ b/python/static/css/line-awesome.min.css @@ -0,0 +1 @@ +.la,.lab,.lad,.lal,.lar,.las{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.la-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.la-xs{font-size:.75em}.la-sm{font-size:.875em}.la-1x{font-size:1em}.la-2x{font-size:2em}.la-3x{font-size:3em}.la-4x{font-size:4em}.la-5x{font-size:5em}.la-6x{font-size:6em}.la-7x{font-size:7em}.la-8x{font-size:8em}.la-9x{font-size:9em}.la-10x{font-size:10em}.la-fw{text-align:center;width:1.25em}.la-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.la-ul>li{position:relative}.la-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.la-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.la-pull-left{float:left}.la-pull-right{float:right}.la.la-pull-left,.lab.la-pull-left,.lal.la-pull-left,.lar.la-pull-left,.las.la-pull-left{margin-right:.3em}.la.la-pull-right,.lab.la-pull-right,.lal.la-pull-right,.lar.la-pull-right,.las.la-pull-right{margin-left:.3em}.la-spin{-webkit-animation:la-spin 2s infinite linear;animation:la-spin 2s infinite linear}.la-pulse{-webkit-animation:la-spin 1s infinite steps(8);animation:la-spin 1s infinite steps(8)}@-webkit-keyframes la-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes la-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.la-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.la-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.la-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.la-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.la-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.la-flip-both,.la-flip-horizontal.la-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .la-flip-both,:root .la-flip-horizontal,:root .la-flip-vertical,:root .la-rotate-180,:root .la-rotate-270,:root .la-rotate-90{-webkit-filter:none;filter:none}.la-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.la-stack-1x,.la-stack-2x{left:0;position:absolute;text-align:center;width:100%}.la-stack-1x{line-height:inherit}.la-stack-2x{font-size:2em}.la-inverse{color:#fff}.la-500px:before{content:"\f26e"}.la-accessible-icon:before{content:"\f368"}.la-accusoft:before{content:"\f369"}.la-acquisitions-incorporated:before{content:"\f6af"}.la-ad:before{content:"\f641"}.la-address-book:before{content:"\f2b9"}.la-address-card:before{content:"\f2bb"}.la-adjust:before{content:"\f042"}.la-adn:before{content:"\f170"}.la-adobe:before{content:"\f778"}.la-adversal:before{content:"\f36a"}.la-affiliatetheme:before{content:"\f36b"}.la-air-freshener:before{content:"\f5d0"}.la-airbnb:before{content:"\f834"}.la-algolia:before{content:"\f36c"}.la-align-center:before{content:"\f037"}.la-align-justify:before{content:"\f039"}.la-align-left:before{content:"\f036"}.la-align-right:before{content:"\f038"}.la-alipay:before{content:"\f642"}.la-allergies:before{content:"\f461"}.la-amazon:before{content:"\f270"}.la-amazon-pay:before{content:"\f42c"}.la-ambulance:before{content:"\f0f9"}.la-american-sign-language-interpreting:before{content:"\f2a3"}.la-amilia:before{content:"\f36d"}.la-anchor:before{content:"\f13d"}.la-android:before{content:"\f17b"}.la-angellist:before{content:"\f209"}.la-angle-double-down:before{content:"\f103"}.la-angle-double-left:before{content:"\f100"}.la-angle-double-right:before{content:"\f101"}.la-angle-double-up:before{content:"\f102"}.la-angle-down:before{content:"\f107"}.la-angle-left:before{content:"\f104"}.la-angle-right:before{content:"\f105"}.la-angle-up:before{content:"\f106"}.la-angry:before{content:"\f556"}.la-angrycreative:before{content:"\f36e"}.la-angular:before{content:"\f420"}.la-ankh:before{content:"\f644"}.la-app-store:before{content:"\f36f"}.la-app-store-ios:before{content:"\f370"}.la-apper:before{content:"\f371"}.la-apple:before{content:"\f179"}.la-apple-alt:before{content:"\f5d1"}.la-apple-pay:before{content:"\f415"}.la-archive:before{content:"\f187"}.la-archway:before{content:"\f557"}.la-arrow-alt-circle-down:before{content:"\f358"}.la-arrow-alt-circle-left:before{content:"\f359"}.la-arrow-alt-circle-right:before{content:"\f35a"}.la-arrow-alt-circle-up:before{content:"\f35b"}.la-arrow-circle-down:before{content:"\f0ab"}.la-arrow-circle-left:before{content:"\f0a8"}.la-arrow-circle-right:before{content:"\f0a9"}.la-arrow-circle-up:before{content:"\f0aa"}.la-arrow-down:before{content:"\f063"}.la-arrow-left:before{content:"\f060"}.la-arrow-right:before{content:"\f061"}.la-arrow-up:before{content:"\f062"}.la-arrows-alt:before{content:"\f0b2"}.la-arrows-alt-h:before{content:"\f337"}.la-arrows-alt-v:before{content:"\f338"}.la-artstation:before{content:"\f77a"}.la-assistive-listening-systems:before{content:"\f2a2"}.la-asterisk:before{content:"\f069"}.la-asymmetrik:before{content:"\f372"}.la-at:before{content:"\f1fa"}.la-atlas:before{content:"\f558"}.la-atlassian:before{content:"\f77b"}.la-atom:before{content:"\f5d2"}.la-audible:before{content:"\f373"}.la-audio-description:before{content:"\f29e"}.la-autoprefixer:before{content:"\f41c"}.la-avianex:before{content:"\f374"}.la-aviato:before{content:"\f421"}.la-award:before{content:"\f559"}.la-aws:before{content:"\f375"}.la-baby:before{content:"\f77c"}.la-baby-carriage:before{content:"\f77d"}.la-backspace:before{content:"\f55a"}.la-backward:before{content:"\f04a"}.la-bacon:before{content:"\f7e5"}.la-balance-scale:before{content:"\f24e"}.la-balance-scale-left:before{content:"\f515"}.la-balance-scale-right:before{content:"\f516"}.la-ban:before{content:"\f05e"}.la-band-aid:before{content:"\f462"}.la-bandcamp:before{content:"\f2d5"}.la-barcode:before{content:"\f02a"}.la-bars:before{content:"\f0c9"}.la-baseball-ball:before{content:"\f433"}.la-basketball-ball:before{content:"\f434"}.la-bath:before{content:"\f2cd"}.la-battery-empty:before{content:"\f244"}.la-battery-full:before{content:"\f240"}.la-battery-half:before{content:"\f242"}.la-battery-quarter:before{content:"\f243"}.la-battery-three-quarters:before{content:"\f241"}.la-battle-net:before{content:"\f835"}.la-bed:before{content:"\f236"}.la-beer:before{content:"\f0fc"}.la-behance:before{content:"\f1b4"}.la-behance-square:before{content:"\f1b5"}.la-bell:before{content:"\f0f3"}.la-bell-slash:before{content:"\f1f6"}.la-bezier-curve:before{content:"\f55b"}.la-bible:before{content:"\f647"}.la-bicycle:before{content:"\f206"}.la-biking:before{content:"\f84a"}.la-bimobject:before{content:"\f378"}.la-binoculars:before{content:"\f1e5"}.la-biohazard:before{content:"\f780"}.la-birthday-cake:before{content:"\f1fd"}.la-bitbucket:before{content:"\f171"}.la-bitcoin:before{content:"\f379"}.la-bity:before{content:"\f37a"}.la-black-tie:before{content:"\f27e"}.la-blackberry:before{content:"\f37b"}.la-blender:before{content:"\f517"}.la-blender-phone:before{content:"\f6b6"}.la-blind:before{content:"\f29d"}.la-blog:before{content:"\f781"}.la-blogger:before{content:"\f37c"}.la-blogger-b:before{content:"\f37d"}.la-bluetooth:before{content:"\f293"}.la-bluetooth-b:before{content:"\f294"}.la-bold:before{content:"\f032"}.la-bolt:before{content:"\f0e7"}.la-bomb:before{content:"\f1e2"}.la-bone:before{content:"\f5d7"}.la-bong:before{content:"\f55c"}.la-book:before{content:"\f02d"}.la-book-dead:before{content:"\f6b7"}.la-book-medical:before{content:"\f7e6"}.la-book-open:before{content:"\f518"}.la-book-reader:before{content:"\f5da"}.la-bookmark:before{content:"\f02e"}.la-bootstrap:before{content:"\f836"}.la-border-all:before{content:"\f84c"}.la-border-none:before{content:"\f850"}.la-border-style:before{content:"\f853"}.la-bowling-ball:before{content:"\f436"}.la-box:before{content:"\f466"}.la-box-open:before{content:"\f49e"}.la-boxes:before{content:"\f468"}.la-braille:before{content:"\f2a1"}.la-brain:before{content:"\f5dc"}.la-bread-slice:before{content:"\f7ec"}.la-briefcase:before{content:"\f0b1"}.la-briefcase-medical:before{content:"\f469"}.la-broadcast-tower:before{content:"\f519"}.la-broom:before{content:"\f51a"}.la-brush:before{content:"\f55d"}.la-btc:before{content:"\f15a"}.la-buffer:before{content:"\f837"}.la-bug:before{content:"\f188"}.la-building:before{content:"\f1ad"}.la-bullhorn:before{content:"\f0a1"}.la-bullseye:before{content:"\f140"}.la-burn:before{content:"\f46a"}.la-buromobelexperte:before{content:"\f37f"}.la-bus:before{content:"\f207"}.la-bus-alt:before{content:"\f55e"}.la-business-time:before{content:"\f64a"}.la-buy-n-large:before{content:"\f8a6"}.la-buysellads:before{content:"\f20d"}.la-calculator:before{content:"\f1ec"}.la-calendar:before{content:"\f133"}.la-calendar-alt:before{content:"\f073"}.la-calendar-check:before{content:"\f274"}.la-calendar-day:before{content:"\f783"}.la-calendar-minus:before{content:"\f272"}.la-calendar-plus:before{content:"\f271"}.la-calendar-times:before{content:"\f273"}.la-calendar-week:before{content:"\f784"}.la-camera:before{content:"\f030"}.la-camera-retro:before{content:"\f083"}.la-campground:before{content:"\f6bb"}.la-canadian-maple-leaf:before{content:"\f785"}.la-candy-cane:before{content:"\f786"}.la-cannabis:before{content:"\f55f"}.la-capsules:before{content:"\f46b"}.la-car:before{content:"\f1b9"}.la-car-alt:before{content:"\f5de"}.la-car-battery:before{content:"\f5df"}.la-car-crash:before{content:"\f5e1"}.la-car-side:before{content:"\f5e4"}.la-caret-down:before{content:"\f0d7"}.la-caret-left:before{content:"\f0d9"}.la-caret-right:before{content:"\f0da"}.la-caret-square-down:before{content:"\f150"}.la-caret-square-left:before{content:"\f191"}.la-caret-square-right:before{content:"\f152"}.la-caret-square-up:before{content:"\f151"}.la-caret-up:before{content:"\f0d8"}.la-carrot:before{content:"\f787"}.la-cart-arrow-down:before{content:"\f218"}.la-cart-plus:before{content:"\f217"}.la-cash-register:before{content:"\f788"}.la-cat:before{content:"\f6be"}.la-cc-amazon-pay:before{content:"\f42d"}.la-cc-amex:before{content:"\f1f3"}.la-cc-apple-pay:before{content:"\f416"}.la-cc-diners-club:before{content:"\f24c"}.la-cc-discover:before{content:"\f1f2"}.la-cc-jcb:before{content:"\f24b"}.la-cc-mastercard:before{content:"\f1f1"}.la-cc-paypal:before{content:"\f1f4"}.la-cc-stripe:before{content:"\f1f5"}.la-cc-visa:before{content:"\f1f0"}.la-centercode:before{content:"\f380"}.la-centos:before{content:"\f789"}.la-certificate:before{content:"\f0a3"}.la-chair:before{content:"\f6c0"}.la-chalkboard:before{content:"\f51b"}.la-chalkboard-teacher:before{content:"\f51c"}.la-charging-station:before{content:"\f5e7"}.la-chart-area:before{content:"\f1fe"}.la-chart-bar:before{content:"\f080"}.la-chart-line:before{content:"\f201"}.la-chart-pie:before{content:"\f200"}.la-check:before{content:"\f00c"}.la-check-circle:before{content:"\f058"}.la-check-double:before{content:"\f560"}.la-check-square:before{content:"\f14a"}.la-cheese:before{content:"\f7ef"}.la-chess:before{content:"\f439"}.la-chess-bishop:before{content:"\f43a"}.la-chess-board:before{content:"\f43c"}.la-chess-king:before{content:"\f43f"}.la-chess-knight:before{content:"\f441"}.la-chess-pawn:before{content:"\f443"}.la-chess-queen:before{content:"\f445"}.la-chess-rook:before{content:"\f447"}.la-chevron-circle-down:before{content:"\f13a"}.la-chevron-circle-left:before{content:"\f137"}.la-chevron-circle-right:before{content:"\f138"}.la-chevron-circle-up:before{content:"\f139"}.la-chevron-down:before{content:"\f078"}.la-chevron-left:before{content:"\f053"}.la-chevron-right:before{content:"\f054"}.la-chevron-up:before{content:"\f077"}.la-child:before{content:"\f1ae"}.la-chrome:before{content:"\f268"}.la-chromecast:before{content:"\f838"}.la-church:before{content:"\f51d"}.la-circle:before{content:"\f111"}.la-circle-notch:before{content:"\f1ce"}.la-city:before{content:"\f64f"}.la-clinic-medical:before{content:"\f7f2"}.la-clipboard:before{content:"\f328"}.la-clipboard-check:before{content:"\f46c"}.la-clipboard-list:before{content:"\f46d"}.la-clock:before{content:"\f017"}.la-clone:before{content:"\f24d"}.la-closed-captioning:before{content:"\f20a"}.la-cloud:before{content:"\f0c2"}.la-cloud-download-alt:before{content:"\f381"}.la-cloud-meatball:before{content:"\f73b"}.la-cloud-moon:before{content:"\f6c3"}.la-cloud-moon-rain:before{content:"\f73c"}.la-cloud-rain:before{content:"\f73d"}.la-cloud-showers-heavy:before{content:"\f740"}.la-cloud-sun:before{content:"\f6c4"}.la-cloud-sun-rain:before{content:"\f743"}.la-cloud-upload-alt:before{content:"\f382"}.la-cloudscale:before{content:"\f383"}.la-cloudsmith:before{content:"\f384"}.la-cloudversify:before{content:"\f385"}.la-cocktail:before{content:"\f561"}.la-code:before{content:"\f121"}.la-code-branch:before{content:"\f126"}.la-codepen:before{content:"\f1cb"}.la-codiepie:before{content:"\f284"}.la-coffee:before{content:"\f0f4"}.la-cog:before{content:"\f013"}.la-cogs:before{content:"\f085"}.la-coins:before{content:"\f51e"}.la-columns:before{content:"\f0db"}.la-comment:before{content:"\f075"}.la-comment-alt:before{content:"\f27a"}.la-comment-dollar:before{content:"\f651"}.la-comment-dots:before{content:"\f4ad"}.la-comment-medical:before{content:"\f7f5"}.la-comment-slash:before{content:"\f4b3"}.la-comments:before{content:"\f086"}.la-comments-dollar:before{content:"\f653"}.la-compact-disc:before{content:"\f51f"}.la-compass:before{content:"\f14e"}.la-compress:before{content:"\f066"}.la-compress-arrows-alt:before{content:"\f78c"}.la-concierge-bell:before{content:"\f562"}.la-confluence:before{content:"\f78d"}.la-connectdevelop:before{content:"\f20e"}.la-contao:before{content:"\f26d"}.la-cookie:before{content:"\f563"}.la-cookie-bite:before{content:"\f564"}.la-copy:before{content:"\f0c5"}.la-copyright:before{content:"\f1f9"}.la-cotton-bureau:before{content:"\f89e"}.la-couch:before{content:"\f4b8"}.la-cpanel:before{content:"\f388"}.la-creative-commons:before{content:"\f25e"}.la-creative-commons-by:before{content:"\f4e7"}.la-creative-commons-nc:before{content:"\f4e8"}.la-creative-commons-nc-eu:before{content:"\f4e9"}.la-creative-commons-nc-jp:before{content:"\f4ea"}.la-creative-commons-nd:before{content:"\f4eb"}.la-creative-commons-pd:before{content:"\f4ec"}.la-creative-commons-pd-alt:before{content:"\f4ed"}.la-creative-commons-remix:before{content:"\f4ee"}.la-creative-commons-sa:before{content:"\f4ef"}.la-creative-commons-sampling:before{content:"\f4f0"}.la-creative-commons-sampling-plus:before{content:"\f4f1"}.la-creative-commons-share:before{content:"\f4f2"}.la-creative-commons-zero:before{content:"\f4f3"}.la-credit-card:before{content:"\f09d"}.la-critical-role:before{content:"\f6c9"}.la-crop:before{content:"\f125"}.la-crop-alt:before{content:"\f565"}.la-cross:before{content:"\f654"}.la-crosshairs:before{content:"\f05b"}.la-crow:before{content:"\f520"}.la-crown:before{content:"\f521"}.la-crutch:before{content:"\f7f7"}.la-css3:before{content:"\f13c"}.la-css3-alt:before{content:"\f38b"}.la-cube:before{content:"\f1b2"}.la-cubes:before{content:"\f1b3"}.la-cut:before{content:"\f0c4"}.la-cuttlefish:before{content:"\f38c"}.la-d-and-d:before{content:"\f38d"}.la-d-and-d-beyond:before{content:"\f6ca"}.la-dashcube:before{content:"\f210"}.la-database:before{content:"\f1c0"}.la-deaf:before{content:"\f2a4"}.la-delicious:before{content:"\f1a5"}.la-democrat:before{content:"\f747"}.la-deploydog:before{content:"\f38e"}.la-deskpro:before{content:"\f38f"}.la-desktop:before{content:"\f108"}.la-dev:before{content:"\f6cc"}.la-deviantart:before{content:"\f1bd"}.la-dharmachakra:before{content:"\f655"}.la-dhl:before{content:"\f790"}.la-diagnoses:before{content:"\f470"}.la-diaspora:before{content:"\f791"}.la-dice:before{content:"\f522"}.la-dice-d20:before{content:"\f6cf"}.la-dice-d6:before{content:"\f6d1"}.la-dice-five:before{content:"\f523"}.la-dice-four:before{content:"\f524"}.la-dice-one:before{content:"\f525"}.la-dice-six:before{content:"\f526"}.la-dice-three:before{content:"\f527"}.la-dice-two:before{content:"\f528"}.la-digg:before{content:"\f1a6"}.la-digital-ocean:before{content:"\f391"}.la-digital-tachograph:before{content:"\f566"}.la-directions:before{content:"\f5eb"}.la-discord:before{content:"\f392"}.la-discourse:before{content:"\f393"}.la-divide:before{content:"\f529"}.la-dizzy:before{content:"\f567"}.la-dna:before{content:"\f471"}.la-dochub:before{content:"\f394"}.la-docker:before{content:"\f395"}.la-dog:before{content:"\f6d3"}.la-dollar-sign:before{content:"\f155"}.la-dolly:before{content:"\f472"}.la-dolly-flatbed:before{content:"\f474"}.la-donate:before{content:"\f4b9"}.la-door-closed:before{content:"\f52a"}.la-door-open:before{content:"\f52b"}.la-dot-circle:before{content:"\f192"}.la-dove:before{content:"\f4ba"}.la-download:before{content:"\f019"}.la-draft2digital:before{content:"\f396"}.la-drafting-compass:before{content:"\f568"}.la-dragon:before{content:"\f6d5"}.la-draw-polygon:before{content:"\f5ee"}.la-dribbble:before{content:"\f17d"}.la-dribbble-square:before{content:"\f397"}.la-dropbox:before{content:"\f16b"}.la-drum:before{content:"\f569"}.la-drum-steelpan:before{content:"\f56a"}.la-drumstick-bite:before{content:"\f6d7"}.la-drupal:before{content:"\f1a9"}.la-dumbbell:before{content:"\f44b"}.la-dumpster:before{content:"\f793"}.la-dumpster-fire:before{content:"\f794"}.la-dungeon:before{content:"\f6d9"}.la-dyalog:before{content:"\f399"}.la-earlybirds:before{content:"\f39a"}.la-ebay:before{content:"\f4f4"}.la-edge:before{content:"\f282"}.la-edit:before{content:"\f044"}.la-egg:before{content:"\f7fb"}.la-eject:before{content:"\f052"}.la-elementor:before{content:"\f430"}.la-ellipsis-h:before{content:"\f141"}.la-ellipsis-v:before{content:"\f142"}.la-ello:before{content:"\f5f1"}.la-ember:before{content:"\f423"}.la-empire:before{content:"\f1d1"}.la-envelope:before{content:"\f0e0"}.la-envelope-open:before{content:"\f2b6"}.la-envelope-open-text:before{content:"\f658"}.la-envelope-square:before{content:"\f199"}.la-envira:before{content:"\f299"}.la-equals:before{content:"\f52c"}.la-eraser:before{content:"\f12d"}.la-erlang:before{content:"\f39d"}.la-ethereum:before{content:"\f42e"}.la-ethernet:before{content:"\f796"}.la-etsy:before{content:"\f2d7"}.la-euro-sign:before{content:"\f153"}.la-evernote:before{content:"\f839"}.la-exchange-alt:before{content:"\f362"}.la-exclamation:before{content:"\f12a"}.la-exclamation-circle:before{content:"\f06a"}.la-exclamation-triangle:before{content:"\f071"}.la-expand:before{content:"\f065"}.la-expand-arrows-alt:before{content:"\f31e"}.la-expeditedssl:before{content:"\f23e"}.la-external-link-alt:before{content:"\f35d"}.la-external-link-square-alt:before{content:"\f360"}.la-eye:before{content:"\f06e"}.la-eye-dropper:before{content:"\f1fb"}.la-eye-slash:before{content:"\f070"}.la-facebook:before{content:"\f09a"}.la-facebook-f:before{content:"\f39e"}.la-facebook-messenger:before{content:"\f39f"}.la-facebook-square:before{content:"\f082"}.la-fan:before{content:"\f863"}.la-fantasy-flight-games:before{content:"\f6dc"}.la-fast-backward:before{content:"\f049"}.la-fast-forward:before{content:"\f050"}.la-fax:before{content:"\f1ac"}.la-feather:before{content:"\f52d"}.la-feather-alt:before{content:"\f56b"}.la-fedex:before{content:"\f797"}.la-fedora:before{content:"\f798"}.la-female:before{content:"\f182"}.la-fighter-jet:before{content:"\f0fb"}.la-figma:before{content:"\f799"}.la-file:before{content:"\f15b"}.la-file-alt:before{content:"\f15c"}.la-file-archive:before{content:"\f1c6"}.la-file-audio:before{content:"\f1c7"}.la-file-code:before{content:"\f1c9"}.la-file-contract:before{content:"\f56c"}.la-file-csv:before{content:"\f6dd"}.la-file-download:before{content:"\f56d"}.la-file-excel:before{content:"\f1c3"}.la-file-export:before{content:"\f56e"}.la-file-image:before{content:"\f1c5"}.la-file-import:before{content:"\f56f"}.la-file-invoice:before{content:"\f570"}.la-file-invoice-dollar:before{content:"\f571"}.la-file-medical:before{content:"\f477"}.la-file-medical-alt:before{content:"\f478"}.la-file-pdf:before{content:"\f1c1"}.la-file-powerpoint:before{content:"\f1c4"}.la-file-prescription:before{content:"\f572"}.la-file-signature:before{content:"\f573"}.la-file-upload:before{content:"\f574"}.la-file-video:before{content:"\f1c8"}.la-file-word:before{content:"\f1c2"}.la-fill:before{content:"\f575"}.la-fill-drip:before{content:"\f576"}.la-film:before{content:"\f008"}.la-filter:before{content:"\f0b0"}.la-fingerprint:before{content:"\f577"}.la-fire:before{content:"\f06d"}.la-fire-alt:before{content:"\f7e4"}.la-fire-extinguisher:before{content:"\f134"}.la-firefox:before{content:"\f269"}.la-first-aid:before{content:"\f479"}.la-first-order:before{content:"\f2b0"}.la-first-order-alt:before{content:"\f50a"}.la-firstdraft:before{content:"\f3a1"}.la-fish:before{content:"\f578"}.la-fist-raised:before{content:"\f6de"}.la-flag:before{content:"\f024"}.la-flag-checkered:before{content:"\f11e"}.la-flag-usa:before{content:"\f74d"}.la-flask:before{content:"\f0c3"}.la-flickr:before{content:"\f16e"}.la-flipboard:before{content:"\f44d"}.la-flushed:before{content:"\f579"}.la-fly:before{content:"\f417"}.la-folder:before{content:"\f07b"}.la-folder-minus:before{content:"\f65d"}.la-folder-open:before{content:"\f07c"}.la-folder-plus:before{content:"\f65e"}.la-font:before{content:"\f031"}.la-font-awesome:before{content:"\f2b4"}.la-font-awesome-alt:before{content:"\f35c"}.la-font-awesome-flag:before{content:"\f425"}.la-font-awesome-logo-full:before{content:"\f4e6"}.la-fonticons:before{content:"\f280"}.la-fonticons-fi:before{content:"\f3a2"}.la-football-ball:before{content:"\f44e"}.la-fort-awesome:before{content:"\f286"}.la-fort-awesome-alt:before{content:"\f3a3"}.la-forumbee:before{content:"\f211"}.la-forward:before{content:"\f04e"}.la-foursquare:before{content:"\f180"}.la-free-code-camp:before{content:"\f2c5"}.la-freebsd:before{content:"\f3a4"}.la-frog:before{content:"\f52e"}.la-frown:before{content:"\f119"}.la-frown-open:before{content:"\f57a"}.la-fulcrum:before{content:"\f50b"}.la-funnel-dollar:before{content:"\f662"}.la-futbol:before{content:"\f1e3"}.la-galactic-republic:before{content:"\f50c"}.la-galactic-senate:before{content:"\f50d"}.la-gamepad:before{content:"\f11b"}.la-gas-pump:before{content:"\f52f"}.la-gavel:before{content:"\f0e3"}.la-gem:before{content:"\f3a5"}.la-genderless:before{content:"\f22d"}.la-get-pocket:before{content:"\f265"}.la-gg:before{content:"\f260"}.la-gg-circle:before{content:"\f261"}.la-ghost:before{content:"\f6e2"}.la-gift:before{content:"\f06b"}.la-gifts:before{content:"\f79c"}.la-git:before{content:"\f1d3"}.la-git-alt:before{content:"\f841"}.la-git-square:before{content:"\f1d2"}.la-github:before{content:"\f09b"}.la-github-alt:before{content:"\f113"}.la-github-square:before{content:"\f092"}.la-gitkraken:before{content:"\f3a6"}.la-gitlab:before{content:"\f296"}.la-gitter:before{content:"\f426"}.la-glass-cheers:before{content:"\f79f"}.la-glass-martini:before{content:"\f000"}.la-glass-martini-alt:before{content:"\f57b"}.la-glass-whiskey:before{content:"\f7a0"}.la-glasses:before{content:"\f530"}.la-glide:before{content:"\f2a5"}.la-glide-g:before{content:"\f2a6"}.la-globe:before{content:"\f0ac"}.la-globe-africa:before{content:"\f57c"}.la-globe-americas:before{content:"\f57d"}.la-globe-asia:before{content:"\f57e"}.la-globe-europe:before{content:"\f7a2"}.la-gofore:before{content:"\f3a7"}.la-golf-ball:before{content:"\f450"}.la-goodreads:before{content:"\f3a8"}.la-goodreads-g:before{content:"\f3a9"}.la-google:before{content:"\f1a0"}.la-google-drive:before{content:"\f3aa"}.la-google-play:before{content:"\f3ab"}.la-google-plus:before{content:"\f2b3"}.la-google-plus-g:before{content:"\f0d5"}.la-google-plus-square:before{content:"\f0d4"}.la-google-wallet:before{content:"\f1ee"}.la-gopuram:before{content:"\f664"}.la-graduation-cap:before{content:"\f19d"}.la-gratipay:before{content:"\f184"}.la-grav:before{content:"\f2d6"}.la-greater-than:before{content:"\f531"}.la-greater-than-equal:before{content:"\f532"}.la-grimace:before{content:"\f57f"}.la-grin:before{content:"\f580"}.la-grin-alt:before{content:"\f581"}.la-grin-beam:before{content:"\f582"}.la-grin-beam-sweat:before{content:"\f583"}.la-grin-hearts:before{content:"\f584"}.la-grin-squint:before{content:"\f585"}.la-grin-squint-tears:before{content:"\f586"}.la-grin-stars:before{content:"\f587"}.la-grin-tears:before{content:"\f588"}.la-grin-tongue:before{content:"\f589"}.la-grin-tongue-squint:before{content:"\f58a"}.la-grin-tongue-wink:before{content:"\f58b"}.la-grin-wink:before{content:"\f58c"}.la-grip-horizontal:before{content:"\f58d"}.la-grip-lines:before{content:"\f7a4"}.la-grip-lines-vertical:before{content:"\f7a5"}.la-grip-vertical:before{content:"\f58e"}.la-gripfire:before{content:"\f3ac"}.la-grunt:before{content:"\f3ad"}.la-guitar:before{content:"\f7a6"}.la-gulp:before{content:"\f3ae"}.la-h-square:before{content:"\f0fd"}.la-hacker-news:before{content:"\f1d4"}.la-hacker-news-square:before{content:"\f3af"}.la-hackerrank:before{content:"\f5f7"}.la-hamburger:before{content:"\f805"}.la-hammer:before{content:"\f6e3"}.la-hamsa:before{content:"\f665"}.la-hand-holding:before{content:"\f4bd"}.la-hand-holding-heart:before{content:"\f4be"}.la-hand-holding-usd:before{content:"\f4c0"}.la-hand-lizard:before{content:"\f258"}.la-hand-middle-finger:before{content:"\f806"}.la-hand-paper:before{content:"\f256"}.la-hand-peace:before{content:"\f25b"}.la-hand-point-down:before{content:"\f0a7"}.la-hand-point-left:before{content:"\f0a5"}.la-hand-point-right:before{content:"\f0a4"}.la-hand-point-up:before{content:"\f0a6"}.la-hand-pointer:before{content:"\f25a"}.la-hand-rock:before{content:"\f255"}.la-hand-scissors:before{content:"\f257"}.la-hand-spock:before{content:"\f259"}.la-hands:before{content:"\f4c2"}.la-hands-helping:before{content:"\f4c4"}.la-handshake:before{content:"\f2b5"}.la-hanukiah:before{content:"\f6e6"}.la-hard-hat:before{content:"\f807"}.la-hashtag:before{content:"\f292"}.la-hat-cowboy:before{content:"\f8c0"}.la-hat-cowboy-side:before{content:"\f8c1"}.la-hat-wizard:before{content:"\f6e8"}.la-haykal:before{content:"\f666"}.la-hdd:before{content:"\f0a0"}.la-heading:before{content:"\f1dc"}.la-headphones:before{content:"\f025"}.la-headphones-alt:before{content:"\f58f"}.la-headset:before{content:"\f590"}.la-heart:before{content:"\f004"}.la-heart-broken:before{content:"\f7a9"}.la-heartbeat:before{content:"\f21e"}.la-helicopter:before{content:"\f533"}.la-highlighter:before{content:"\f591"}.la-hiking:before{content:"\f6ec"}.la-hippo:before{content:"\f6ed"}.la-hips:before{content:"\f452"}.la-hire-a-helper:before{content:"\f3b0"}.la-history:before{content:"\f1da"}.la-hockey-puck:before{content:"\f453"}.la-holly-berry:before{content:"\f7aa"}.la-home:before{content:"\f015"}.la-hooli:before{content:"\f427"}.la-hornbill:before{content:"\f592"}.la-horse:before{content:"\f6f0"}.la-horse-head:before{content:"\f7ab"}.la-hospital:before{content:"\f0f8"}.la-hospital-alt:before{content:"\f47d"}.la-hospital-symbol:before{content:"\f47e"}.la-hot-tub:before{content:"\f593"}.la-hotdog:before{content:"\f80f"}.la-hotel:before{content:"\f594"}.la-hotjar:before{content:"\f3b1"}.la-hourglass:before{content:"\f254"}.la-hourglass-end:before{content:"\f253"}.la-hourglass-half:before{content:"\f252"}.la-hourglass-start:before{content:"\f251"}.la-house-damage:before{content:"\f6f1"}.la-houzz:before{content:"\f27c"}.la-hryvnia:before{content:"\f6f2"}.la-html5:before{content:"\f13b"}.la-hubspot:before{content:"\f3b2"}.la-i-cursor:before{content:"\f246"}.la-ice-cream:before{content:"\f810"}.la-icicles:before{content:"\f7ad"}.la-icons:before{content:"\f86d"}.la-id-badge:before{content:"\f2c1"}.la-id-card:before{content:"\f2c2"}.la-id-card-alt:before{content:"\f47f"}.la-igloo:before{content:"\f7ae"}.la-image:before{content:"\f03e"}.la-images:before{content:"\f302"}.la-imdb:before{content:"\f2d8"}.la-inbox:before{content:"\f01c"}.la-indent:before{content:"\f03c"}.la-industry:before{content:"\f275"}.la-infinity:before{content:"\f534"}.la-info:before{content:"\f129"}.la-info-circle:before{content:"\f05a"}.la-instagram:before{content:"\f16d"}.la-intercom:before{content:"\f7af"}.la-internet-explorer:before{content:"\f26b"}.la-invision:before{content:"\f7b0"}.la-ioxhost:before{content:"\f208"}.la-italic:before{content:"\f033"}.la-itch-io:before{content:"\f83a"}.la-itunes:before{content:"\f3b4"}.la-itunes-note:before{content:"\f3b5"}.la-java:before{content:"\f4e4"}.la-jedi:before{content:"\f669"}.la-jedi-order:before{content:"\f50e"}.la-jenkins:before{content:"\f3b6"}.la-jira:before{content:"\f7b1"}.la-joget:before{content:"\f3b7"}.la-joint:before{content:"\f595"}.la-joomla:before{content:"\f1aa"}.la-journal-whills:before{content:"\f66a"}.la-js:before{content:"\f3b8"}.la-js-square:before{content:"\f3b9"}.la-jsfiddle:before{content:"\f1cc"}.la-kaaba:before{content:"\f66b"}.la-kaggle:before{content:"\f5fa"}.la-key:before{content:"\f084"}.la-keybase:before{content:"\f4f5"}.la-keyboard:before{content:"\f11c"}.la-keycdn:before{content:"\f3ba"}.la-khanda:before{content:"\f66d"}.la-kickstarter:before{content:"\f3bb"}.la-kickstarter-k:before{content:"\f3bc"}.la-kiss:before{content:"\f596"}.la-kiss-beam:before{content:"\f597"}.la-kiss-wink-heart:before{content:"\f598"}.la-kiwi-bird:before{content:"\f535"}.la-korvue:before{content:"\f42f"}.la-landmark:before{content:"\f66f"}.la-language:before{content:"\f1ab"}.la-laptop:before{content:"\f109"}.la-laptop-code:before{content:"\f5fc"}.la-laptop-medical:before{content:"\f812"}.la-laravel:before{content:"\f3bd"}.la-lastfm:before{content:"\f202"}.la-lastfm-square:before{content:"\f203"}.la-laugh:before{content:"\f599"}.la-laugh-beam:before{content:"\f59a"}.la-laugh-squint:before{content:"\f59b"}.la-laugh-wink:before{content:"\f59c"}.la-layer-group:before{content:"\f5fd"}.la-leaf:before{content:"\f06c"}.la-leanpub:before{content:"\f212"}.la-lemon:before{content:"\f094"}.la-less:before{content:"\f41d"}.la-less-than:before{content:"\f536"}.la-less-than-equal:before{content:"\f537"}.la-level-down-alt:before{content:"\f3be"}.la-level-up-alt:before{content:"\f3bf"}.la-life-ring:before{content:"\f1cd"}.la-lightbulb:before{content:"\f0eb"}.la-line:before{content:"\f3c0"}.la-link:before{content:"\f0c1"}.la-linkedin:before{content:"\f08c"}.la-linkedin-in:before{content:"\f0e1"}.la-linode:before{content:"\f2b8"}.la-linux:before{content:"\f17c"}.la-lira-sign:before{content:"\f195"}.la-list:before{content:"\f03a"}.la-list-alt:before{content:"\f022"}.la-list-ol:before{content:"\f0cb"}.la-list-ul:before{content:"\f0ca"}.la-location-arrow:before{content:"\f124"}.la-lock:before{content:"\f023"}.la-lock-open:before{content:"\f3c1"}.la-long-arrow-alt-down:before{content:"\f309"}.la-long-arrow-alt-left:before{content:"\f30a"}.la-long-arrow-alt-right:before{content:"\f30b"}.la-long-arrow-alt-up:before{content:"\f30c"}.la-low-vision:before{content:"\f2a8"}.la-luggage-cart:before{content:"\f59d"}.la-lyft:before{content:"\f3c3"}.la-magento:before{content:"\f3c4"}.la-magic:before{content:"\f0d0"}.la-magnet:before{content:"\f076"}.la-mail-bulk:before{content:"\f674"}.la-mailchimp:before{content:"\f59e"}.la-male:before{content:"\f183"}.la-mandalorian:before{content:"\f50f"}.la-map:before{content:"\f279"}.la-map-marked:before{content:"\f59f"}.la-map-marked-alt:before{content:"\f5a0"}.la-map-marker:before{content:"\f041"}.la-map-marker-alt:before{content:"\f3c5"}.la-map-pin:before{content:"\f276"}.la-map-signs:before{content:"\f277"}.la-markdown:before{content:"\f60f"}.la-marker:before{content:"\f5a1"}.la-mars:before{content:"\f222"}.la-mars-double:before{content:"\f227"}.la-mars-stroke:before{content:"\f229"}.la-mars-stroke-h:before{content:"\f22b"}.la-mars-stroke-v:before{content:"\f22a"}.la-mask:before{content:"\f6fa"}.la-mastodon:before{content:"\f4f6"}.la-maxcdn:before{content:"\f136"}.la-mdb:before{content:"\f8ca"}.la-medal:before{content:"\f5a2"}.la-medapps:before{content:"\f3c6"}.la-medium:before{content:"\f23a"}.la-medium-m:before{content:"\f3c7"}.la-medkit:before{content:"\f0fa"}.la-medrt:before{content:"\f3c8"}.la-meetup:before{content:"\f2e0"}.la-megaport:before{content:"\f5a3"}.la-meh:before{content:"\f11a"}.la-meh-blank:before{content:"\f5a4"}.la-meh-rolling-eyes:before{content:"\f5a5"}.la-memory:before{content:"\f538"}.la-mendeley:before{content:"\f7b3"}.la-menorah:before{content:"\f676"}.la-mercury:before{content:"\f223"}.la-meteor:before{content:"\f753"}.la-microchip:before{content:"\f2db"}.la-microphone:before{content:"\f130"}.la-microphone-alt:before{content:"\f3c9"}.la-microphone-alt-slash:before{content:"\f539"}.la-microphone-slash:before{content:"\f131"}.la-microscope:before{content:"\f610"}.la-microsoft:before{content:"\f3ca"}.la-minus:before{content:"\f068"}.la-minus-circle:before{content:"\f056"}.la-minus-square:before{content:"\f146"}.la-mitten:before{content:"\f7b5"}.la-mix:before{content:"\f3cb"}.la-mixcloud:before{content:"\f289"}.la-mizuni:before{content:"\f3cc"}.la-mobile:before{content:"\f10b"}.la-mobile-alt:before{content:"\f3cd"}.la-modx:before{content:"\f285"}.la-monero:before{content:"\f3d0"}.la-money-bill:before{content:"\f0d6"}.la-money-bill-alt:before{content:"\f3d1"}.la-money-bill-wave:before{content:"\f53a"}.la-money-bill-wave-alt:before{content:"\f53b"}.la-money-check:before{content:"\f53c"}.la-money-check-alt:before{content:"\f53d"}.la-monument:before{content:"\f5a6"}.la-moon:before{content:"\f186"}.la-mortar-pestle:before{content:"\f5a7"}.la-mosque:before{content:"\f678"}.la-motorcycle:before{content:"\f21c"}.la-mountain:before{content:"\f6fc"}.la-mouse:before{content:"\f8cc"}.la-mouse-pointer:before{content:"\f245"}.la-mug-hot:before{content:"\f7b6"}.la-music:before{content:"\f001"}.la-napster:before{content:"\f3d2"}.la-neos:before{content:"\f612"}.la-network-wired:before{content:"\f6ff"}.la-neuter:before{content:"\f22c"}.la-newspaper:before{content:"\f1ea"}.la-nimblr:before{content:"\f5a8"}.la-node:before{content:"\f419"}.la-node-js:before{content:"\f3d3"}.la-not-equal:before{content:"\f53e"}.la-notes-medical:before{content:"\f481"}.la-npm:before{content:"\f3d4"}.la-ns8:before{content:"\f3d5"}.la-nutritionix:before{content:"\f3d6"}.la-object-group:before{content:"\f247"}.la-object-ungroup:before{content:"\f248"}.la-odnoklassniki:before{content:"\f263"}.la-odnoklassniki-square:before{content:"\f264"}.la-oil-can:before{content:"\f613"}.la-old-republic:before{content:"\f510"}.la-om:before{content:"\f679"}.la-opencart:before{content:"\f23d"}.la-openid:before{content:"\f19b"}.la-opera:before{content:"\f26a"}.la-optin-monster:before{content:"\f23c"}.la-orcid:before{content:"\f8d2"}.la-osi:before{content:"\f41a"}.la-otter:before{content:"\f700"}.la-outdent:before{content:"\f03b"}.la-page4:before{content:"\f3d7"}.la-pagelines:before{content:"\f18c"}.la-pager:before{content:"\f815"}.la-paint-brush:before{content:"\f1fc"}.la-paint-roller:before{content:"\f5aa"}.la-palette:before{content:"\f53f"}.la-palfed:before{content:"\f3d8"}.la-pallet:before{content:"\f482"}.la-paper-plane:before{content:"\f1d8"}.la-paperclip:before{content:"\f0c6"}.la-parachute-box:before{content:"\f4cd"}.la-paragraph:before{content:"\f1dd"}.la-parking:before{content:"\f540"}.la-passport:before{content:"\f5ab"}.la-pastafarianism:before{content:"\f67b"}.la-paste:before{content:"\f0ea"}.la-patreon:before{content:"\f3d9"}.la-pause:before{content:"\f04c"}.la-pause-circle:before{content:"\f28b"}.la-paw:before{content:"\f1b0"}.la-paypal:before{content:"\f1ed"}.la-peace:before{content:"\f67c"}.la-pen:before{content:"\f304"}.la-pen-alt:before{content:"\f305"}.la-pen-fancy:before{content:"\f5ac"}.la-pen-nib:before{content:"\f5ad"}.la-pen-square:before{content:"\f14b"}.la-pencil-alt:before{content:"\f303"}.la-pencil-ruler:before{content:"\f5ae"}.la-penny-arcade:before{content:"\f704"}.la-people-carry:before{content:"\f4ce"}.la-pepper-hot:before{content:"\f816"}.la-percent:before{content:"\f295"}.la-percentage:before{content:"\f541"}.la-periscope:before{content:"\f3da"}.la-person-booth:before{content:"\f756"}.la-phabricator:before{content:"\f3db"}.la-phoenix-framework:before{content:"\f3dc"}.la-phoenix-squadron:before{content:"\f511"}.la-phone:before{content:"\f095"}.la-phone-alt:before{content:"\f879"}.la-phone-slash:before{content:"\f3dd"}.la-phone-square:before{content:"\f098"}.la-phone-square-alt:before{content:"\f87b"}.la-phone-volume:before{content:"\f2a0"}.la-photo-video:before{content:"\f87c"}.la-php:before{content:"\f457"}.la-pied-piper:before{content:"\f2ae"}.la-pied-piper-alt:before{content:"\f1a8"}.la-pied-piper-hat:before{content:"\f4e5"}.la-pied-piper-pp:before{content:"\f1a7"}.la-piggy-bank:before{content:"\f4d3"}.la-pills:before{content:"\f484"}.la-pinterest:before{content:"\f0d2"}.la-pinterest-p:before{content:"\f231"}.la-pinterest-square:before{content:"\f0d3"}.la-pizza-slice:before{content:"\f818"}.la-place-of-worship:before{content:"\f67f"}.la-plane:before{content:"\f072"}.la-plane-arrival:before{content:"\f5af"}.la-plane-departure:before{content:"\f5b0"}.la-play:before{content:"\f04b"}.la-play-circle:before{content:"\f144"}.la-playstation:before{content:"\f3df"}.la-plug:before{content:"\f1e6"}.la-plus:before{content:"\f067"}.la-plus-circle:before{content:"\f055"}.la-plus-square:before{content:"\f0fe"}.la-podcast:before{content:"\f2ce"}.la-poll:before{content:"\f681"}.la-poll-h:before{content:"\f682"}.la-poo:before{content:"\f2fe"}.la-poo-storm:before{content:"\f75a"}.la-poop:before{content:"\f619"}.la-portrait:before{content:"\f3e0"}.la-pound-sign:before{content:"\f154"}.la-power-off:before{content:"\f011"}.la-pray:before{content:"\f683"}.la-praying-hands:before{content:"\f684"}.la-prescription:before{content:"\f5b1"}.la-prescription-bottle:before{content:"\f485"}.la-prescription-bottle-alt:before{content:"\f486"}.la-print:before{content:"\f02f"}.la-procedures:before{content:"\f487"}.la-product-hunt:before{content:"\f288"}.la-project-diagram:before{content:"\f542"}.la-pushed:before{content:"\f3e1"}.la-puzzle-piece:before{content:"\f12e"}.la-python:before{content:"\f3e2"}.la-qq:before{content:"\f1d6"}.la-qrcode:before{content:"\f029"}.la-question:before{content:"\f128"}.la-question-circle:before{content:"\f059"}.la-quidditch:before{content:"\f458"}.la-quinscape:before{content:"\f459"}.la-quora:before{content:"\f2c4"}.la-quote-left:before{content:"\f10d"}.la-quote-right:before{content:"\f10e"}.la-quran:before{content:"\f687"}.la-r-project:before{content:"\f4f7"}.la-radiation:before{content:"\f7b9"}.la-radiation-alt:before{content:"\f7ba"}.la-rainbow:before{content:"\f75b"}.la-random:before{content:"\f074"}.la-raspberry-pi:before{content:"\f7bb"}.la-ravelry:before{content:"\f2d9"}.la-react:before{content:"\f41b"}.la-reacteurope:before{content:"\f75d"}.la-readme:before{content:"\f4d5"}.la-rebel:before{content:"\f1d0"}.la-receipt:before{content:"\f543"}.la-record-vinyl:before{content:"\f8d9"}.la-recycle:before{content:"\f1b8"}.la-red-river:before{content:"\f3e3"}.la-reddit:before{content:"\f1a1"}.la-reddit-alien:before{content:"\f281"}.la-reddit-square:before{content:"\f1a2"}.la-redhat:before{content:"\f7bc"}.la-redo:before{content:"\f01e"}.la-redo-alt:before{content:"\f2f9"}.la-registered:before{content:"\f25d"}.la-remove-format:before{content:"\f87d"}.la-renren:before{content:"\f18b"}.la-reply:before{content:"\f3e5"}.la-reply-all:before{content:"\f122"}.la-replyd:before{content:"\f3e6"}.la-republican:before{content:"\f75e"}.la-researchgate:before{content:"\f4f8"}.la-resolving:before{content:"\f3e7"}.la-restroom:before{content:"\f7bd"}.la-retweet:before{content:"\f079"}.la-rev:before{content:"\f5b2"}.la-ribbon:before{content:"\f4d6"}.la-ring:before{content:"\f70b"}.la-road:before{content:"\f018"}.la-robot:before{content:"\f544"}.la-rocket:before{content:"\f135"}.la-rocketchat:before{content:"\f3e8"}.la-rockrms:before{content:"\f3e9"}.la-route:before{content:"\f4d7"}.la-rss:before{content:"\f09e"}.la-rss-square:before{content:"\f143"}.la-ruble-sign:before{content:"\f158"}.la-ruler:before{content:"\f545"}.la-ruler-combined:before{content:"\f546"}.la-ruler-horizontal:before{content:"\f547"}.la-ruler-vertical:before{content:"\f548"}.la-running:before{content:"\f70c"}.la-rupee-sign:before{content:"\f156"}.la-sad-cry:before{content:"\f5b3"}.la-sad-tear:before{content:"\f5b4"}.la-safari:before{content:"\f267"}.la-salesforce:before{content:"\f83b"}.la-sass:before{content:"\f41e"}.la-satellite:before{content:"\f7bf"}.la-satellite-dish:before{content:"\f7c0"}.la-save:before{content:"\f0c7"}.la-schlix:before{content:"\f3ea"}.la-school:before{content:"\f549"}.la-screwdriver:before{content:"\f54a"}.la-scribd:before{content:"\f28a"}.la-scroll:before{content:"\f70e"}.la-sd-card:before{content:"\f7c2"}.la-search:before{content:"\f002"}.la-search-dollar:before{content:"\f688"}.la-search-location:before{content:"\f689"}.la-search-minus:before{content:"\f010"}.la-search-plus:before{content:"\f00e"}.la-searchengin:before{content:"\f3eb"}.la-seedling:before{content:"\f4d8"}.la-sellcast:before{content:"\f2da"}.la-sellsy:before{content:"\f213"}.la-server:before{content:"\f233"}.la-servicestack:before{content:"\f3ec"}.la-shapes:before{content:"\f61f"}.la-share:before{content:"\f064"}.la-share-alt:before{content:"\f1e0"}.la-share-alt-square:before{content:"\f1e1"}.la-share-square:before{content:"\f14d"}.la-shekel-sign:before{content:"\f20b"}.la-shield-alt:before{content:"\f3ed"}.la-ship:before{content:"\f21a"}.la-shipping-fast:before{content:"\f48b"}.la-shirtsinbulk:before{content:"\f214"}.la-shoe-prints:before{content:"\f54b"}.la-shopping-bag:before{content:"\f290"}.la-shopping-basket:before{content:"\f291"}.la-shopping-cart:before{content:"\f07a"}.la-shopware:before{content:"\f5b5"}.la-shower:before{content:"\f2cc"}.la-shuttle-van:before{content:"\f5b6"}.la-sign:before{content:"\f4d9"}.la-sign-in-alt:before{content:"\f2f6"}.la-sign-language:before{content:"\f2a7"}.la-sign-out-alt:before{content:"\f2f5"}.la-signal:before{content:"\f012"}.la-signature:before{content:"\f5b7"}.la-sim-card:before{content:"\f7c4"}.la-simplybuilt:before{content:"\f215"}.la-sistrix:before{content:"\f3ee"}.la-sitemap:before{content:"\f0e8"}.la-sith:before{content:"\f512"}.la-skating:before{content:"\f7c5"}.la-sketch:before{content:"\f7c6"}.la-skiing:before{content:"\f7c9"}.la-skiing-nordic:before{content:"\f7ca"}.la-skull:before{content:"\f54c"}.la-skull-crossbones:before{content:"\f714"}.la-skyatlas:before{content:"\f216"}.la-skype:before{content:"\f17e"}.la-slack:before{content:"\f198"}.la-slack-hash:before{content:"\f3ef"}.la-slash:before{content:"\f715"}.la-sleigh:before{content:"\f7cc"}.la-sliders-h:before{content:"\f1de"}.la-slideshare:before{content:"\f1e7"}.la-smile:before{content:"\f118"}.la-smile-beam:before{content:"\f5b8"}.la-smile-wink:before{content:"\f4da"}.la-smog:before{content:"\f75f"}.la-smoking:before{content:"\f48d"}.la-smoking-ban:before{content:"\f54d"}.la-sms:before{content:"\f7cd"}.la-snapchat:before{content:"\f2ab"}.la-snapchat-ghost:before{content:"\f2ac"}.la-snapchat-square:before{content:"\f2ad"}.la-snowboarding:before{content:"\f7ce"}.la-snowflake:before{content:"\f2dc"}.la-snowman:before{content:"\f7d0"}.la-snowplow:before{content:"\f7d2"}.la-socks:before{content:"\f696"}.la-solar-panel:before{content:"\f5ba"}.la-sort:before{content:"\f0dc"}.la-sort-alpha-down:before{content:"\f15d"}.la-sort-alpha-down-alt:before{content:"\f881"}.la-sort-alpha-up:before{content:"\f15e"}.la-sort-alpha-up-alt:before{content:"\f882"}.la-sort-amount-down:before{content:"\f160"}.la-sort-amount-down-alt:before{content:"\f884"}.la-sort-amount-up:before{content:"\f161"}.la-sort-amount-up-alt:before{content:"\f885"}.la-sort-down:before{content:"\f0dd"}.la-sort-numeric-down:before{content:"\f162"}.la-sort-numeric-down-alt:before{content:"\f886"}.la-sort-numeric-up:before{content:"\f163"}.la-sort-numeric-up-alt:before{content:"\f887"}.la-sort-up:before{content:"\f0de"}.la-soundcloud:before{content:"\f1be"}.la-sourcetree:before{content:"\f7d3"}.la-spa:before{content:"\f5bb"}.la-space-shuttle:before{content:"\f197"}.la-speakap:before{content:"\f3f3"}.la-speaker-deck:before{content:"\f83c"}.la-spell-check:before{content:"\f891"}.la-spider:before{content:"\f717"}.la-spinner:before{content:"\f110"}.la-splotch:before{content:"\f5bc"}.la-spotify:before{content:"\f1bc"}.la-spray-can:before{content:"\f5bd"}.la-square:before{content:"\f0c8"}.la-square-full:before{content:"\f45c"}.la-square-root-alt:before{content:"\f698"}.la-squarespace:before{content:"\f5be"}.la-stack-exchange:before{content:"\f18d"}.la-stack-overflow:before{content:"\f16c"}.la-stackpath:before{content:"\f842"}.la-stamp:before{content:"\f5bf"}.la-star:before{content:"\f005"}.la-star-and-crescent:before{content:"\f699"}.la-star-half:before{content:"\f089"}.la-star-half-alt:before{content:"\f5c0"}.la-star-of-david:before{content:"\f69a"}.la-star-of-life:before{content:"\f621"}.la-staylinked:before{content:"\f3f5"}.la-steam:before{content:"\f1b6"}.la-steam-square:before{content:"\f1b7"}.la-steam-symbol:before{content:"\f3f6"}.la-step-backward:before{content:"\f048"}.la-step-forward:before{content:"\f051"}.la-stethoscope:before{content:"\f0f1"}.la-sticker-mule:before{content:"\f3f7"}.la-sticky-note:before{content:"\f249"}.la-stop:before{content:"\f04d"}.la-stop-circle:before{content:"\f28d"}.la-stopwatch:before{content:"\f2f2"}.la-store:before{content:"\f54e"}.la-store-alt:before{content:"\f54f"}.la-strava:before{content:"\f428"}.la-stream:before{content:"\f550"}.la-street-view:before{content:"\f21d"}.la-strikethrough:before{content:"\f0cc"}.la-stripe:before{content:"\f429"}.la-stripe-s:before{content:"\f42a"}.la-stroopwafel:before{content:"\f551"}.la-studiovinari:before{content:"\f3f8"}.la-stumbleupon:before{content:"\f1a4"}.la-stumbleupon-circle:before{content:"\f1a3"}.la-subscript:before{content:"\f12c"}.la-subway:before{content:"\f239"}.la-suitcase:before{content:"\f0f2"}.la-suitcase-rolling:before{content:"\f5c1"}.la-sun:before{content:"\f185"}.la-superpowers:before{content:"\f2dd"}.la-superscript:before{content:"\f12b"}.la-supple:before{content:"\f3f9"}.la-surprise:before{content:"\f5c2"}.la-suse:before{content:"\f7d6"}.la-swatchbook:before{content:"\f5c3"}.la-swift:before{content:"\f8e1"}.la-swimmer:before{content:"\f5c4"}.la-swimming-pool:before{content:"\f5c5"}.la-symfony:before{content:"\f83d"}.la-synagogue:before{content:"\f69b"}.la-sync:before{content:"\f021"}.la-sync-alt:before{content:"\f2f1"}.la-syringe:before{content:"\f48e"}.la-table:before{content:"\f0ce"}.la-table-tennis:before{content:"\f45d"}.la-tablet:before{content:"\f10a"}.la-tablet-alt:before{content:"\f3fa"}.la-tablets:before{content:"\f490"}.la-tachometer-alt:before{content:"\f3fd"}.la-tag:before{content:"\f02b"}.la-tags:before{content:"\f02c"}.la-tape:before{content:"\f4db"}.la-tasks:before{content:"\f0ae"}.la-taxi:before{content:"\f1ba"}.la-teamspeak:before{content:"\f4f9"}.la-teeth:before{content:"\f62e"}.la-teeth-open:before{content:"\f62f"}.la-telegram:before{content:"\f2c6"}.la-telegram-plane:before{content:"\f3fe"}.la-temperature-high:before{content:"\f769"}.la-temperature-low:before{content:"\f76b"}.la-tencent-weibo:before{content:"\f1d5"}.la-tenge:before{content:"\f7d7"}.la-terminal:before{content:"\f120"}.la-text-height:before{content:"\f034"}.la-text-width:before{content:"\f035"}.la-th:before{content:"\f00a"}.la-th-large:before{content:"\f009"}.la-th-list:before{content:"\f00b"}.la-the-red-yeti:before{content:"\f69d"}.la-theater-masks:before{content:"\f630"}.la-themeco:before{content:"\f5c6"}.la-themeisle:before{content:"\f2b2"}.la-thermometer:before{content:"\f491"}.la-thermometer-empty:before{content:"\f2cb"}.la-thermometer-full:before{content:"\f2c7"}.la-thermometer-half:before{content:"\f2c9"}.la-thermometer-quarter:before{content:"\f2ca"}.la-thermometer-three-quarters:before{content:"\f2c8"}.la-think-peaks:before{content:"\f731"}.la-thumbs-down:before{content:"\f165"}.la-thumbs-up:before{content:"\f164"}.la-thumbtack:before{content:"\f08d"}.la-ticket-alt:before{content:"\f3ff"}.la-times:before{content:"\f00d"}.la-times-circle:before{content:"\f057"}.la-tint:before{content:"\f043"}.la-tint-slash:before{content:"\f5c7"}.la-tired:before{content:"\f5c8"}.la-toggle-off:before{content:"\f204"}.la-toggle-on:before{content:"\f205"}.la-toilet:before{content:"\f7d8"}.la-toilet-paper:before{content:"\f71e"}.la-toolbox:before{content:"\f552"}.la-tools:before{content:"\f7d9"}.la-tooth:before{content:"\f5c9"}.la-torah:before{content:"\f6a0"}.la-torii-gate:before{content:"\f6a1"}.la-tractor:before{content:"\f722"}.la-trade-federation:before{content:"\f513"}.la-trademark:before{content:"\f25c"}.la-traffic-light:before{content:"\f637"}.la-train:before{content:"\f238"}.la-tram:before{content:"\f7da"}.la-transgender:before{content:"\f224"}.la-transgender-alt:before{content:"\f225"}.la-trash:before{content:"\f1f8"}.la-trash-alt:before{content:"\f2ed"}.la-trash-restore:before{content:"\f829"}.la-trash-restore-alt:before{content:"\f82a"}.la-tree:before{content:"\f1bb"}.la-trello:before{content:"\f181"}.la-tripadvisor:before{content:"\f262"}.la-trophy:before{content:"\f091"}.la-truck:before{content:"\f0d1"}.la-truck-loading:before{content:"\f4de"}.la-truck-monster:before{content:"\f63b"}.la-truck-moving:before{content:"\f4df"}.la-truck-pickup:before{content:"\f63c"}.la-tshirt:before{content:"\f553"}.la-tty:before{content:"\f1e4"}.la-tumblr:before{content:"\f173"}.la-tumblr-square:before{content:"\f174"}.la-tv:before{content:"\f26c"}.la-twitch:before{content:"\f1e8"}.la-twitter:before{content:"\f099"}.la-twitter-square:before{content:"\f081"}.la-typo3:before{content:"\f42b"}.la-uber:before{content:"\f402"}.la-ubuntu:before{content:"\f7df"}.la-uikit:before{content:"\f403"}.la-umbraco:before{content:"\f8e8"}.la-umbrella:before{content:"\f0e9"}.la-umbrella-beach:before{content:"\f5ca"}.la-underline:before{content:"\f0cd"}.la-undo:before{content:"\f0e2"}.la-undo-alt:before{content:"\f2ea"}.la-uniregistry:before{content:"\f404"}.la-universal-access:before{content:"\f29a"}.la-university:before{content:"\f19c"}.la-unlink:before{content:"\f127"}.la-unlock:before{content:"\f09c"}.la-unlock-alt:before{content:"\f13e"}.la-untappd:before{content:"\f405"}.la-upload:before{content:"\f093"}.la-ups:before{content:"\f7e0"}.la-usb:before{content:"\f287"}.la-user:before{content:"\f007"}.la-user-alt:before{content:"\f406"}.la-user-alt-slash:before{content:"\f4fa"}.la-user-astronaut:before{content:"\f4fb"}.la-user-check:before{content:"\f4fc"}.la-user-circle:before{content:"\f2bd"}.la-user-clock:before{content:"\f4fd"}.la-user-cog:before{content:"\f4fe"}.la-user-edit:before{content:"\f4ff"}.la-user-friends:before{content:"\f500"}.la-user-graduate:before{content:"\f501"}.la-user-injured:before{content:"\f728"}.la-user-lock:before{content:"\f502"}.la-user-md:before{content:"\f0f0"}.la-user-minus:before{content:"\f503"}.la-user-ninja:before{content:"\f504"}.la-user-nurse:before{content:"\f82f"}.la-user-plus:before{content:"\f234"}.la-user-secret:before{content:"\f21b"}.la-user-shield:before{content:"\f505"}.la-user-slash:before{content:"\f506"}.la-user-tag:before{content:"\f507"}.la-user-tie:before{content:"\f508"}.la-user-times:before{content:"\f235"}.la-users:before{content:"\f0c0"}.la-users-cog:before{content:"\f509"}.la-usps:before{content:"\f7e1"}.la-ussunnah:before{content:"\f407"}.la-utensil-spoon:before{content:"\f2e5"}.la-utensils:before{content:"\f2e7"}.la-vaadin:before{content:"\f408"}.la-vector-square:before{content:"\f5cb"}.la-venus:before{content:"\f221"}.la-venus-double:before{content:"\f226"}.la-venus-mars:before{content:"\f228"}.la-viacoin:before{content:"\f237"}.la-viadeo:before{content:"\f2a9"}.la-viadeo-square:before{content:"\f2aa"}.la-vial:before{content:"\f492"}.la-vials:before{content:"\f493"}.la-viber:before{content:"\f409"}.la-video:before{content:"\f03d"}.la-video-slash:before{content:"\f4e2"}.la-vihara:before{content:"\f6a7"}.la-vimeo:before{content:"\f40a"}.la-vimeo-square:before{content:"\f194"}.la-vimeo-v:before{content:"\f27d"}.la-vine:before{content:"\f1ca"}.la-vk:before{content:"\f189"}.la-vnv:before{content:"\f40b"}.la-voicemail:before{content:"\f897"}.la-volleyball-ball:before{content:"\f45f"}.la-volume-down:before{content:"\f027"}.la-volume-mute:before{content:"\f6a9"}.la-volume-off:before{content:"\f026"}.la-volume-up:before{content:"\f028"}.la-vote-yea:before{content:"\f772"}.la-vr-cardboard:before{content:"\f729"}.la-vuejs:before{content:"\f41f"}.la-walking:before{content:"\f554"}.la-wallet:before{content:"\f555"}.la-warehouse:before{content:"\f494"}.la-water:before{content:"\f773"}.la-wave-square:before{content:"\f83e"}.la-waze:before{content:"\f83f"}.la-weebly:before{content:"\f5cc"}.la-weibo:before{content:"\f18a"}.la-weight:before{content:"\f496"}.la-weight-hanging:before{content:"\f5cd"}.la-weixin:before{content:"\f1d7"}.la-whatsapp:before{content:"\f232"}.la-whatsapp-square:before{content:"\f40c"}.la-wheelchair:before{content:"\f193"}.la-whmcs:before{content:"\f40d"}.la-wifi:before{content:"\f1eb"}.la-wikipedia-w:before{content:"\f266"}.la-wind:before{content:"\f72e"}.la-window-close:before{content:"\f410"}.la-window-maximize:before{content:"\f2d0"}.la-window-minimize:before{content:"\f2d1"}.la-window-restore:before{content:"\f2d2"}.la-windows:before{content:"\f17a"}.la-wine-bottle:before{content:"\f72f"}.la-wine-glass:before{content:"\f4e3"}.la-wine-glass-alt:before{content:"\f5ce"}.la-wix:before{content:"\f5cf"}.la-wizards-of-the-coast:before{content:"\f730"}.la-wolf-pack-battalion:before{content:"\f514"}.la-won-sign:before{content:"\f159"}.la-wordpress:before{content:"\f19a"}.la-wordpress-simple:before{content:"\f411"}.la-wpbeginner:before{content:"\f297"}.la-wpexplorer:before{content:"\f2de"}.la-wpforms:before{content:"\f298"}.la-wpressr:before{content:"\f3e4"}.la-wrench:before{content:"\f0ad"}.la-x-ray:before{content:"\f497"}.la-xbox:before{content:"\f412"}.la-xing:before{content:"\f168"}.la-xing-square:before{content:"\f169"}.la-y-combinator:before{content:"\f23b"}.la-yahoo:before{content:"\f19e"}.la-yammer:before{content:"\f840"}.la-yandex:before{content:"\f413"}.la-yandex-international:before{content:"\f414"}.la-yarn:before{content:"\f7e3"}.la-yelp:before{content:"\f1e9"}.la-yen-sign:before{content:"\f157"}.la-yin-yang:before{content:"\f6ad"}.la-yoast:before{content:"\f2b1"}.la-youtube:before{content:"\f167"}.la-youtube-square:before{content:"\f431"}.la-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:'Line Awesome Brands';font-style:normal;font-weight:400;font-display:auto;src:url(../fonts/la-brands-400.eot);src:url(../fonts/la-brands-400.eot?#iefix) format("embedded-opentype"),url(../fonts/la-brands-400.woff2) format("woff2"),url(../fonts/la-brands-400.woff) format("woff"),url(../fonts/la-brands-400.ttf) format("truetype"),url(../fonts/la-brands-400.svg#lineawesome) format("svg")}.lab{font-family:'Line Awesome Brands'}@font-face{font-family:'Line Awesome Free';font-style:normal;font-weight:400;font-display:auto;src:url(../fonts/la-regular-400.eot);src:url(../fonts/la-regular-400.eot?#iefix) format("embedded-opentype"),url(../fonts/la-regular-400.woff2) format("woff2"),url(../fonts/la-regular-400.woff) format("woff"),url(../fonts/la-regular-400.ttf) format("truetype"),url(../fonts/la-regular-400.svg#lineawesome) format("svg")}.lar{font-family:'Line Awesome Free';font-weight:400}@font-face{font-family:'Line Awesome Free';font-style:normal;font-weight:900;font-display:auto;src:url(../fonts/la-solid-900.eot);src:url(../fonts/la-solid-900.eot?#iefix) format("embedded-opentype"),url(../fonts/la-solid-900.woff2) format("woff2"),url(../fonts/la-solid-900.woff) format("woff"),url(../fonts/la-solid-900.ttf) format("truetype"),url(../fonts/la-solid-900.svg#lineawesome) format("svg")}.la,.las{font-family:'Line Awesome Free';font-weight:900}.la.la-glass:before{content:"\f000"}.la.la-meetup{font-family:'Line Awesome Brands';font-weight:400}.la.la-star-o{font-family:'Line Awesome Free';font-weight:400}.la.la-star-o:before{content:"\f005"}.la.la-remove:before{content:"\f00d"}.la.la-close:before{content:"\f00d"}.la.la-gear:before{content:"\f013"}.la.la-trash-o{font-family:'Line Awesome Free';font-weight:400}.la.la-trash-o:before{content:"\f2ed"}.la.la-file-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-o:before{content:"\f15b"}.la.la-clock-o{font-family:'Line Awesome Free';font-weight:400}.la.la-clock-o:before{content:"\f017"}.la.la-arrow-circle-o-down{font-family:'Line Awesome Free';font-weight:400}.la.la-arrow-circle-o-down:before{content:"\f358"}.la.la-arrow-circle-o-up{font-family:'Line Awesome Free';font-weight:400}.la.la-arrow-circle-o-up:before{content:"\f35b"}.la.la-play-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-play-circle-o:before{content:"\f144"}.la.la-repeat:before{content:"\f01e"}.la.la-rotate-right:before{content:"\f01e"}.la.la-refresh:before{content:"\f021"}.la.la-list-alt{font-family:'Line Awesome Free';font-weight:400}.la.la-dedent:before{content:"\f03b"}.la.la-video-camera:before{content:"\f03d"}.la.la-picture-o{font-family:'Line Awesome Free';font-weight:400}.la.la-picture-o:before{content:"\f03e"}.la.la-photo{font-family:'Line Awesome Free';font-weight:400}.la.la-photo:before{content:"\f03e"}.la.la-image{font-family:'Line Awesome Free';font-weight:400}.la.la-image:before{content:"\f03e"}.la.la-pencil:before{content:"\f303"}.la.la-map-marker:before{content:"\f3c5"}.la.la-pencil-square-o{font-family:'Line Awesome Free';font-weight:400}.la.la-pencil-square-o:before{content:"\f044"}.la.la-share-square-o{font-family:'Line Awesome Free';font-weight:400}.la.la-share-square-o:before{content:"\f14d"}.la.la-check-square-o{font-family:'Line Awesome Free';font-weight:400}.la.la-check-square-o:before{content:"\f14a"}.la.la-arrows:before{content:"\f0b2"}.la.la-times-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-times-circle-o:before{content:"\f057"}.la.la-check-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-check-circle-o:before{content:"\f058"}.la.la-mail-forward:before{content:"\f064"}.la.la-eye{font-family:'Line Awesome Free';font-weight:400}.la.la-eye-slash{font-family:'Line Awesome Free';font-weight:400}.la.la-warning:before{content:"\f071"}.la.la-calendar:before{content:"\f073"}.la.la-arrows-v:before{content:"\f338"}.la.la-arrows-h:before{content:"\f337"}.la.la-bar-chart{font-family:'Line Awesome Free';font-weight:400}.la.la-bar-chart:before{content:"\f080"}.la.la-bar-chart-o{font-family:'Line Awesome Free';font-weight:400}.la.la-bar-chart-o:before{content:"\f080"}.la.la-twitter-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-facebook-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-gears:before{content:"\f085"}.la.la-thumbs-o-up{font-family:'Line Awesome Free';font-weight:400}.la.la-thumbs-o-up:before{content:"\f164"}.la.la-thumbs-o-down{font-family:'Line Awesome Free';font-weight:400}.la.la-thumbs-o-down:before{content:"\f165"}.la.la-heart-o{font-family:'Line Awesome Free';font-weight:400}.la.la-heart-o:before{content:"\f004"}.la.la-sign-out:before{content:"\f2f5"}.la.la-linkedin-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-linkedin-square:before{content:"\f08c"}.la.la-thumb-tack:before{content:"\f08d"}.la.la-external-link:before{content:"\f35d"}.la.la-sign-in:before{content:"\f2f6"}.la.la-github-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-lemon-o{font-family:'Line Awesome Free';font-weight:400}.la.la-lemon-o:before{content:"\f094"}.la.la-square-o{font-family:'Line Awesome Free';font-weight:400}.la.la-square-o:before{content:"\f0c8"}.la.la-bookmark-o{font-family:'Line Awesome Free';font-weight:400}.la.la-bookmark-o:before{content:"\f02e"}.la.la-twitter{font-family:'Line Awesome Brands';font-weight:400}.la.la-facebook{font-family:'Line Awesome Brands';font-weight:400}.la.la-facebook:before{content:"\f39e"}.la.la-facebook-f{font-family:'Line Awesome Brands';font-weight:400}.la.la-facebook-f:before{content:"\f39e"}.la.la-github{font-family:'Line Awesome Brands';font-weight:400}.la.la-credit-card{font-family:'Line Awesome Free';font-weight:400}.la.la-feed:before{content:"\f09e"}.la.la-hdd-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hdd-o:before{content:"\f0a0"}.la.la-hand-o-right{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-o-right:before{content:"\f0a4"}.la.la-hand-o-left{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-o-left:before{content:"\f0a5"}.la.la-hand-o-up{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-o-up:before{content:"\f0a6"}.la.la-hand-o-down{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-o-down:before{content:"\f0a7"}.la.la-arrows-alt:before{content:"\f31e"}.la.la-group:before{content:"\f0c0"}.la.la-chain:before{content:"\f0c1"}.la.la-scissors:before{content:"\f0c4"}.la.la-files-o{font-family:'Line Awesome Free';font-weight:400}.la.la-files-o:before{content:"\f0c5"}.la.la-floppy-o{font-family:'Line Awesome Free';font-weight:400}.la.la-floppy-o:before{content:"\f0c7"}.la.la-navicon:before{content:"\f0c9"}.la.la-reorder:before{content:"\f0c9"}.la.la-pinterest{font-family:'Line Awesome Brands';font-weight:400}.la.la-pinterest-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-google-plus-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-google-plus{font-family:'Line Awesome Brands';font-weight:400}.la.la-google-plus:before{content:"\f0d5"}.la.la-money{font-family:'Line Awesome Free';font-weight:400}.la.la-money:before{content:"\f3d1"}.la.la-unsorted:before{content:"\f0dc"}.la.la-sort-desc:before{content:"\f0dd"}.la.la-sort-asc:before{content:"\f0de"}.la.la-linkedin{font-family:'Line Awesome Brands';font-weight:400}.la.la-linkedin:before{content:"\f0e1"}.la.la-rotate-left:before{content:"\f0e2"}.la.la-legal:before{content:"\f0e3"}.la.la-tachometer:before{content:"\f3fd"}.la.la-dashboard:before{content:"\f3fd"}.la.la-comment-o{font-family:'Line Awesome Free';font-weight:400}.la.la-comment-o:before{content:"\f075"}.la.la-comments-o{font-family:'Line Awesome Free';font-weight:400}.la.la-comments-o:before{content:"\f086"}.la.la-flash:before{content:"\f0e7"}.la.la-clipboard{font-family:'Line Awesome Free';font-weight:400}.la.la-paste{font-family:'Line Awesome Free';font-weight:400}.la.la-paste:before{content:"\f328"}.la.la-lightbulb-o{font-family:'Line Awesome Free';font-weight:400}.la.la-lightbulb-o:before{content:"\f0eb"}.la.la-exchange:before{content:"\f362"}.la.la-cloud-download:before{content:"\f381"}.la.la-cloud-upload:before{content:"\f382"}.la.la-bell-o{font-family:'Line Awesome Free';font-weight:400}.la.la-bell-o:before{content:"\f0f3"}.la.la-cutlery:before{content:"\f2e7"}.la.la-file-text-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-text-o:before{content:"\f15c"}.la.la-building-o{font-family:'Line Awesome Free';font-weight:400}.la.la-building-o:before{content:"\f1ad"}.la.la-hospital-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hospital-o:before{content:"\f0f8"}.la.la-tablet:before{content:"\f3fa"}.la.la-mobile:before{content:"\f3cd"}.la.la-mobile-phone:before{content:"\f3cd"}.la.la-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-circle-o:before{content:"\f111"}.la.la-mail-reply:before{content:"\f3e5"}.la.la-github-alt{font-family:'Line Awesome Brands';font-weight:400}.la.la-folder-o{font-family:'Line Awesome Free';font-weight:400}.la.la-folder-o:before{content:"\f07b"}.la.la-folder-open-o{font-family:'Line Awesome Free';font-weight:400}.la.la-folder-open-o:before{content:"\f07c"}.la.la-smile-o{font-family:'Line Awesome Free';font-weight:400}.la.la-smile-o:before{content:"\f118"}.la.la-frown-o{font-family:'Line Awesome Free';font-weight:400}.la.la-frown-o:before{content:"\f119"}.la.la-meh-o{font-family:'Line Awesome Free';font-weight:400}.la.la-meh-o:before{content:"\f11a"}.la.la-keyboard-o{font-family:'Line Awesome Free';font-weight:400}.la.la-keyboard-o:before{content:"\f11c"}.la.la-flag-o{font-family:'Line Awesome Free';font-weight:400}.la.la-flag-o:before{content:"\f024"}.la.la-mail-reply-all:before{content:"\f122"}.la.la-star-half-o{font-family:'Line Awesome Free';font-weight:400}.la.la-star-half-o:before{content:"\f089"}.la.la-star-half-empty{font-family:'Line Awesome Free';font-weight:400}.la.la-star-half-empty:before{content:"\f089"}.la.la-star-half-full{font-family:'Line Awesome Free';font-weight:400}.la.la-star-half-full:before{content:"\f089"}.la.la-code-fork:before{content:"\f126"}.la.la-chain-broken:before{content:"\f127"}.la.la-shield:before{content:"\f3ed"}.la.la-calendar-o{font-family:'Line Awesome Free';font-weight:400}.la.la-calendar-o:before{content:"\f133"}.la.la-maxcdn{font-family:'Line Awesome Brands';font-weight:400}.la.la-html5{font-family:'Line Awesome Brands';font-weight:400}.la.la-css3{font-family:'Line Awesome Brands';font-weight:400}.la.la-ticket:before{content:"\f3ff"}.la.la-minus-square-o{font-family:'Line Awesome Free';font-weight:400}.la.la-minus-square-o:before{content:"\f146"}.la.la-level-up:before{content:"\f3bf"}.la.la-level-down:before{content:"\f3be"}.la.la-pencil-square:before{content:"\f14b"}.la.la-external-link-square:before{content:"\f360"}.la.la-compass{font-family:'Line Awesome Free';font-weight:400}.la.la-caret-square-o-down{font-family:'Line Awesome Free';font-weight:400}.la.la-caret-square-o-down:before{content:"\f150"}.la.la-toggle-down{font-family:'Line Awesome Free';font-weight:400}.la.la-toggle-down:before{content:"\f150"}.la.la-caret-square-o-up{font-family:'Line Awesome Free';font-weight:400}.la.la-caret-square-o-up:before{content:"\f151"}.la.la-toggle-up{font-family:'Line Awesome Free';font-weight:400}.la.la-toggle-up:before{content:"\f151"}.la.la-caret-square-o-right{font-family:'Line Awesome Free';font-weight:400}.la.la-caret-square-o-right:before{content:"\f152"}.la.la-toggle-right{font-family:'Line Awesome Free';font-weight:400}.la.la-toggle-right:before{content:"\f152"}.la.la-eur:before{content:"\f153"}.la.la-euro:before{content:"\f153"}.la.la-gbp:before{content:"\f154"}.la.la-usd:before{content:"\f155"}.la.la-dollar:before{content:"\f155"}.la.la-inr:before{content:"\f156"}.la.la-rupee:before{content:"\f156"}.la.la-jpy:before{content:"\f157"}.la.la-cny:before{content:"\f157"}.la.la-rmb:before{content:"\f157"}.la.la-yen:before{content:"\f157"}.la.la-rub:before{content:"\f158"}.la.la-ruble:before{content:"\f158"}.la.la-rouble:before{content:"\f158"}.la.la-krw:before{content:"\f159"}.la.la-won:before{content:"\f159"}.la.la-btc{font-family:'Line Awesome Brands';font-weight:400}.la.la-bitcoin{font-family:'Line Awesome Brands';font-weight:400}.la.la-bitcoin:before{content:"\f15a"}.la.la-file-text:before{content:"\f15c"}.la.la-sort-alpha-asc:before{content:"\f15d"}.la.la-sort-alpha-desc:before{content:"\f881"}.la.la-sort-amount-asc:before{content:"\f160"}.la.la-sort-amount-desc:before{content:"\f884"}.la.la-sort-numeric-asc:before{content:"\f162"}.la.la-sort-numeric-desc:before{content:"\f886"}.la.la-youtube-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-youtube{font-family:'Line Awesome Brands';font-weight:400}.la.la-xing{font-family:'Line Awesome Brands';font-weight:400}.la.la-xing-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-youtube-play{font-family:'Line Awesome Brands';font-weight:400}.la.la-youtube-play:before{content:"\f167"}.la.la-dropbox{font-family:'Line Awesome Brands';font-weight:400}.la.la-stack-overflow{font-family:'Line Awesome Brands';font-weight:400}.la.la-instagram{font-family:'Line Awesome Brands';font-weight:400}.la.la-flickr{font-family:'Line Awesome Brands';font-weight:400}.la.la-adn{font-family:'Line Awesome Brands';font-weight:400}.la.la-bitbucket{font-family:'Line Awesome Brands';font-weight:400}.la.la-bitbucket-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-bitbucket-square:before{content:"\f171"}.la.la-tumblr{font-family:'Line Awesome Brands';font-weight:400}.la.la-tumblr-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-long-arrow-down:before{content:"\f309"}.la.la-long-arrow-up:before{content:"\f30c"}.la.la-long-arrow-left:before{content:"\f30a"}.la.la-long-arrow-right:before{content:"\f30b"}.la.la-apple{font-family:'Line Awesome Brands';font-weight:400}.la.la-windows{font-family:'Line Awesome Brands';font-weight:400}.la.la-android{font-family:'Line Awesome Brands';font-weight:400}.la.la-linux{font-family:'Line Awesome Brands';font-weight:400}.la.la-dribbble{font-family:'Line Awesome Brands';font-weight:400}.la.la-skype{font-family:'Line Awesome Brands';font-weight:400}.la.la-foursquare{font-family:'Line Awesome Brands';font-weight:400}.la.la-trello{font-family:'Line Awesome Brands';font-weight:400}.la.la-gratipay{font-family:'Line Awesome Brands';font-weight:400}.la.la-gittip{font-family:'Line Awesome Brands';font-weight:400}.la.la-gittip:before{content:"\f184"}.la.la-sun-o{font-family:'Line Awesome Free';font-weight:400}.la.la-sun-o:before{content:"\f185"}.la.la-moon-o{font-family:'Line Awesome Free';font-weight:400}.la.la-moon-o:before{content:"\f186"}.la.la-vk{font-family:'Line Awesome Brands';font-weight:400}.la.la-weibo{font-family:'Line Awesome Brands';font-weight:400}.la.la-renren{font-family:'Line Awesome Brands';font-weight:400}.la.la-pagelines{font-family:'Line Awesome Brands';font-weight:400}.la.la-stack-exchange{font-family:'Line Awesome Brands';font-weight:400}.la.la-arrow-circle-o-right{font-family:'Line Awesome Free';font-weight:400}.la.la-arrow-circle-o-right:before{content:"\f35a"}.la.la-arrow-circle-o-left{font-family:'Line Awesome Free';font-weight:400}.la.la-arrow-circle-o-left:before{content:"\f359"}.la.la-caret-square-o-left{font-family:'Line Awesome Free';font-weight:400}.la.la-caret-square-o-left:before{content:"\f191"}.la.la-toggle-left{font-family:'Line Awesome Free';font-weight:400}.la.la-toggle-left:before{content:"\f191"}.la.la-dot-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-dot-circle-o:before{content:"\f192"}.la.la-vimeo-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-try:before{content:"\f195"}.la.la-turkish-lira:before{content:"\f195"}.la.la-plus-square-o{font-family:'Line Awesome Free';font-weight:400}.la.la-plus-square-o:before{content:"\f0fe"}.la.la-slack{font-family:'Line Awesome Brands';font-weight:400}.la.la-wordpress{font-family:'Line Awesome Brands';font-weight:400}.la.la-openid{font-family:'Line Awesome Brands';font-weight:400}.la.la-institution:before{content:"\f19c"}.la.la-bank:before{content:"\f19c"}.la.la-mortar-board:before{content:"\f19d"}.la.la-yahoo{font-family:'Line Awesome Brands';font-weight:400}.la.la-google{font-family:'Line Awesome Brands';font-weight:400}.la.la-reddit{font-family:'Line Awesome Brands';font-weight:400}.la.la-reddit-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-stumbleupon-circle{font-family:'Line Awesome Brands';font-weight:400}.la.la-stumbleupon{font-family:'Line Awesome Brands';font-weight:400}.la.la-delicious{font-family:'Line Awesome Brands';font-weight:400}.la.la-digg{font-family:'Line Awesome Brands';font-weight:400}.la.la-pied-piper-pp{font-family:'Line Awesome Brands';font-weight:400}.la.la-pied-piper-alt{font-family:'Line Awesome Brands';font-weight:400}.la.la-drupal{font-family:'Line Awesome Brands';font-weight:400}.la.la-joomla{font-family:'Line Awesome Brands';font-weight:400}.la.la-spoon:before{content:"\f2e5"}.la.la-behance{font-family:'Line Awesome Brands';font-weight:400}.la.la-behance-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-steam{font-family:'Line Awesome Brands';font-weight:400}.la.la-steam-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-automobile:before{content:"\f1b9"}.la.la-cab:before{content:"\f1ba"}.la.la-envelope-o{font-family:'Line Awesome Free';font-weight:400}.la.la-envelope-o:before{content:"\f0e0"}.la.la-deviantart{font-family:'Line Awesome Brands';font-weight:400}.la.la-soundcloud{font-family:'Line Awesome Brands';font-weight:400}.la.la-file-pdf-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-pdf-o:before{content:"\f1c1"}.la.la-file-word-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-word-o:before{content:"\f1c2"}.la.la-file-excel-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-excel-o:before{content:"\f1c3"}.la.la-file-powerpoint-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-powerpoint-o:before{content:"\f1c4"}.la.la-file-image-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-image-o:before{content:"\f1c5"}.la.la-file-photo-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-photo-o:before{content:"\f1c5"}.la.la-file-picture-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-picture-o:before{content:"\f1c5"}.la.la-file-archive-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-archive-o:before{content:"\f1c6"}.la.la-file-zip-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-zip-o:before{content:"\f1c6"}.la.la-file-audio-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-audio-o:before{content:"\f1c7"}.la.la-file-sound-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-sound-o:before{content:"\f1c7"}.la.la-file-video-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-video-o:before{content:"\f1c8"}.la.la-file-movie-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-movie-o:before{content:"\f1c8"}.la.la-file-code-o{font-family:'Line Awesome Free';font-weight:400}.la.la-file-code-o:before{content:"\f1c9"}.la.la-vine{font-family:'Line Awesome Brands';font-weight:400}.la.la-codepen{font-family:'Line Awesome Brands';font-weight:400}.la.la-jsfiddle{font-family:'Line Awesome Brands';font-weight:400}.la.la-life-ring{font-family:'Line Awesome Free';font-weight:400}.la.la-life-bouy{font-family:'Line Awesome Free';font-weight:400}.la.la-life-bouy:before{content:"\f1cd"}.la.la-life-buoy{font-family:'Line Awesome Free';font-weight:400}.la.la-life-buoy:before{content:"\f1cd"}.la.la-life-saver{font-family:'Line Awesome Free';font-weight:400}.la.la-life-saver:before{content:"\f1cd"}.la.la-support{font-family:'Line Awesome Free';font-weight:400}.la.la-support:before{content:"\f1cd"}.la.la-circle-o-notch:before{content:"\f1ce"}.la.la-rebel{font-family:'Line Awesome Brands';font-weight:400}.la.la-ra{font-family:'Line Awesome Brands';font-weight:400}.la.la-ra:before{content:"\f1d0"}.la.la-resistance{font-family:'Line Awesome Brands';font-weight:400}.la.la-resistance:before{content:"\f1d0"}.la.la-empire{font-family:'Line Awesome Brands';font-weight:400}.la.la-ge{font-family:'Line Awesome Brands';font-weight:400}.la.la-ge:before{content:"\f1d1"}.la.la-git-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-git{font-family:'Line Awesome Brands';font-weight:400}.la.la-hacker-news{font-family:'Line Awesome Brands';font-weight:400}.la.la-y-combinator-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-y-combinator-square:before{content:"\f1d4"}.la.la-yc-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-yc-square:before{content:"\f1d4"}.la.la-tencent-weibo{font-family:'Line Awesome Brands';font-weight:400}.la.la-qq{font-family:'Line Awesome Brands';font-weight:400}.la.la-weixin{font-family:'Line Awesome Brands';font-weight:400}.la.la-wechat{font-family:'Line Awesome Brands';font-weight:400}.la.la-wechat:before{content:"\f1d7"}.la.la-send:before{content:"\f1d8"}.la.la-paper-plane-o{font-family:'Line Awesome Free';font-weight:400}.la.la-paper-plane-o:before{content:"\f1d8"}.la.la-send-o{font-family:'Line Awesome Free';font-weight:400}.la.la-send-o:before{content:"\f1d8"}.la.la-circle-thin{font-family:'Line Awesome Free';font-weight:400}.la.la-circle-thin:before{content:"\f111"}.la.la-header:before{content:"\f1dc"}.la.la-sliders:before{content:"\f1de"}.la.la-futbol-o{font-family:'Line Awesome Free';font-weight:400}.la.la-futbol-o:before{content:"\f1e3"}.la.la-soccer-ball-o{font-family:'Line Awesome Free';font-weight:400}.la.la-soccer-ball-o:before{content:"\f1e3"}.la.la-slideshare{font-family:'Line Awesome Brands';font-weight:400}.la.la-twitch{font-family:'Line Awesome Brands';font-weight:400}.la.la-yelp{font-family:'Line Awesome Brands';font-weight:400}.la.la-newspaper-o{font-family:'Line Awesome Free';font-weight:400}.la.la-newspaper-o:before{content:"\f1ea"}.la.la-paypal{font-family:'Line Awesome Brands';font-weight:400}.la.la-google-wallet{font-family:'Line Awesome Brands';font-weight:400}.la.la-cc-visa{font-family:'Line Awesome Brands';font-weight:400}.la.la-cc-mastercard{font-family:'Line Awesome Brands';font-weight:400}.la.la-cc-discover{font-family:'Line Awesome Brands';font-weight:400}.la.la-cc-amex{font-family:'Line Awesome Brands';font-weight:400}.la.la-cc-paypal{font-family:'Line Awesome Brands';font-weight:400}.la.la-cc-stripe{font-family:'Line Awesome Brands';font-weight:400}.la.la-bell-slash-o{font-family:'Line Awesome Free';font-weight:400}.la.la-bell-slash-o:before{content:"\f1f6"}.la.la-trash:before{content:"\f2ed"}.la.la-copyright{font-family:'Line Awesome Free';font-weight:400}.la.la-eyedropper:before{content:"\f1fb"}.la.la-area-chart:before{content:"\f1fe"}.la.la-pie-chart:before{content:"\f200"}.la.la-line-chart:before{content:"\f201"}.la.la-lastfm{font-family:'Line Awesome Brands';font-weight:400}.la.la-lastfm-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-ioxhost{font-family:'Line Awesome Brands';font-weight:400}.la.la-angellist{font-family:'Line Awesome Brands';font-weight:400}.la.la-cc{font-family:'Line Awesome Free';font-weight:400}.la.la-cc:before{content:"\f20a"}.la.la-ils:before{content:"\f20b"}.la.la-shekel:before{content:"\f20b"}.la.la-sheqel:before{content:"\f20b"}.la.la-meanpath{font-family:'Line Awesome Brands';font-weight:400}.la.la-meanpath:before{content:"\f2b4"}.la.la-buysellads{font-family:'Line Awesome Brands';font-weight:400}.la.la-connectdevelop{font-family:'Line Awesome Brands';font-weight:400}.la.la-dashcube{font-family:'Line Awesome Brands';font-weight:400}.la.la-forumbee{font-family:'Line Awesome Brands';font-weight:400}.la.la-leanpub{font-family:'Line Awesome Brands';font-weight:400}.la.la-sellsy{font-family:'Line Awesome Brands';font-weight:400}.la.la-shirtsinbulk{font-family:'Line Awesome Brands';font-weight:400}.la.la-simplybuilt{font-family:'Line Awesome Brands';font-weight:400}.la.la-skyatlas{font-family:'Line Awesome Brands';font-weight:400}.la.la-diamond{font-family:'Line Awesome Free';font-weight:400}.la.la-diamond:before{content:"\f3a5"}.la.la-intersex:before{content:"\f224"}.la.la-facebook-official{font-family:'Line Awesome Brands';font-weight:400}.la.la-facebook-official:before{content:"\f09a"}.la.la-pinterest-p{font-family:'Line Awesome Brands';font-weight:400}.la.la-whatsapp{font-family:'Line Awesome Brands';font-weight:400}.la.la-hotel:before{content:"\f236"}.la.la-viacoin{font-family:'Line Awesome Brands';font-weight:400}.la.la-medium{font-family:'Line Awesome Brands';font-weight:400}.la.la-y-combinator{font-family:'Line Awesome Brands';font-weight:400}.la.la-yc{font-family:'Line Awesome Brands';font-weight:400}.la.la-yc:before{content:"\f23b"}.la.la-optin-monster{font-family:'Line Awesome Brands';font-weight:400}.la.la-opencart{font-family:'Line Awesome Brands';font-weight:400}.la.la-expeditedssl{font-family:'Line Awesome Brands';font-weight:400}.la.la-battery-4:before{content:"\f240"}.la.la-battery:before{content:"\f240"}.la.la-battery-3:before{content:"\f241"}.la.la-battery-2:before{content:"\f242"}.la.la-battery-1:before{content:"\f243"}.la.la-battery-0:before{content:"\f244"}.la.la-object-group{font-family:'Line Awesome Free';font-weight:400}.la.la-object-ungroup{font-family:'Line Awesome Free';font-weight:400}.la.la-sticky-note-o{font-family:'Line Awesome Free';font-weight:400}.la.la-sticky-note-o:before{content:"\f249"}.la.la-cc-jcb{font-family:'Line Awesome Brands';font-weight:400}.la.la-cc-diners-club{font-family:'Line Awesome Brands';font-weight:400}.la.la-clone{font-family:'Line Awesome Free';font-weight:400}.la.la-hourglass-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hourglass-o:before{content:"\f254"}.la.la-hourglass-1:before{content:"\f251"}.la.la-hourglass-2:before{content:"\f252"}.la.la-hourglass-3:before{content:"\f253"}.la.la-hand-rock-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-rock-o:before{content:"\f255"}.la.la-hand-grab-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-grab-o:before{content:"\f255"}.la.la-hand-paper-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-paper-o:before{content:"\f256"}.la.la-hand-stop-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-stop-o:before{content:"\f256"}.la.la-hand-scissors-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-scissors-o:before{content:"\f257"}.la.la-hand-lizard-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-lizard-o:before{content:"\f258"}.la.la-hand-spock-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-spock-o:before{content:"\f259"}.la.la-hand-pointer-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-pointer-o:before{content:"\f25a"}.la.la-hand-peace-o{font-family:'Line Awesome Free';font-weight:400}.la.la-hand-peace-o:before{content:"\f25b"}.la.la-registered{font-family:'Line Awesome Free';font-weight:400}.la.la-creative-commons{font-family:'Line Awesome Brands';font-weight:400}.la.la-gg{font-family:'Line Awesome Brands';font-weight:400}.la.la-gg-circle{font-family:'Line Awesome Brands';font-weight:400}.la.la-tripadvisor{font-family:'Line Awesome Brands';font-weight:400}.la.la-odnoklassniki{font-family:'Line Awesome Brands';font-weight:400}.la.la-odnoklassniki-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-get-pocket{font-family:'Line Awesome Brands';font-weight:400}.la.la-wikipedia-w{font-family:'Line Awesome Brands';font-weight:400}.la.la-safari{font-family:'Line Awesome Brands';font-weight:400}.la.la-chrome{font-family:'Line Awesome Brands';font-weight:400}.la.la-firefox{font-family:'Line Awesome Brands';font-weight:400}.la.la-opera{font-family:'Line Awesome Brands';font-weight:400}.la.la-internet-explorer{font-family:'Line Awesome Brands';font-weight:400}.la.la-television:before{content:"\f26c"}.la.la-contao{font-family:'Line Awesome Brands';font-weight:400}.la.la-500px{font-family:'Line Awesome Brands';font-weight:400}.la.la-amazon{font-family:'Line Awesome Brands';font-weight:400}.la.la-calendar-plus-o{font-family:'Line Awesome Free';font-weight:400}.la.la-calendar-plus-o:before{content:"\f271"}.la.la-calendar-minus-o{font-family:'Line Awesome Free';font-weight:400}.la.la-calendar-minus-o:before{content:"\f272"}.la.la-calendar-times-o{font-family:'Line Awesome Free';font-weight:400}.la.la-calendar-times-o:before{content:"\f273"}.la.la-calendar-check-o{font-family:'Line Awesome Free';font-weight:400}.la.la-calendar-check-o:before{content:"\f274"}.la.la-map-o{font-family:'Line Awesome Free';font-weight:400}.la.la-map-o:before{content:"\f279"}.la.la-commenting:before{content:"\f4ad"}.la.la-commenting-o{font-family:'Line Awesome Free';font-weight:400}.la.la-commenting-o:before{content:"\f4ad"}.la.la-houzz{font-family:'Line Awesome Brands';font-weight:400}.la.la-vimeo{font-family:'Line Awesome Brands';font-weight:400}.la.la-vimeo:before{content:"\f27d"}.la.la-black-tie{font-family:'Line Awesome Brands';font-weight:400}.la.la-fonticons{font-family:'Line Awesome Brands';font-weight:400}.la.la-reddit-alien{font-family:'Line Awesome Brands';font-weight:400}.la.la-edge{font-family:'Line Awesome Brands';font-weight:400}.la.la-credit-card-alt:before{content:"\f09d"}.la.la-codiepie{font-family:'Line Awesome Brands';font-weight:400}.la.la-modx{font-family:'Line Awesome Brands';font-weight:400}.la.la-fort-awesome{font-family:'Line Awesome Brands';font-weight:400}.la.la-usb{font-family:'Line Awesome Brands';font-weight:400}.la.la-product-hunt{font-family:'Line Awesome Brands';font-weight:400}.la.la-mixcloud{font-family:'Line Awesome Brands';font-weight:400}.la.la-scribd{font-family:'Line Awesome Brands';font-weight:400}.la.la-pause-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-pause-circle-o:before{content:"\f28b"}.la.la-stop-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-stop-circle-o:before{content:"\f28d"}.la.la-bluetooth{font-family:'Line Awesome Brands';font-weight:400}.la.la-bluetooth-b{font-family:'Line Awesome Brands';font-weight:400}.la.la-gitlab{font-family:'Line Awesome Brands';font-weight:400}.la.la-wpbeginner{font-family:'Line Awesome Brands';font-weight:400}.la.la-wpforms{font-family:'Line Awesome Brands';font-weight:400}.la.la-envira{font-family:'Line Awesome Brands';font-weight:400}.la.la-wheelchair-alt{font-family:'Line Awesome Brands';font-weight:400}.la.la-wheelchair-alt:before{content:"\f368"}.la.la-question-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-question-circle-o:before{content:"\f059"}.la.la-volume-control-phone:before{content:"\f2a0"}.la.la-asl-interpreting:before{content:"\f2a3"}.la.la-deafness:before{content:"\f2a4"}.la.la-hard-of-hearing:before{content:"\f2a4"}.la.la-glide{font-family:'Line Awesome Brands';font-weight:400}.la.la-glide-g{font-family:'Line Awesome Brands';font-weight:400}.la.la-signing:before{content:"\f2a7"}.la.la-viadeo{font-family:'Line Awesome Brands';font-weight:400}.la.la-viadeo-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-snapchat{font-family:'Line Awesome Brands';font-weight:400}.la.la-snapchat-ghost{font-family:'Line Awesome Brands';font-weight:400}.la.la-snapchat-square{font-family:'Line Awesome Brands';font-weight:400}.la.la-pied-piper{font-family:'Line Awesome Brands';font-weight:400}.la.la-first-order{font-family:'Line Awesome Brands';font-weight:400}.la.la-yoast{font-family:'Line Awesome Brands';font-weight:400}.la.la-themeisle{font-family:'Line Awesome Brands';font-weight:400}.la.la-google-plus-official{font-family:'Line Awesome Brands';font-weight:400}.la.la-google-plus-official:before{content:"\f2b3"}.la.la-google-plus-circle{font-family:'Line Awesome Brands';font-weight:400}.la.la-google-plus-circle:before{content:"\f2b3"}.la.la-font-awesome{font-family:'Line Awesome Brands';font-weight:400}.la.la-fa{font-family:'Line Awesome Brands';font-weight:400}.la.la-fa:before{content:"\f2b4"}.la.la-handshake-o{font-family:'Line Awesome Free';font-weight:400}.la.la-handshake-o:before{content:"\f2b5"}.la.la-envelope-open-o{font-family:'Line Awesome Free';font-weight:400}.la.la-envelope-open-o:before{content:"\f2b6"}.la.la-linode{font-family:'Line Awesome Brands';font-weight:400}.la.la-address-book-o{font-family:'Line Awesome Free';font-weight:400}.la.la-address-book-o:before{content:"\f2b9"}.la.la-vcard:before{content:"\f2bb"}.la.la-address-card-o{font-family:'Line Awesome Free';font-weight:400}.la.la-address-card-o:before{content:"\f2bb"}.la.la-vcard-o{font-family:'Line Awesome Free';font-weight:400}.la.la-vcard-o:before{content:"\f2bb"}.la.la-user-circle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-user-circle-o:before{content:"\f2bd"}.la.la-user-o{font-family:'Line Awesome Free';font-weight:400}.la.la-user-o:before{content:"\f007"}.la.la-id-badge{font-family:'Line Awesome Free';font-weight:400}.la.la-drivers-license:before{content:"\f2c2"}.la.la-id-card-o{font-family:'Line Awesome Free';font-weight:400}.la.la-id-card-o:before{content:"\f2c2"}.la.la-drivers-license-o{font-family:'Line Awesome Free';font-weight:400}.la.la-drivers-license-o:before{content:"\f2c2"}.la.la-quora{font-family:'Line Awesome Brands';font-weight:400}.la.la-free-code-camp{font-family:'Line Awesome Brands';font-weight:400}.la.la-telegram{font-family:'Line Awesome Brands';font-weight:400}.la.la-thermometer-4:before{content:"\f2c7"}.la.la-thermometer:before{content:"\f2c7"}.la.la-thermometer-3:before{content:"\f2c8"}.la.la-thermometer-2:before{content:"\f2c9"}.la.la-thermometer-1:before{content:"\f2ca"}.la.la-thermometer-0:before{content:"\f2cb"}.la.la-bathtub:before{content:"\f2cd"}.la.la-s15:before{content:"\f2cd"}.la.la-window-maximize{font-family:'Line Awesome Free';font-weight:400}.la.la-window-restore{font-family:'Line Awesome Free';font-weight:400}.la.la-times-rectangle:before{content:"\f410"}.la.la-window-close-o{font-family:'Line Awesome Free';font-weight:400}.la.la-window-close-o:before{content:"\f410"}.la.la-times-rectangle-o{font-family:'Line Awesome Free';font-weight:400}.la.la-times-rectangle-o:before{content:"\f410"}.la.la-bandcamp{font-family:'Line Awesome Brands';font-weight:400}.la.la-grav{font-family:'Line Awesome Brands';font-weight:400}.la.la-etsy{font-family:'Line Awesome Brands';font-weight:400}.la.la-imdb{font-family:'Line Awesome Brands';font-weight:400}.la.la-ravelry{font-family:'Line Awesome Brands';font-weight:400}.la.la-eercast{font-family:'Line Awesome Brands';font-weight:400}.la.la-eercast:before{content:"\f2da"}.la.la-snowflake-o{font-family:'Line Awesome Free';font-weight:400}.la.la-snowflake-o:before{content:"\f2dc"}.la.la-superpowers{font-family:'Line Awesome Brands';font-weight:400}.la.la-wpexplorer{font-family:'Line Awesome Brands';font-weight:400}.la.la-spotify{font-family:'Line Awesome Brands';font-weight:400} diff --git a/python/static/css/style.css b/python/static/css/style.css new file mode 100644 index 0000000..adfea1a --- /dev/null +++ b/python/static/css/style.css @@ -0,0 +1,159 @@ +body { + background-color: #f5f5f5; + background-image: url('/static/img/bg.png'); + background-size: cover; +} + +.align-center { + vertical-align: middle; + text-align: center; +} + +/* Layout */ +.centered { + position: fixed; + text-align: center; + top: 50%; + left: 50%; + transform: translate(-50%, -50%) !important; +} + +#disk { + width: 66vw; + border-radius: 1200px; + aspect-ratio: 1 / 1 !important; + background-image: url('/static/img/vinyl.png'); + background-position: center; + background-size: cover; +} + +.card { + box-shadow: 0 0 36px 0px rgba(128, 128, 128, 0.128); + background-color: white; + padding: 32px; + border-radius: 20px; +} + +.modal-body { + background-color: #f5f5f5; +} + +.navbar-avatar { + max-height: 40px; + border-radius: 30px; + height: 40px; +} + +.main-menu-link { + /*font-size: 24px;*/ + /*font-family: RobotoSlab;*/ +} + +a { + text-decoration: none; + transition: 0.3s; +} + +#header { + position: fixed; + top: 0; + width: 100%; +} + +#action_list { + float: right; + padding: 20px; + color: white; + position: fixed; + right: 0; +} + +#action_list a { + color: white; +} + +#logo { + display: flex; + align-items: baseline; +} + +#search_bar { + background: url('/static/svg/search-solid.svg') no-repeat scroll 12px 7px; + padding-left: 48px; + background-size: 20px; + border-radius: 66px; +} + +#navigation { + /*padding-top: 32px;*/ +} + +.navbar { + padding-left: 12px; + padding-right: 12px; +} + +#navigation_logo { + max-width: 216px; +} + +#content { + min-height: 100vh; +} + +#footer { + text-align: center; + position: fixed; + bottom: 0; + width: 100%; +} + +.logo { + width: 100%; +} + +.dl_queue_img { + position: relative; +} + +.icn-spinner { + animation: spin-animation 0.9s infinite; + display: inline-block; +} + +.icn-downloading { + top: 50%; + left: 50%; + position: absolute; + transform: translate(-50%, -50%); +} + +.vinyl-card { + background-image: url('/static/img/vinyl-card.png'); + background-position: right; + border-radius: 20px; +} + +@keyframes spin-animation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(359deg); + } +} + +@keyframes spin{ + from{transform:rotate(0deg)} + to{transform:rotate(360deg)} +} + +@-webkit-keyframes spin { + from {-webkit-transform:rotate(0deg);} + to { -webkit-transform:rotate(360deg);} +} + +@-moz-keyframes spin { + from {-moz-transform:rotate(0deg);} + to { -moz-transform:rotate(360deg);} +} diff --git a/python/static/favicon.ico b/python/static/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/python/static/favicon.svg b/python/static/favicon.svg new file mode 100755 index 0000000..11969e7 --- /dev/null +++ b/python/static/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/python/static/fonts/la-brands-400.eot b/python/static/fonts/la-brands-400.eot new file mode 100644 index 0000000..81969f5 Binary files /dev/null and b/python/static/fonts/la-brands-400.eot differ diff --git a/python/static/fonts/la-brands-400.svg b/python/static/fonts/la-brands-400.svg new file mode 100644 index 0000000..b903f64 --- /dev/null +++ b/python/static/fonts/la-brands-400.svg @@ -0,0 +1,1313 @@ + + + +Created by Icons8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/python/static/fonts/la-brands-400.ttf b/python/static/fonts/la-brands-400.ttf new file mode 100644 index 0000000..6cd243d Binary files /dev/null and b/python/static/fonts/la-brands-400.ttf differ diff --git a/python/static/fonts/la-brands-400.woff b/python/static/fonts/la-brands-400.woff new file mode 100644 index 0000000..32f7df4 Binary files /dev/null and b/python/static/fonts/la-brands-400.woff differ diff --git a/python/static/fonts/la-brands-400.woff2 b/python/static/fonts/la-brands-400.woff2 new file mode 100644 index 0000000..5177028 Binary files /dev/null and b/python/static/fonts/la-brands-400.woff2 differ diff --git a/python/static/fonts/la-regular-400.eot b/python/static/fonts/la-regular-400.eot new file mode 100644 index 0000000..a93a4a2 Binary files /dev/null and b/python/static/fonts/la-regular-400.eot differ diff --git a/python/static/fonts/la-regular-400.svg b/python/static/fonts/la-regular-400.svg new file mode 100644 index 0000000..43b8602 --- /dev/null +++ b/python/static/fonts/la-regular-400.svg @@ -0,0 +1,467 @@ + + + +Created by Icons8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/python/static/fonts/la-regular-400.ttf b/python/static/fonts/la-regular-400.ttf new file mode 100644 index 0000000..226653f Binary files /dev/null and b/python/static/fonts/la-regular-400.ttf differ diff --git a/python/static/fonts/la-regular-400.woff b/python/static/fonts/la-regular-400.woff new file mode 100644 index 0000000..3010f91 Binary files /dev/null and b/python/static/fonts/la-regular-400.woff differ diff --git a/python/static/fonts/la-regular-400.woff2 b/python/static/fonts/la-regular-400.woff2 new file mode 100644 index 0000000..f7dab5d Binary files /dev/null and b/python/static/fonts/la-regular-400.woff2 differ diff --git a/python/static/fonts/la-solid-900.eot b/python/static/fonts/la-solid-900.eot new file mode 100644 index 0000000..d739c05 Binary files /dev/null and b/python/static/fonts/la-solid-900.eot differ diff --git a/python/static/fonts/la-solid-900.svg b/python/static/fonts/la-solid-900.svg new file mode 100644 index 0000000..02fc485 --- /dev/null +++ b/python/static/fonts/la-solid-900.svg @@ -0,0 +1,2894 @@ + + + +Created by Icons8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/python/static/fonts/la-solid-900.ttf b/python/static/fonts/la-solid-900.ttf new file mode 100644 index 0000000..e0ec957 Binary files /dev/null and b/python/static/fonts/la-solid-900.ttf differ diff --git a/python/static/fonts/la-solid-900.woff b/python/static/fonts/la-solid-900.woff new file mode 100644 index 0000000..26a5134 Binary files /dev/null and b/python/static/fonts/la-solid-900.woff differ diff --git a/python/static/fonts/la-solid-900.woff2 b/python/static/fonts/la-solid-900.woff2 new file mode 100644 index 0000000..22e909c Binary files /dev/null and b/python/static/fonts/la-solid-900.woff2 differ diff --git a/python/static/img/bg.png b/python/static/img/bg.png new file mode 100644 index 0000000..0267986 Binary files /dev/null and b/python/static/img/bg.png differ diff --git a/python/static/img/vinyl-card.jpg b/python/static/img/vinyl-card.jpg new file mode 100644 index 0000000..b2c74cc Binary files /dev/null and b/python/static/img/vinyl-card.jpg differ diff --git a/python/static/img/vinyl-card.png b/python/static/img/vinyl-card.png new file mode 100644 index 0000000..d5184b5 Binary files /dev/null and b/python/static/img/vinyl-card.png differ diff --git a/python/static/img/vinyl-card.xcf b/python/static/img/vinyl-card.xcf new file mode 100644 index 0000000..edc65bc Binary files /dev/null and b/python/static/img/vinyl-card.xcf differ diff --git a/python/static/img/vinyl.png b/python/static/img/vinyl.png new file mode 100644 index 0000000..36fbcc1 Binary files /dev/null and b/python/static/img/vinyl.png differ diff --git a/python/static/img/vinyl.xcf b/python/static/img/vinyl.xcf new file mode 100644 index 0000000..9957345 Binary files /dev/null and b/python/static/img/vinyl.xcf differ diff --git a/python/static/index.php b/python/static/index.php new file mode 100644 index 0000000..947d989 --- /dev/null +++ b/python/static/index.php @@ -0,0 +1,17 @@ +handleRequest(Request::capture()); diff --git a/python/static/js/app.js b/python/static/js/app.js new file mode 100644 index 0000000..9d667ad --- /dev/null +++ b/python/static/js/app.js @@ -0,0 +1,166 @@ +console.log('Version 1:20:2'); +const appModal = $('#modalDownloadQueue'); +const loader = $("#loader-wrapper"); +let ArtistTable = {}; // Initialized for ajax reload + +function requestQueue() { + $.ajax({ + url: '/api/queue', + success: (response) => { + Alpine.store('app').Queue = response; + } + }) +} + +function template_artist_result(element) { + let image_src = element.image.replace('/var/www/html/public', ''); + console.log(image_src); + return ` +
+
+
+
+ +
+
+

${element.name}

+
+
+
+
+ ` +} + +function construct_artist_result_html(artist_list) { + let html = '

Found Artist

'; + let index = 0; + if (artist_list.length > 1) { + artist_list.forEach((element) => { + index += 1; + html += template_artist_result(element); + if (index === 1 && artist_list.length > 1) { + html += '
'; + html += '
Suggested Artists
' + html += '
'; + } + }) + } else { + html += template_artist_result(artist_list); + } + return html +} + +function proc_notification(icon, title, html) { + Swal.fire({ + icon: icon, + title: title, + html: html + }) +} + +function artist_queue_toggle(element) { + let self = $(element); + let artist_name = self.data('artist_name'); + self.prop('disabled', true) + $.ajax({ + url: `/api/queue/artist/${self.data('artist_id')}`, + success: () => { + proc_notification('success', 'Queued Download', `Artist ${artist_name} Queued for Download!`); + // ArtistTable.ajax.reload(); + }, + error: (response) => { + console.log(response); + proc_notification('error', 'What the flip?!', `Failed to queue artist ${artist_name}

${response.status}: ${response.statusText}`); + self.prop('disabled', false); + } + }) +} + +function bind_action_buttons() { + $('#settings_btn').on('click', () => { + $('#modalSettings').modal('toggle'); + }); + + $('#catalog_btn').on('click', () => { + $('#modalCatalog').modal('toggle'); + }); + + $('#queue_btn').on('click', () => { + appModal.modal('toggle'); + }); + + $('#download_btn').on('click', () => { + let artist = $('#search_bar').val(); + + // Send request to server + setTimeout(() => { + + if (artist == '') { + return proc_notification('error', 'Whoopsie!', 'You need to add an artist, c\'mon man!');; + } + + loader.fadeIn(300); + + $.ajax({ + url: `/artist/${artist}`, + success: (response) => { + let html = construct_artist_result_html(response); + proc_notification('success', 'Shazam!', html); + ArtistTable.ajax.reload(); + $('#search_bar').val(''); + loader.fadeOut(700); + }, + error: (response) => { + proc_notification('error', 'What the flip?!', response.statusText); + loader.fadeOut(700); + } + }); + + }, 10); + + }); +} + +document.addEventListener('alpine:init', () => { + console.log('Alpine:init'); + Alpine.store('app', { + Queue: [], // Rendered in the 'Queue' modal + }); + requestQueue(); + setInterval(requestQueue, 10000); + $("#loader-wrapper").fadeOut(900); + +}); + +$(document).ready(function () { + bind_action_buttons(); + //Datatable for 'Catalog' menu + ArtistTable = $('#artistsCatalogDatatable').DataTable({ + ajax: '/api/artists', + type: 'get', + dataType: 'json', + columns: [ + { + data: 'thumbnail', orderable: false, render: (data) => { + return `` + } + }, + {data: 'name'}, + { + title: 'Channel', data: 'url_remote', render: (data) => { + return `` + } + }, + {data: 'state'}, + { + data: 'id', orderable: false, render: (data, type, row) => { + let stateDiable = row.state === 'in_progress' ? 'disabled' : ''; + let stateClass = row.state === 'done' ? 'btn-success' : 'btn-primary'; + let artist_name = row.name; + let button_icon = row.state === 'done' ? '' : ''; + return `` + } + } + ], + }); +}); diff --git a/python/static/js/datatables.js b/python/static/js/datatables.js new file mode 100644 index 0000000..b3a4cfe --- /dev/null +++ b/python/static/js/datatables.js @@ -0,0 +1,13544 @@ +/*! DataTables 2.1.3 + * © SpryMedia Ltd - datatables.net/license + */ + +/** + * @summary DataTables + * @description Paginate, search and order HTML tables + * @version 2.1.3 + * @author SpryMedia Ltd + * @contact www.datatables.net + * @copyright SpryMedia Ltd. + * + * This source file is free software, available under the following license: + * MIT license - https://datatables.net/license + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: https://www.datatables.net + */ + +(function( factory ) { + "use strict"; + + if ( typeof define === 'function' && define.amd ) { + // AMD + define( ['jquery'], function ( $ ) { + return factory( $, window, document ); + } ); + } + else if ( typeof exports === 'object' ) { + // CommonJS + // jQuery's factory checks for a global window - if it isn't present then it + // returns a factory function that expects the window object + var jq = require('jquery'); + + if (typeof window === 'undefined') { + module.exports = function (root, $) { + if ( ! root ) { + // CommonJS environments without a window global must pass a + // root. This will give an error otherwise + root = window; + } + + if ( ! $ ) { + $ = jq( root ); + } + + return factory( $, root, root.document ); + }; + } + else { + module.exports = factory( jq, window, window.document ); + } + } + else { + // Browser + window.DataTable = factory( jQuery, window, document ); + } +}(function( $, window, document ) { + "use strict"; + + + var DataTable = function ( selector, options ) + { + // Check if called with a window or jQuery object for DOM less applications + // This is for backwards compatibility + if (DataTable.factory(selector, options)) { + return DataTable; + } + + // When creating with `new`, create a new DataTable, returning the API instance + if (this instanceof DataTable) { + return $(selector).DataTable(options); + } + else { + // Argument switching + options = selector; + } + + var _that = this; + var emptyInit = options === undefined; + var len = this.length; + + if ( emptyInit ) { + options = {}; + } + + // Method to get DT API instance from jQuery object + this.api = function () + { + return new _Api( this ); + }; + + this.each(function() { + // For each initialisation we want to give it a clean initialisation + // object that can be bashed around + var o = {}; + var oInit = len > 1 ? // optimisation for single table case + _fnExtend( o, options, true ) : + options; + + + var i=0, iLen; + var sId = this.getAttribute( 'id' ); + var defaults = DataTable.defaults; + var $this = $(this); + + + /* Sanity check */ + if ( this.nodeName.toLowerCase() != 'table' ) + { + _fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 ); + return; + } + + $(this).trigger( 'options.dt', oInit ); + + /* Backwards compatibility for the defaults */ + _fnCompatOpts( defaults ); + _fnCompatCols( defaults.column ); + + /* Convert the camel-case defaults to Hungarian */ + _fnCamelToHungarian( defaults, defaults, true ); + _fnCamelToHungarian( defaults.column, defaults.column, true ); + + /* Setting up the initialisation object */ + _fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ), true ); + + + + /* Check to see if we are re-initialising a table */ + var allSettings = DataTable.settings; + for ( i=0, iLen=allSettings.length ; i').prependTo(this), + fastData: function (row, column, type) { + return _fnGetCellData(oSettings, row, column, type); + } + } ); + oSettings.nTable = this; + oSettings.oInit = oInit; + + allSettings.push( oSettings ); + + // Make a single API instance available for internal handling + oSettings.api = new _Api( oSettings ); + + // Need to add the instance after the instance after the settings object has been added + // to the settings array, so we can self reference the table instance if more than one + oSettings.oInstance = (_that.length===1) ? _that : $this.dataTable(); + + // Backwards compatibility, before we apply all the defaults + _fnCompatOpts( oInit ); + + // If the length menu is given, but the init display length is not, use the length menu + if ( oInit.aLengthMenu && ! oInit.iDisplayLength ) + { + oInit.iDisplayLength = Array.isArray(oInit.aLengthMenu[0]) + ? oInit.aLengthMenu[0][0] + : $.isPlainObject( oInit.aLengthMenu[0] ) + ? oInit.aLengthMenu[0].value + : oInit.aLengthMenu[0]; + } + + // Apply the defaults and init options to make a single init object will all + // options defined from defaults and instance options. + oInit = _fnExtend( $.extend( true, {}, defaults ), oInit ); + + + // Map the initialisation options onto the settings object + _fnMap( oSettings.oFeatures, oInit, [ + "bPaginate", + "bLengthChange", + "bFilter", + "bSort", + "bSortMulti", + "bInfo", + "bProcessing", + "bAutoWidth", + "bSortClasses", + "bServerSide", + "bDeferRender" + ] ); + _fnMap( oSettings, oInit, [ + "ajax", + "fnFormatNumber", + "sServerMethod", + "aaSorting", + "aaSortingFixed", + "aLengthMenu", + "sPaginationType", + "iStateDuration", + "bSortCellsTop", + "iTabIndex", + "sDom", + "fnStateLoadCallback", + "fnStateSaveCallback", + "renderer", + "searchDelay", + "rowId", + "caption", + "layout", + "orderDescReverse", + [ "iCookieDuration", "iStateDuration" ], // backwards compat + [ "oSearch", "oPreviousSearch" ], + [ "aoSearchCols", "aoPreSearchCols" ], + [ "iDisplayLength", "_iDisplayLength" ] + ] ); + _fnMap( oSettings.oScroll, oInit, [ + [ "sScrollX", "sX" ], + [ "sScrollXInner", "sXInner" ], + [ "sScrollY", "sY" ], + [ "bScrollCollapse", "bCollapse" ] + ] ); + _fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" ); + + /* Callback functions which are array driven */ + _fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback ); + _fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams ); + _fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams ); + _fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded ); + _fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback ); + _fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow ); + _fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback ); + _fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback ); + _fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete ); + _fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback ); + + oSettings.rowIdFn = _fnGetObjectDataFn( oInit.rowId ); + + /* Browser support detection */ + _fnBrowserDetect( oSettings ); + + var oClasses = oSettings.oClasses; + + $.extend( oClasses, DataTable.ext.classes, oInit.oClasses ); + $this.addClass( oClasses.table ); + + if (! oSettings.oFeatures.bPaginate) { + oInit.iDisplayStart = 0; + } + + if ( oSettings.iInitDisplayStart === undefined ) + { + /* Display start point, taking into account the save saving */ + oSettings.iInitDisplayStart = oInit.iDisplayStart; + oSettings._iDisplayStart = oInit.iDisplayStart; + } + + var defer = oInit.iDeferLoading; + if ( defer !== null ) + { + oSettings.deferLoading = true; + + var tmp = Array.isArray(defer); + oSettings._iRecordsDisplay = tmp ? defer[0] : defer; + oSettings._iRecordsTotal = tmp ? defer[1] : defer; + } + + /* + * Columns + * See if we should load columns automatically or use defined ones + */ + var columnsInit = []; + var thead = this.getElementsByTagName('thead'); + var initHeaderLayout = _fnDetectHeader( oSettings, thead[0] ); + + // If we don't have a columns array, then generate one with nulls + if ( oInit.aoColumns ) { + columnsInit = oInit.aoColumns; + } + else if ( initHeaderLayout.length ) { + for ( i=0, iLen=initHeaderLayout[0].length ; i').appendTo( $this ); + } + + caption.html( oSettings.caption ); + } + + // Store the caption side, so we can remove the element from the document + // when creating the element + if (caption.length) { + caption[0]._captionSide = caption.css('caption-side'); + oSettings.captionNode = caption[0]; + } + + if ( thead.length === 0 ) { + thead = $('').appendTo($this); + } + oSettings.nTHead = thead[0]; + $('tr', thead).addClass(oClasses.thead.row); + + var tbody = $this.children('tbody'); + if ( tbody.length === 0 ) { + tbody = $('').insertAfter(thead); + } + oSettings.nTBody = tbody[0]; + + var tfoot = $this.children('tfoot'); + if ( tfoot.length === 0 ) { + // If we are a scrolling table, and no footer has been given, then we need to create + // a tfoot element for the caption element to be appended to + tfoot = $('').appendTo($this); + } + oSettings.nTFoot = tfoot[0]; + $('tr', tfoot).addClass(oClasses.tfoot.row); + + // Copy the data index array + oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); + + // Initialisation complete - table can be drawn + oSettings.bInitialised = true; + + // Language definitions + var oLanguage = oSettings.oLanguage; + $.extend( true, oLanguage, oInit.oLanguage ); + + if ( oLanguage.sUrl ) { + // Get the language definitions from a file + $.ajax( { + dataType: 'json', + url: oLanguage.sUrl, + success: function ( json ) { + _fnCamelToHungarian( defaults.oLanguage, json ); + $.extend( true, oLanguage, json, oSettings.oInit.oLanguage ); + + _fnCallbackFire( oSettings, null, 'i18n', [oSettings], true); + _fnInitialise( oSettings ); + }, + error: function () { + // Error occurred loading language file + _fnLog( oSettings, 0, 'i18n file loading error', 21 ); + + // Continue on as best we can + _fnInitialise( oSettings ); + } + } ); + } + else { + _fnCallbackFire( oSettings, null, 'i18n', [oSettings]); + _fnInitialise( oSettings ); + } + } ); + _that = null; + return this; + }; + + + + /** + * DataTables extensions + * + * This namespace acts as a collection area for plug-ins that can be used to + * extend DataTables capabilities. Indeed many of the build in methods + * use this method to provide their own capabilities (sorting methods for + * example). + * + * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy + * reasons + * + * @namespace + */ + DataTable.ext = _ext = { + /** + * Buttons. For use with the Buttons extension for DataTables. This is + * defined here so other extensions can define buttons regardless of load + * order. It is _not_ used by DataTables core. + * + * @type object + * @default {} + */ + buttons: {}, + + + /** + * Element class names + * + * @type object + * @default {} + */ + classes: {}, + + + /** + * DataTables build type (expanded by the download builder) + * + * @type string + */ + builder: "-source-", + + + /** + * Error reporting. + * + * How should DataTables report an error. Can take the value 'alert', + * 'throw', 'none' or a function. + * + * @type string|function + * @default alert + */ + errMode: "alert", + + + /** + * Legacy so v1 plug-ins don't throw js errors on load + */ + feature: [], + + /** + * Feature plug-ins. + * + * This is an object of callbacks which provide the features for DataTables + * to be initialised via the `layout` option. + */ + features: {}, + + + /** + * Row searching. + * + * This method of searching is complimentary to the default type based + * searching, and a lot more comprehensive as it allows you complete control + * over the searching logic. Each element in this array is a function + * (parameters described below) that is called for every row in the table, + * and your logic decides if it should be included in the searching data set + * or not. + * + * Searching functions have the following input parameters: + * + * 1. `{object}` DataTables settings object: see + * {@link DataTable.models.oSettings} + * 2. `{array|object}` Data for the row to be processed (same as the + * original format that was passed in as the data source, or an array + * from a DOM data source + * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which + * can be useful to retrieve the `TR` element if you need DOM interaction. + * + * And the following return is expected: + * + * * {boolean} Include the row in the searched result set (true) or not + * (false) + * + * Note that as with the main search ability in DataTables, technically this + * is "filtering", since it is subtractive. However, for consistency in + * naming we call it searching here. + * + * @type array + * @default [] + * + * @example + * // The following example shows custom search being applied to the + * // fourth column (i.e. the data[3] index) based on two input values + * // from the end-user, matching the data in a certain range. + * $.fn.dataTable.ext.search.push( + * function( settings, data, dataIndex ) { + * var min = document.getElementById('min').value * 1; + * var max = document.getElementById('max').value * 1; + * var version = data[3] == "-" ? 0 : data[3]*1; + * + * if ( min == "" && max == "" ) { + * return true; + * } + * else if ( min == "" && version < max ) { + * return true; + * } + * else if ( min < version && "" == max ) { + * return true; + * } + * else if ( min < version && version < max ) { + * return true; + * } + * return false; + * } + * ); + */ + search: [], + + + /** + * Selector extensions + * + * The `selector` option can be used to extend the options available for the + * selector modifier options (`selector-modifier` object data type) that + * each of the three built in selector types offer (row, column and cell + + * their plural counterparts). For example the Select extension uses this + * mechanism to provide an option to select only rows, columns and cells + * that have been marked as selected by the end user (`{selected: true}`), + * which can be used in conjunction with the existing built in selector + * options. + * + * Each property is an array to which functions can be pushed. The functions + * take three attributes: + * + * * Settings object for the host table + * * Options object (`selector-modifier` object type) + * * Array of selected item indexes + * + * The return is an array of the resulting item indexes after the custom + * selector has been applied. + * + * @type object + */ + selector: { + cell: [], + column: [], + row: [] + }, + + + /** + * Legacy configuration options. Enable and disable legacy options that + * are available in DataTables. + * + * @type object + */ + legacy: { + /** + * Enable / disable DataTables 1.9 compatible server-side processing + * requests + * + * @type boolean + * @default null + */ + ajax: null + }, + + + /** + * Pagination plug-in methods. + * + * Each entry in this object is a function and defines which buttons should + * be shown by the pagination rendering method that is used for the table: + * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the + * buttons are displayed in the document, while the functions here tell it + * what buttons to display. This is done by returning an array of button + * descriptions (what each button will do). + * + * Pagination types (the four built in options and any additional plug-in + * options defined here) can be used through the `paginationType` + * initialisation parameter. + * + * The functions defined take two parameters: + * + * 1. `{int} page` The current page index + * 2. `{int} pages` The number of pages in the table + * + * Each function is expected to return an array where each element of the + * array can be one of: + * + * * `first` - Jump to first page when activated + * * `last` - Jump to last page when activated + * * `previous` - Show previous page when activated + * * `next` - Show next page when activated + * * `{int}` - Show page of the index given + * * `{array}` - A nested array containing the above elements to add a + * containing 'DIV' element (might be useful for styling). + * + * Note that DataTables v1.9- used this object slightly differently whereby + * an object with two functions would be defined for each plug-in. That + * ability is still supported by DataTables 1.10+ to provide backwards + * compatibility, but this option of use is now decremented and no longer + * documented in DataTables 1.10+. + * + * @type object + * @default {} + * + * @example + * // Show previous, next and current page buttons only + * $.fn.dataTableExt.oPagination.current = function ( page, pages ) { + * return [ 'previous', page, 'next' ]; + * }; + */ + pager: {}, + + + renderer: { + pageButton: {}, + header: {} + }, + + + /** + * Ordering plug-ins - custom data source + * + * The extension options for ordering of data available here is complimentary + * to the default type based ordering that DataTables typically uses. It + * allows much greater control over the the data that is being used to + * order a column, but is necessarily therefore more complex. + * + * This type of ordering is useful if you want to do ordering based on data + * live from the DOM (for example the contents of an 'input' element) rather + * than just the static string that DataTables knows of. + * + * The way these plug-ins work is that you create an array of the values you + * wish to be ordering for the column in question and then return that + * array. The data in the array much be in the index order of the rows in + * the table (not the currently ordering order!). Which order data gathering + * function is run here depends on the `dt-init columns.orderDataType` + * parameter that is used for the column (if any). + * + * The functions defined take two parameters: + * + * 1. `{object}` DataTables settings object: see + * {@link DataTable.models.oSettings} + * 2. `{int}` Target column index + * + * Each function is expected to return an array: + * + * * `{array}` Data for the column to be ordering upon + * + * @type array + * + * @example + * // Ordering using `input` node values + * $.fn.dataTable.ext.order['dom-text'] = function ( settings, col ) + * { + * return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { + * return $('input', td).val(); + * } ); + * } + */ + order: {}, + + + /** + * Type based plug-ins. + * + * Each column in DataTables has a type assigned to it, either by automatic + * detection or by direct assignment using the `type` option for the column. + * The type of a column will effect how it is ordering and search (plug-ins + * can also make use of the column type if required). + * + * @namespace + */ + type: { + /** + * Automatic column class assignment + */ + className: {}, + + /** + * Type detection functions. + * + * The functions defined in this object are used to automatically detect + * a column's type, making initialisation of DataTables super easy, even + * when complex data is in the table. + * + * The functions defined take two parameters: + * + * 1. `{*}` Data from the column cell to be analysed + * 2. `{settings}` DataTables settings object. This can be used to + * perform context specific type detection - for example detection + * based on language settings such as using a comma for a decimal + * place. Generally speaking the options from the settings will not + * be required + * + * Each function is expected to return: + * + * * `{string|null}` Data type detected, or null if unknown (and thus + * pass it on to the other type detection functions. + * + * @type array + * + * @example + * // Currency type detection plug-in: + * $.fn.dataTable.ext.type.detect.push( + * function ( data, settings ) { + * // Check the numeric part + * if ( ! data.substring(1).match(/[0-9]/) ) { + * return null; + * } + * + * // Check prefixed by currency + * if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) { + * return 'currency'; + * } + * return null; + * } + * ); + */ + detect: [], + + /** + * Automatic renderer assignment + */ + render: {}, + + + /** + * Type based search formatting. + * + * The type based searching functions can be used to pre-format the + * data to be search on. For example, it can be used to strip HTML + * tags or to de-format telephone numbers for numeric only searching. + * + * Note that is a search is not defined for a column of a given type, + * no search formatting will be performed. + * + * Pre-processing of searching data plug-ins - When you assign the sType + * for a column (or have it automatically detected for you by DataTables + * or a type detection plug-in), you will typically be using this for + * custom sorting, but it can also be used to provide custom searching + * by allowing you to pre-processing the data and returning the data in + * the format that should be searched upon. This is done by adding + * functions this object with a parameter name which matches the sType + * for that target column. This is the corollary of afnSortData + * for searching data. + * + * The functions defined take a single parameter: + * + * 1. `{*}` Data from the column cell to be prepared for searching + * + * Each function is expected to return: + * + * * `{string|null}` Formatted string that will be used for the searching. + * + * @type object + * @default {} + * + * @example + * $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) { + * return d.replace(/\n/g," ").replace( /<.*?>/g, "" ); + * } + */ + search: {}, + + + /** + * Type based ordering. + * + * The column type tells DataTables what ordering to apply to the table + * when a column is sorted upon. The order for each type that is defined, + * is defined by the functions available in this object. + * + * Each ordering option can be described by three properties added to + * this object: + * + * * `{type}-pre` - Pre-formatting function + * * `{type}-asc` - Ascending order function + * * `{type}-desc` - Descending order function + * + * All three can be used together, only `{type}-pre` or only + * `{type}-asc` and `{type}-desc` together. It is generally recommended + * that only `{type}-pre` is used, as this provides the optimal + * implementation in terms of speed, although the others are provided + * for compatibility with existing Javascript sort functions. + * + * `{type}-pre`: Functions defined take a single parameter: + * + * 1. `{*}` Data from the column cell to be prepared for ordering + * + * And return: + * + * * `{*}` Data to be sorted upon + * + * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort + * functions, taking two parameters: + * + * 1. `{*}` Data to compare to the second parameter + * 2. `{*}` Data to compare to the first parameter + * + * And returning: + * + * * `{*}` Ordering match: <0 if first parameter should be sorted lower + * than the second parameter, ===0 if the two parameters are equal and + * >0 if the first parameter should be sorted height than the second + * parameter. + * + * @type object + * @default {} + * + * @example + * // Numeric ordering of formatted numbers with a pre-formatter + * $.extend( $.fn.dataTable.ext.type.order, { + * "string-pre": function(x) { + * a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" ); + * return parseFloat( a ); + * } + * } ); + * + * @example + * // Case-sensitive string ordering, with no pre-formatting method + * $.extend( $.fn.dataTable.ext.order, { + * "string-case-asc": function(x,y) { + * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + * }, + * "string-case-desc": function(x,y) { + * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + * } + * } ); + */ + order: {} + }, + + /** + * Unique DataTables instance counter + * + * @type int + * @private + */ + _unique: 0, + + + // + // Depreciated + // The following properties are retained for backwards compatibility only. + // The should not be used in new projects and will be removed in a future + // version + // + + /** + * Version check function. + * @type function + * @depreciated Since 1.10 + */ + fnVersionCheck: DataTable.fnVersionCheck, + + + /** + * Index for what 'this' index API functions should use + * @type int + * @deprecated Since v1.10 + */ + iApiIndex: 0, + + + /** + * Software version + * @type string + * @deprecated Since v1.10 + */ + sVersion: DataTable.version + }; + + + // + // Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts + // + $.extend( _ext, { + afnFiltering: _ext.search, + aTypes: _ext.type.detect, + ofnSearch: _ext.type.search, + oSort: _ext.type.order, + afnSortData: _ext.order, + aoFeatures: _ext.feature, + oStdClasses: _ext.classes, + oPagination: _ext.pager + } ); + + + $.extend( DataTable.ext.classes, { + container: 'dt-container', + empty: { + row: 'dt-empty' + }, + info: { + container: 'dt-info' + }, + layout: { + row: 'dt-layout-row', + cell: 'dt-layout-cell', + tableRow: 'dt-layout-table', + tableCell: '', + start: 'dt-layout-start', + end: 'dt-layout-end', + full: 'dt-layout-full' + }, + length: { + container: 'dt-length', + select: 'dt-input' + }, + order: { + canAsc: 'dt-orderable-asc', + canDesc: 'dt-orderable-desc', + isAsc: 'dt-ordering-asc', + isDesc: 'dt-ordering-desc', + none: 'dt-orderable-none', + position: 'sorting_' + }, + processing: { + container: 'dt-processing' + }, + scrolling: { + body: 'dt-scroll-body', + container: 'dt-scroll', + footer: { + self: 'dt-scroll-foot', + inner: 'dt-scroll-footInner' + }, + header: { + self: 'dt-scroll-head', + inner: 'dt-scroll-headInner' + } + }, + search: { + container: 'dt-search', + input: 'dt-input' + }, + table: 'dataTable', + tbody: { + cell: '', + row: '' + }, + thead: { + cell: '', + row: '' + }, + tfoot: { + cell: '', + row: '' + }, + paging: { + active: 'current', + button: 'dt-paging-button', + container: 'dt-paging', + disabled: 'disabled' + } + } ); + + + /* + * It is useful to have variables which are scoped locally so only the + * DataTables functions can access them and they don't leak into global space. + * At the same time these functions are often useful over multiple files in the + * core and API, so we list, or at least document, all variables which are used + * by DataTables as private variables here. This also ensures that there is no + * clashing of variable names and that they can easily referenced for reuse. + */ + + + // Defined else where + // _selector_run + // _selector_opts + // _selector_row_indexes + + var _ext; // DataTable.ext + var _Api; // DataTable.Api + var _api_register; // DataTable.Api.register + var _api_registerPlural; // DataTable.Api.registerPlural + + var _re_dic = {}; + var _re_new_lines = /[\r\n\u2028]/g; + var _re_html = /<([^>]*>)/g; + var _max_str_len = Math.pow(2, 28); + + // This is not strict ISO8601 - Date.parse() is quite lax, although + // implementations differ between browsers. + var _re_date = /^\d{2,4}[./-]\d{1,2}[./-]\d{1,2}([T ]{1}\d{1,2}[:.]\d{2}([.:]\d{2})?)?$/; + + // Escape regular expression special characters + var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' ); + + // https://en.wikipedia.org/wiki/Foreign_exchange_market + // - \u20BD - Russian ruble. + // - \u20a9 - South Korean Won + // - \u20BA - Turkish Lira + // - \u20B9 - Indian Rupee + // - R - Brazil (R$) and South Africa + // - fr - Swiss Franc + // - kr - Swedish krona, Norwegian krone and Danish krone + // - \u2009 is thin space and \u202F is narrow no-break space, both used in many + // - Ƀ - Bitcoin + // - Ξ - Ethereum + // standards as thousands separators. + var _re_formatted_numeric = /['\u00A0,$£€¥%\u2009\u202F\u20BD\u20a9\u20BArfkɃΞ]/gi; + + + var _empty = function ( d ) { + return !d || d === true || d === '-' ? true : false; + }; + + + var _intVal = function ( s ) { + var integer = parseInt( s, 10 ); + return !isNaN(integer) && isFinite(s) ? integer : null; + }; + + // Convert from a formatted number with characters other than `.` as the + // decimal place, to a Javascript number + var _numToDecimal = function ( num, decimalPoint ) { + // Cache created regular expressions for speed as this function is called often + if ( ! _re_dic[ decimalPoint ] ) { + _re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' ); + } + return typeof num === 'string' && decimalPoint !== '.' ? + num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) : + num; + }; + + + var _isNumber = function ( d, decimalPoint, formatted, allowEmpty ) { + var type = typeof d; + var strType = type === 'string'; + + if ( type === 'number' || type === 'bigint') { + return true; + } + + // If empty return immediately so there must be a number if it is a + // formatted string (this stops the string "k", or "kr", etc being detected + // as a formatted number for currency + if ( allowEmpty && _empty( d ) ) { + return true; + } + + if ( decimalPoint && strType ) { + d = _numToDecimal( d, decimalPoint ); + } + + if ( formatted && strType ) { + d = d.replace( _re_formatted_numeric, '' ); + } + + return !isNaN( parseFloat(d) ) && isFinite( d ); + }; + + + // A string without HTML in it can be considered to be HTML still + var _isHtml = function ( d ) { + return _empty( d ) || typeof d === 'string'; + }; + + // Is a string a number surrounded by HTML? + var _htmlNumeric = function ( d, decimalPoint, formatted, allowEmpty ) { + if ( allowEmpty && _empty( d ) ) { + return true; + } + + // input and select strings mean that this isn't just a number + if (typeof d === 'string' && d.match(/<(input|select)/i)) { + return null; + } + + var html = _isHtml( d ); + return ! html ? + null : + _isNumber( _stripHtml( d ), decimalPoint, formatted, allowEmpty ) ? + true : + null; + }; + + + var _pluck = function ( a, prop, prop2 ) { + var out = []; + var i=0, ien=a.length; + + // Could have the test in the loop for slightly smaller code, but speed + // is essential here + if ( prop2 !== undefined ) { + for ( ; i _max_str_len) { + throw new Error('Exceeded max str len'); + } + + var previous; + + input = input.replace(_re_html, ''); // Complete tags + + // Safety for incomplete script tag - use do / while to ensure that + // we get all instances + do { + previous = input; + input = input.replace(/ + + + + + + +
+
+ +

Loading..

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

Enter an Artist

+
+ + +
+
+ +
+
+ + + + Search + +
+ +
+
+
+
+ + + + + + + + + + + + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/python/utils/__init__.py b/python/utils/__init__.py index 42b1ba6..9c91bd5 100644 --- a/python/utils/__init__.py +++ b/python/utils/__init__.py @@ -1,2 +1,4 @@ +from . import database from . import download +from . import psqldb from . import yt_dlp_logger diff --git a/python/utils/archive/sqldb.py b/python/utils/archive/sqldb.py new file mode 100644 index 0000000..142795f --- /dev/null +++ b/python/utils/archive/sqldb.py @@ -0,0 +1,382 @@ +from __future__ import annotations + +import sqlite3 +from contextlib import contextmanager +from typing import Any, Dict, Iterable, List, Optional, Tuple, Union + +# --------------------------------------------------------------------------- # +# Variables +# --------------------------------------------------------------------------- # +DB_PATH = {'memory': ":memory:", "file": ""} + +# --------------------------------------------------------------------------- # +# Helper type aliases +# --------------------------------------------------------------------------- # +Row = Dict[str, Any] +# A column description is: (name, type, optional constraints) +ColumnDef = Tuple[str, str, str] # name, type, constraints (empty if none) + + +class SqlDb: + """ + Thin wrapper around sqlite3 that exposes CRUD helpers for arbitrary tables. + """ + + def __init__(self, db_path: str = ":memory:") -> None: + """ + Open a connection to the SQLite database. + + Parameters + ---------- + db_path : str + Path to the database file. Use ':memory:' for an in‑memory DB. + """ + self.db_path = db_path + self.conn = sqlite3.connect(self.db_path) + # Use sqlite.Row so that we can return rows as dictionaries + self.conn.row_factory = sqlite3.Row + self.cursor = self.conn.cursor() + + # ----------------------------------------------------------------------- # + # Context‑manager support + # ----------------------------------------------------------------------- # + def __enter__(self) -> "SqlDb": + return self + + def __exit__(self, exc_type, exc_val, exc_tb) -> None: + self.close() + + def close(self) -> None: + """Close the database connection.""" + self.cursor.close() + self.conn.close() + + # ----------------------------------------------------------------------- # + # Table creation + # ----------------------------------------------------------------------- # + def create_table( + self, + table: str, + columns: Iterable[ColumnDef], + *, + primary_key: Optional[str] = None, + ) -> None: + """ + Create a table with the given columns. + + Parameters + ---------- + table : str + Table name. + columns : iterable of ColumnDef + Each item is a tuple: (column_name, sql_type, constraints) + Example: ("name", "TEXT", "NOT NULL") + primary_key : str | None + Name of the column that should be the PRIMARY KEY. + If omitted, *no* primary key is created automatically. + """ + col_defs: List[str] = [] + for name, col_type, constraints in columns: + if constraints: + col_defs.append(f"{name} {col_type} {constraints}") + else: + col_defs.append(f"{name} {col_type}") + + if primary_key: + # SQLite allows only one PRIMARY KEY per table, so we make sure + # that the PK column is part of the definition. + # We will just add "PRIMARY KEY" to the column definition. + pk_index = next( + (i for i, col in enumerate(col_defs) if col.startswith(primary_key)), + None, + ) + if pk_index is not None: + col_defs[pk_index] = f"{col_defs[pk_index]} PRIMARY KEY" + else: + # If the PK column wasn't part of the supplied list, + # we add a separate primary key constraint. + col_defs.append(f"PRIMARY KEY ({primary_key})") + + sql = f"CREATE TABLE IF NOT EXISTS {table} ({', '.join(col_defs)});" + self.cursor.execute(sql) + self.conn.commit() + + # ----------------------------------------------------------------------- # + # Generic CRUD helpers + # ----------------------------------------------------------------------- # + def _dict_to_columns_and_placeholders( + self, data: Dict[str, Any] + ) -> Tuple[str, str, Tuple[Any, ...]]: + """ + Convert a dict into a comma‑separated list of columns, + a list of '?' placeholders and a tuple of values. + """ + columns = ", ".join(data.keys()) + placeholders = ", ".join("?" for _ in data) + values = tuple(data.values()) + return columns, placeholders, values + + def insert( + self, table: str, data: Dict[str, Any] + ) -> int: + """ + Insert a single row. + + Parameters + ---------- + table : str + Table name. + data : dict + Column/value mapping. + + Returns + ------- + int + The lastrowid of the inserted row. + """ + cols, phs, vals = self._dict_to_columns_and_placeholders(data) + sql = f"INSERT INTO {table} ({cols}) VALUES ({phs})" + self.cursor.execute(sql, vals) + self.conn.commit() + return self.cursor.lastrowid + + def insert_many( + self, table: str, rows: Iterable[Dict[str, Any]] + ) -> List[int]: + """ + Insert many rows at once. + + Parameters + ---------- + table : str + Table name. + rows : iterable of dict + Each dict represents a row to insert. + + Returns + ------- + list of int + List of lastrowid values for each inserted row. + """ + # All rows must share the same keys + rows = list(rows) + if not rows: + return [] + + cols, phs, _ = self._dict_to_columns_and_placeholders(rows[0]) + sql = f"INSERT INTO {table} ({cols}) VALUES ({phs})" + + # Build a list of tuples for the values + values = [tuple(row[col] for col in cols.split(", ")) for row in rows] + self.cursor.executemany(sql, values) + self.conn.commit() + + # SQLite gives only the last row id; we approximate + last_id = self.cursor.lastrowid + # For deterministic behaviour we will simply return the last id for each row. + return [last_id - len(rows) + i + 1 for i in range(len(rows))] + + def get( + self, + table: str, + pk: str, + pk_value: Any, + *, + columns: Optional[List[str]] = None, + ) -> Optional[Row]: + """ + Retrieve a single row by primary key. + + Parameters + ---------- + table : str + Table name. + pk : str + Name of the primary‑key column. + pk_value : any + Value of the primary key. + columns : list | None + Columns to retrieve. If None, all columns are returned. + + Returns + ------- + dict or None + Row as a dict, or None if not found. + """ + cols = ", ".join(columns) if columns else "*" + sql = f"SELECT {cols} FROM {table} WHERE {pk} = ?" + self.cursor.execute(sql, (pk_value,)) + row = self.cursor.fetchone() + return dict(row) if row else None + + def get_all( + self, + table: str, + *, + columns: Optional[List[str]] = None, + where: Optional[str] = None, + where_args: Optional[Iterable[Any]] = None, + order_by: Optional[str] = None, + limit: Optional[int] = None, + ) -> List[Row]: + """ + Retrieve all rows, optionally filtered/sorted/paginated. + + Parameters + ---------- + table : str + Table name. + columns : list | None + Columns to fetch. If None, all columns are returned. + where : str | None + Optional WHERE clause (without the word WHERE). + where_args : iterable | None + Values for the WHERE clause placeholders. + order_by : str | None + ORDER BY clause (without the word ORDER BY). + limit : int | None + LIMIT clause. + + Returns + ------- + list of dict + List of rows as dictionaries. + """ + cols = ", ".join(columns) if columns else "*" + sql = f"SELECT {cols} FROM {table}" + args: List[Any] = [] + + if where: + sql += f" WHERE {where}" + if where_args: + args.extend(where_args) + + if order_by: + sql += f" ORDER BY {order_by}" + + if limit is not None: + sql += " LIMIT ?" + args.append(limit) + + self.cursor.execute(sql, tuple(args)) + rows = self.cursor.fetchall() + return [dict(row) for row in rows] + + def update( + self, + table: str, + pk: str, + pk_value: Any, + data: Dict[str, Any], + ) -> bool: + """ + Update a row identified by its primary key. + + Parameters + ---------- + table : str + Table name. + pk : str + Primary‑key column name. + pk_value : any + Value of the primary key. + data : dict + Column/value pairs to update. + + Returns + ------- + bool + True if a row was updated, False otherwise. + """ + if not data: + return False + + set_clause = ", ".join(f"{col} = ?" for col in data) + vals = tuple(data.values()) + (pk_value,) + sql = f"UPDATE {table} SET {set_clause} WHERE {pk} = ?" + self.cursor.execute(sql, vals) + self.conn.commit() + return self.cursor.rowcount > 0 + + def delete(self, table: str, pk: str, pk_value: Any) -> bool: + """ + Delete a row by primary key. + + Parameters + ---------- + table : str + Table name. + pk : str + Primary‑key column name. + pk_value : any + Value of the primary key. + + Returns + ------- + bool + True if a row was deleted, False otherwise. + """ + sql = f"DELETE FROM {table} WHERE {pk} = ?" + self.cursor.execute(sql, (pk_value,)) + self.conn.commit() + return self.cursor.rowcount > 0 +# +# # --------------------------------------------------------------------------- # +# # Example usage +# # --------------------------------------------------------------------------- # +# if __name__ == "__main__": +# # Using an in‑memory database for demonstration +# with GenericSQLiteDB(":memory:") as db: +# # Define two tables of different shapes +# user_columns = [ +# ("id", "INTEGER", ""), # will become PRIMARY KEY via parameter +# ("name", "TEXT", "NOT NULL"), +# ("email", "TEXT", "UNIQUE NOT NULL"), +# ("created_at", "TEXT", ""), +# ] +# +# product_columns = [ +# ("product_id", "INTEGER", ""), +# ("name", "TEXT", "NOT NULL"), +# ("price", "REAL", "NOT NULL"), +# ("stock", "INTEGER", ""), +# ] +# +# # Create tables +# db.create_table("users", user_columns, primary_key="id") +# db.create_table("products", product_columns, primary_key="product_id") +# +# # Insert a user +# user_id = db.insert( +# "users", +# {"id": 1, "name": "Alice", "email": "alice@example.com", "created_at": "2024‑01‑01"}, +# ) +# print(f"Inserted user id={user_id}") +# +# # Insert multiple products +# prod_ids = db.insert_many( +# "products", +# [ +# {"product_id": 101, "name": "Gizmo", "price": 19.99, "stock": 50}, +# {"product_id": 102, "name": "Widget", "price": 9.49, "stock": 200}, +# ], +# ) +# print(f"Inserted product ids={prod_ids}") +# +# # Retrieve a single user +# user = db.get("users", "id", user_id) +# print("Fetched user:", user) +# +# # Update the user's email +# db.update("users", "id", user_id, {"email": "alice@newdomain.com"}) +# print("Updated user:", db.get("users", "id", user_id)) +# +# # List all products that are in stock > 10 +# print( +# "Products in stock > 10:", +# db.get_all("products", where="stock > ?", where_args=(10,)), +# ) +# +# # Delete the user +# db.delete("users", "id", user_id) +# print("User after delete:", db.get("users", "id", user_id)) diff --git a/python/utils/archive/user_sqlite.py b/python/utils/archive/user_sqlite.py new file mode 100644 index 0000000..69bbda0 --- /dev/null +++ b/python/utils/archive/user_sqlite.py @@ -0,0 +1,157 @@ +import sqlite3 +from typing import Any, Iterable, List, Tuple, Optional, Dict + + +class SQLiteDB: + """Thin wrapper around sqlite3 that exposes CRUD helpers.""" + + def __init__(self, db_path: str = ":memory:") -> None: + """ + Open a connection to the SQLite database. + + Parameters + ---------- + db_path : str + Path to the database file. Use ':memory:' for an in‑memory DB. + """ + self.db_path = db_path + self.conn: sqlite3.Connection = sqlite3.connect(self.db_path) + # Row factory makes rows behave like dictionaries + self.conn.row_factory = sqlite3.Row + self.cursor: sqlite3.Cursor = self.conn.cursor() + + # ------------------------------------------------------------------ + # Table helpers + # ------------------------------------------------------------------ + def create_users_table(self) -> None: + """ + Create a simple 'users' table if it does not exist. + + Table schema: + id INTEGER PRIMARY KEY AUTOINCREMENT + name TEXT NOT NULL + age INTEGER + """ + sql = """ + CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + age INTEGER + ); + """ + self.cursor.execute(sql) + self.conn.commit() + + # ------------------------------------------------------------------ + # CRUD + # ------------------------------------------------------------------ + def insert_user(self, name: str, age: Optional[int] = None) -> int: + """ + Insert a new user. + + Returns + ------- + int + The newly created row id. + """ + sql = "INSERT INTO users (name, age) VALUES (?, ?)" + self.cursor.execute(sql, (name, age)) + self.conn.commit() + return self.cursor.lastrowid + + def get_user(self, user_id: int) -> Optional[Dict[str, Any]]: + """ + Retrieve a single user by id. + + Returns + ------- + dict or None + Row as a dictionary if found, otherwise None. + """ + sql = "SELECT * FROM users WHERE id = ?" + self.cursor.execute(sql, (user_id,)) + row = self.cursor.fetchone() + return dict(row) if row else None + + def get_all_users(self) -> List[Dict[str, Any]]: + """ + Retrieve all users. + + Returns + ------- + list of dict + All rows as dictionaries. + """ + sql = "SELECT * FROM users" + self.cursor.execute(sql) + rows = self.cursor.fetchall() + return [dict(row) for row in rows] + + def update_user(self, user_id: int, name: Optional[str] = None, + age: Optional[int] = None) -> bool: + """ + Update a user's name and/or age. + + Parameters + ---------- + user_id : int + The id of the user to update. + name : str | None + New name (or None to leave unchanged). + age : int | None + New age (or None to leave unchanged). + + Returns + ------- + bool + True if a row was updated, False otherwise. + """ + # Build dynamic SET clause + fields: List[str] = [] + values: List[Any] = [] + + if name is not None: + fields.append("name = ?") + values.append(name) + if age is not None: + fields.append("age = ?") + values.append(age) + + if not fields: + # Nothing to update + return False + + values.append(user_id) + sql = f"UPDATE users SET {', '.join(fields)} WHERE id = ?" + self.cursor.execute(sql, tuple(values)) + self.conn.commit() + return self.cursor.rowcount > 0 + + def delete_user(self, user_id: int) -> bool: + """ + Delete a user by id. + + Returns + ------- + bool + True if a row was deleted, False otherwise. + """ + sql = "DELETE FROM users WHERE id = ?" + self.cursor.execute(sql, (user_id,)) + self.conn.commit() + return self.cursor.rowcount > 0 + + # ------------------------------------------------------------------ + # Utility + # ------------------------------------------------------------------ + def close(self) -> None: + """Close the database connection.""" + self.cursor.close() + self.conn.close() + + # Context manager support + def __enter__(self) -> "SQLiteDB": + return self + + def __exit__(self, exc_type, exc_val, exc_tb) -> None: + self.close() diff --git a/python/utils/database.py b/python/utils/database.py new file mode 100644 index 0000000..bfbf48e --- /dev/null +++ b/python/utils/database.py @@ -0,0 +1,9 @@ +from .psqldb import PSQLDB +from .settings import Settings as settings + +DB = PSQLDB( + host=settings.POSTGRES_HOST, + database=settings.POSTGRES_DB, + user=settings.POSTGRES_USER, + password=settings.POSTGRES_PASSWORD, +) diff --git a/python/utils/psqldb.py b/python/utils/psqldb.py new file mode 100644 index 0000000..c2e0802 --- /dev/null +++ b/python/utils/psqldb.py @@ -0,0 +1,414 @@ +from __future__ import annotations + +import os +import sys +from typing import Any, Dict, Iterable, List, Optional, Tuple + +import psycopg2 +import psycopg2.extras + + +# --------------------------------------------------------------------------- # +# Type aliases +# --------------------------------------------------------------------------- # +Row = Dict[str, Any] +ColumnDef = Tuple[str, str, str] # (name, type, constraints) + + +# --------------------------------------------------------------------------- # +# Helper class +# --------------------------------------------------------------------------- # +class PSQLDB: + """ + A thin wrapper around psycopg2 that provides generic CRUD helpers. + """ + + def __init__( + self, + *, + host: str = "localhost", + port: int = 5432, + database: str, + user: str, + password: str, + sslmode: str = "prefer", + autocommit: bool = True, + ) -> None: + """ + Open a connection to the PostgreSQL database. + + Parameters + ---------- + host : str + Database host. + port : int + Database port. + database : str + Database name. + user : str + Username. + password : str + Password. + sslmode : str + SSL mode (default: "prefer"). + autocommit : bool + If True, each statement is committed automatically. + """ + self.conn = psycopg2.connect( + host=host, + port=port, + dbname=database, + user=user, + password=password, + sslmode=sslmode, + ) + self.conn.autocommit = autocommit + self.cursor_factory = psycopg2.extras.RealDictCursor + self.cursor = self.conn.cursor(cursor_factory=self.cursor_factory) + + # --------------------------------------------------------------------- # + # Context manager support + # --------------------------------------------------------------------- # + def __enter__(self) -> "PSQLDB": + return self + + def __exit__(self, exc_type, exc, tb) -> None: + if exc_type: + self.conn.rollback() + else: + self.conn.commit() + self.cursor.close() + self.conn.close() + + def close(self) -> None: + """Explicitly close the underlying connection.""" + self.cursor.close() + self.conn.close() + + # --------------------------------------------------------------------- # + # Internal helpers + # --------------------------------------------------------------------- # + def _build_create_sql(self, table: str, columns: Iterable[ColumnDef], primary_key: Optional[str]) -> str: + parts = [] + for name, col_type, constraints in columns: + col_part = f"{name} {col_type}" + if constraints: + col_part += f" {constraints}" + parts.append(col_part) + + pk_clause = f", PRIMARY KEY ({primary_key})" if primary_key else "" + columns_sql = ", ".join(parts) + return f"CREATE TABLE IF NOT EXISTS {table} ({columns_sql}{pk_clause});" + + def _build_set_clause(self, data: Dict[str, Any]) -> Tuple[str, List[Any]]: + """ + Helper for UPDATE and INSERT. Returns a ``SET``‑style clause + and the corresponding values list. + + Example: data={'name':'bob', 'age':30} + → ("name = %s, age = %s", ['bob', 30]) + """ + if not data: + raise ValueError("data dictionary must contain at least one key") + + clause = ", ".join(f"{k} = %s" for k in data) + values = list(data.values()) + return clause, values + + # --------------------------------------------------------------------- # + # Schema helpers + # --------------------------------------------------------------------- # + def create_table( + self, + table: str, + columns: Iterable[ColumnDef], + primary_key: Optional[str] = None, + *, + if_not_exists: bool = True, + # You can add more constraints here – e.g. UNIQUE, CHECK, etc. + ) -> None: + """ + Create a new table with the supplied column set. + + Parameters + ---------- + table : str + Table name. + columns : iterable of (name, type, constraints) + Constraints are appended verbatim – e.g. "NOT NULL", "UNIQUE". + primary_key : str | None + Column name that should become the primary key. If None, no PK is added. + if_not_exists : bool + If True (default) the statement is `CREATE TABLE IF NOT EXISTS`. + """ + sql = self._build_create_sql(table, columns, primary_key) + if not if_not_exists: + sql = sql.replace("IF NOT EXISTS", "") + self.cursor.execute(sql) + + # --------------------------------------------------------------------- # + # CRUD helpers + # --------------------------------------------------------------------- # + def insert(self, table: str, data: Dict[str, Any]) -> int: + """ + Insert a single row and return the *generated* primary key + (if the table uses a `SERIAL`/`IDENTITY` PK). + If you supply the PK yourself, the returned value will just be that value. + + Parameters + ---------- + table : str + Table name. + data : dict + Column/value mapping. + + Returns + ------- + int + The value of the last inserted primary key. + """ + cols = ", ".join(data.keys()) + placeholders = ", ".join(f"%s" for _ in data) + values = list(data.values()) + + sql = f"INSERT INTO {table} ({cols}) VALUES ({placeholders}) RETURNING *;" + self.cursor.execute(sql, values) + row = self.cursor.fetchone() + # If you want *only* the PK you can change this to RETURNING id, etc. + return row[next(iter(row))] # first column value – usually the PK + + def insert_many(self, table: str, rows: Iterable[Dict[str, Any]], *, fetch_first: bool = False) -> List[int]: + """ + Bulk insert – very fast thanks to execute_values. + + Parameters + ---------- + table : str + Table name. + rows : iterable of dict + Each dict represents one row. + fetch_first : bool + If True, the first row’s PK will be returned as a list of one element. + Useful for a quick “INSERT … RETURNING …” when you only care about the first id. + + Returns + ------- + list[int] + List of primary‑key values of the inserted rows. + """ + if not rows: + return [] + + keys = rows[0].keys() + columns = ", ".join(keys) + values = [tuple(row[k] for k in keys) for row in rows] + placeholder = f"({', '.join(['%s'] * len(keys))})" + + sql = f"INSERT INTO {table} ({columns}) VALUES %s RETURNING *;" + psycopg2.extras.execute_values( + self.cursor, + sql, + values, + template=placeholder, + fetch=True, + ) + # Return the PK column of every inserted row (first column by convention) + return [r[next(iter(r))] for r in self.cursor.fetchall()] + + def get(self, table: str, pk_column: str, pk_value: Any, *, columns: Optional[List[str]] = None) -> Optional[Row]: + """ + Retrieve a single row by its primary key. + + Parameters + ---------- + table : str + Table name. + pk_column : str + Primary‑key column name. + pk_value : Any + Value of the primary key. + columns : list[str] | None + If supplied, only those columns will be selected. + + Returns + ------- + dict | None + The row as a dictionary, or None if not found. + """ + cols = ", ".join(columns) if columns else "*" + sql = f"SELECT {cols} FROM {table} WHERE {pk_column} = %s LIMIT 1;" + self.cursor.execute(sql, (pk_value,)) + return self.cursor.fetchone() + + def get_all( + self, + table: str, + *, + columns: Optional[List[str]] = None, + where: Optional[str] = None, + where_args: Optional[Iterable[Any]] = None, + order_by: Optional[str] = None, + limit: Optional[int] = None, + offset: Optional[int] = None, + ) -> List[Row]: + """ + Retrieve many rows with optional filtering, sorting and pagination. + + Parameters + ---------- + table : str + Table name. + columns : list[str] | None + List of columns to fetch. If None → SELECT *. + where : str | None + Raw `WHERE` clause *without* the leading `WHERE`. Use `%s` for placeholders. + where_args : iterable | None + Values that match the placeholders in `where`. + order_by : str | None + Raw `ORDER BY` clause (no leading `ORDER BY`). + limit : int | None + Max rows to return. + offset : int | None + Skip the first N rows. + + Returns + ------- + list[dict] + List of rows as dictionaries. + """ + cols = ", ".join(columns) if columns else "*" + sql = f"SELECT {cols} FROM {table}" + params: List[Any] = [] + + if where: + sql += f" WHERE {where}" + if where_args: + params.extend(where_args) + + if order_by: + sql += f" ORDER BY {order_by}" + + if limit is not None: + sql += " LIMIT %s" + params.append(limit) + + if offset is not None: + sql += " OFFSET %s" + params.append(offset) + + self.cursor.execute(sql, params) + return self.cursor.fetchall() + + def update(self, table: str, pk_column: str, pk_value: Any, data: Dict[str, Any]) -> bool: + """ + Update one row by its primary key. + + Parameters + ---------- + table : str + Table name. + pk_column : str + Primary‑key column name. + pk_value : Any + Primary‑key value. + data : dict + Column/value pairs to update. + + Returns + ------- + bool + True if a row was modified, False otherwise. + """ + if not data: + return False + + set_clause = ", ".join(f"{col} = %s" for col in data) + params = list(data.values()) + [pk_value] + sql = f"UPDATE {table} SET {set_clause} WHERE {pk_column} = %s;" + self.cursor.execute(sql, params) + return self.cursor.rowcount > 0 + + def delete(self, table: str, pk_column: str, pk_value: Any) -> bool: + """ + Delete a row by its primary key. + + Returns + ------- + bool + True if a row was deleted. + """ + sql = f"DELETE FROM {table} WHERE {pk_column} = %s;" + self.cursor.execute(sql, (pk_value,)) + return self.cursor.rowcount > 0 + +# +# # ----------------------------------------------------------------------- # +# # Demo usage +# # ----------------------------------------------------------------------- # +# def _demo(): +# db = os.getenv("POSTGRES_DB", "testdb") +# user = os.getenv("POSTGRES_USER", "postgres") +# pwd = os.getenv("POSTGRES_PASSWORD", "") +# host = os.getenv("POSTGRES_HOST", "localhost") +# port = int(os.getenv("POSTGRES_PORT", "5432")) +# +# with PostgreSQLDB( +# host=host, database=db, user=user, password=pwd, port=port +# ) as db: +# +# # 1. Create table +# db.create_table( +# "users", +# [ +# ("id", "SERIAL", ""), # Identity / auto‑increment +# ("username", "TEXT", "NOT NULL"), +# ("email", "TEXT", "UNIQUE"), +# ("age", "INTEGER", "CHECK (age >= 0)"), +# ], +# primary_key="id", +# ) +# +# # 2. Insert +# user_id = db.insert( +# "users", +# {"username": "alice", "email": "alice@example.com", "age": 25}, +# ) +# print(f"Inserted user id={user_id}") +# +# # 3. Bulk insert +# bulk_ids = db.insert_many( +# "users", +# [ +# {"username": "bob", "email": "bob@example.com", "age": 30}, +# {"username": "carol", "email": "carol@example.com", "age": 22}, +# ], +# ) +# print(f"Bulk inserted ids: {bulk_ids}") +# +# # 4. Get single +# user = db.get("users", "id", user_id) +# print("Fetched user:", user) +# +# # 5. Get many +# all_users = db.get_all( +# "users", +# where="age >= %s", +# where_args=[20], +# order_by="age DESC", +# limit=10, +# ) +# print("All users:", all_users) +# +# # 6. Update +# updated = db.update("users", "id", user_id, {"age": 26, "email": "alice26@example.com"}) +# print("Update status:", updated) +# +# # 7. Delete +# deleted = db.delete("users", "id", user_id) +# print("Deleted:", deleted) +# +# # ----------------------------------------------------------------------- # +# # Entry point for `python -m` usage +# # ----------------------------------------------------------------------- # +# if __name__ == "__main__": +# _demo() \ No newline at end of file diff --git a/python/utils/settings.py b/python/utils/settings.py new file mode 100644 index 0000000..ae7cd4e --- /dev/null +++ b/python/utils/settings.py @@ -0,0 +1,9 @@ +import os + + +class Settings(object): + POSTGRES_HOST = os.getenv("DB_HOST", "postgres") + POSTGRES_PORT = os.getenv("DB_PORT", 5432) + POSTGRES_DB = os.getenv("DB_NAME", "postgres") + POSTGRES_USER = os.getenv("DB_USER", "postgres") + POSTGRES_PASSWORD = os.getenv("DB_PASS", "password")