commit
b882b2e661
227 changed files with 64250 additions and 0 deletions
@ -0,0 +1,22 @@ |
|||||
|
FROM cstf2:latest |
||||
|
MAINTAINER "Gabriel Menessy" <gabriel.menessy@komm.one> |
||||
|
|
||||
|
ENV LANG C.UTF-8 |
||||
|
|
||||
|
ENV TZ=Europe/Berlin |
||||
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone |
||||
|
|
||||
|
RUN dpkg-reconfigure -f noninteractive tzdata |
||||
|
# |
||||
|
ADD containercontent / |
||||
|
|
||||
|
WORKDIR "/opt/chatbot_engine/" |
||||
|
# RUN ls -l |
||||
|
|
||||
|
# Server |
||||
|
EXPOSE 8001 |
||||
|
STOPSIGNAL SIGINT |
||||
|
ENTRYPOINT ["python3", "manage.py"] |
||||
|
CMD ["runserver", "0.0.0.0:8001"] |
||||
|
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,27 @@ |
|||||
|
from django.contrib import admin |
||||
|
from .models import Responce, Question, Question_Responce |
||||
|
# Register your models here. |
||||
|
|
||||
|
class QuestionAdmin(admin.ModelAdmin): |
||||
|
fieldsets = [ |
||||
|
(None, {'fields': ['session_id', 'question_text']}), |
||||
|
('Date information', {'fields': ['publi_date'], 'classes': ['collapse']}), |
||||
|
] |
||||
|
|
||||
|
|
||||
|
class ResponceAdmin(admin.ModelAdmin): |
||||
|
fieldsets = [ |
||||
|
(None, {'fields': ['session_id', 'responce_text']}), |
||||
|
('Date information', {'fields': ['publi_date'], 'classes': ['collapse']}), |
||||
|
] |
||||
|
|
||||
|
class Question_ResponceAdmin(admin.ModelAdmin): |
||||
|
fieldsets = [ |
||||
|
(None, {'fields': ['session_id', 'question_text', 'responce_text']}), |
||||
|
('Date information', {'fields': ['publi_date'], 'classes': ['collapse']}), |
||||
|
] |
||||
|
|
||||
|
|
||||
|
admin.site.register(Question, QuestionAdmin) |
||||
|
admin.site.register(Responce, ResponceAdmin) |
||||
|
admin.site.register(Question_Responce, Question_ResponceAdmin) |
@ -0,0 +1,5 @@ |
|||||
|
from django.apps import AppConfig |
||||
|
|
||||
|
|
||||
|
class chatbotConfig(AppConfig): |
||||
|
name = 'chatbot' |
@ -0,0 +1,59 @@ |
|||||
|
from django.http import JsonResponse |
||||
|
from django.template import loader |
||||
|
import json |
||||
|
from prodae import knn_ae as knn_ae |
||||
|
from time import gmtime, strftime |
||||
|
from chatbot.models import Question, Responce, Question_Responce |
||||
|
|
||||
|
from importlib import import_module |
||||
|
from django.conf import settings |
||||
|
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore |
||||
|
|
||||
|
|
||||
|
def ae(request): |
||||
|
if request.method == 'POST': |
||||
|
jsonData = json.loads(request.body.decode('utf-8')) |
||||
|
msg = jsonData["msg"] |
||||
|
userId = jsonData["userId"] |
||||
|
klass1 = knn_ae.klassifizieren(msg) |
||||
|
klass = klass1[0:2] |
||||
|
intent1 = klass1[0][0] |
||||
|
accurancy1 = klass1[0][1] |
||||
|
if len(klass1)>1: |
||||
|
intent2 = klass1[1][0] |
||||
|
accurancy2 = klass1[1][1] |
||||
|
else: |
||||
|
intent2 = 'Null' |
||||
|
accurancy2 = 'Null' |
||||
|
klass = str(klass) |
||||
|
intent1 = str(intent1) |
||||
|
accurancy1 = str(accurancy1) |
||||
|
intent2 = str(intent2) |
||||
|
accurancy2 = str(accurancy2) |
||||
|
res = knn_ae.antwort(msg, jsonData["userId"]) |
||||
|
time = strftime("%Y-%m-%d %H:%M:%S", gmtime()) |
||||
|
#s = request.session |
||||
|
s = SessionStore() |
||||
|
s.save() |
||||
|
sess_id = s.session_key |
||||
|
print(request.session.session_key) |
||||
|
quest = Question(session_id=userId, question_text=msg, publi_date=time) |
||||
|
quest.save() |
||||
|
resp = Responce(session_id=userId, responce_text=res, publi_date=time) |
||||
|
resp.save() |
||||
|
qr = Question_Responce(session_id=userId, question_text=msg, intent1=intent1, accurancy1=accurancy1, intent2=intent2, accurancy2=accurancy2, responce_text=res, publi_date=time) |
||||
|
qr.save() |
||||
|
return JsonResponse({ |
||||
|
"desc": "Success", |
||||
|
"klass": klass, |
||||
|
"intent1": intent1, |
||||
|
"accurancy1": accurancy1, |
||||
|
"intent2": intent2, |
||||
|
"accurancy2": accurancy2, |
||||
|
"ques": msg, |
||||
|
"res": res, |
||||
|
"user": userId, |
||||
|
"time": time |
||||
|
}) |
||||
|
else: |
||||
|
return JsonResponse({"desc": "Bad request"}, status=400) |
@ -0,0 +1,46 @@ |
|||||
|
# Generated by Django 3.1.5 on 2021-04-30 14:28 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
initial = True |
||||
|
|
||||
|
dependencies = [ |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='Question', |
||||
|
fields=[ |
||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('session_id', models.CharField(blank=True, max_length=200, null=True)), |
||||
|
('question_text', models.CharField(max_length=200)), |
||||
|
('publi_date', models.DateTimeField(verbose_name='date published')), |
||||
|
], |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='Question_Responce', |
||||
|
fields=[ |
||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('session_id', models.CharField(blank=True, max_length=200, null=True)), |
||||
|
('question_text', models.CharField(max_length=200)), |
||||
|
('intent1', models.CharField(max_length=200)), |
||||
|
('accurancy1', models.CharField(max_length=200)), |
||||
|
('intent2', models.CharField(max_length=200)), |
||||
|
('accurancy2', models.CharField(max_length=200)), |
||||
|
('responce_text', models.CharField(max_length=200)), |
||||
|
('publi_date', models.DateTimeField(verbose_name='date published')), |
||||
|
], |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='Responce', |
||||
|
fields=[ |
||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('session_id', models.CharField(blank=True, max_length=200, null=True)), |
||||
|
('responce_text', models.CharField(max_length=200)), |
||||
|
('publi_date', models.DateTimeField(verbose_name='date published')), |
||||
|
], |
||||
|
), |
||||
|
] |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,43 @@ |
|||||
|
from django.db import models |
||||
|
import datetime |
||||
|
from django.utils import timezone |
||||
|
# Create your models here. |
||||
|
#Nach Änderung von models dann delete datenbank und dann makemigrations chatbot und dann migrate |
||||
|
|
||||
|
class Question(models.Model): |
||||
|
session_id = models.CharField(max_length=200, blank=True, null=True) |
||||
|
question_text = models.CharField(max_length=200) |
||||
|
publi_date = models.DateTimeField('date published') |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.question_text |
||||
|
|
||||
|
def was_published_recently(self): |
||||
|
now = timezone.now() |
||||
|
return now - datetime.timedelta(days=1) <= self.publi_date <= now |
||||
|
|
||||
|
was_published_recently.admin_order_field = 'publi_date' |
||||
|
was_published_recently.boolean = True |
||||
|
was_published_recently.short_description = 'Published recently?' |
||||
|
|
||||
|
|
||||
|
class Responce(models.Model): |
||||
|
session_id = models.CharField(max_length=200, blank=True, null=True) |
||||
|
responce_text = models.CharField(max_length=200) |
||||
|
publi_date = models.DateTimeField('date published') |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.responce_text |
||||
|
|
||||
|
class Question_Responce(models.Model): |
||||
|
session_id = models.CharField(max_length=200, blank=True, null=True) |
||||
|
question_text = models.CharField(max_length=200) |
||||
|
intent1 = models.CharField(max_length=200) |
||||
|
accurancy1 = models.CharField(max_length=200) |
||||
|
intent2 = models.CharField(max_length=200) |
||||
|
accurancy2 = models.CharField(max_length=200) |
||||
|
responce_text = models.CharField(max_length=200) |
||||
|
publi_date = models.DateTimeField('date published') |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.question_text |
@ -0,0 +1,8 @@ |
|||||
|
from django.urls import path |
||||
|
from django.conf.urls import url |
||||
|
|
||||
|
from . import controller_ae |
||||
|
|
||||
|
urlpatterns = [ |
||||
|
path('/chatbot', controller_ae.ae) |
||||
|
] |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,132 @@ |
|||||
|
""" |
||||
|
Django settings for ortena_chatbot project. |
||||
|
|
||||
|
Generated by 'django-admin startproject' using Django 2.0.7. |
||||
|
|
||||
|
For more information on this file, see |
||||
|
https://docs.djangoproject.com/en/2.0/topics/settings/ |
||||
|
|
||||
|
For the full list of settings and their values, see |
||||
|
https://docs.djangoproject.com/en/2.0/ref/settings/ |
||||
|
""" |
||||
|
|
||||
|
import os |
||||
|
|
||||
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) |
||||
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
||||
|
|
||||
|
|
||||
|
# Quick-start development settings - unsuitable for production |
||||
|
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ |
||||
|
|
||||
|
# SECURITY WARNING: keep the secret key used in production secret! |
||||
|
SECRET_KEY = '-h)4epd%%i5h7j^q28(b3oezib!9z+lo19z(t_$y1*rbf!*@*2' |
||||
|
|
||||
|
# SECURITY WARNING: don't run with debug turned on in production! |
||||
|
DEBUG = True |
||||
|
|
||||
|
ALLOWED_HOSTS = ['k1z06s042.komm.one', '127.0.0.1', '0.0.0.0', '89.58.12.121','voicebot.digitalakademie-bw.de'] |
||||
|
|
||||
|
|
||||
|
# Application definition |
||||
|
|
||||
|
INSTALLED_APPS = [ |
||||
|
'django.contrib.admin', |
||||
|
'django.contrib.auth', |
||||
|
'django.contrib.contenttypes', |
||||
|
'django.contrib.sessions', |
||||
|
'django.contrib.messages', |
||||
|
'django.contrib.staticfiles', |
||||
|
'chatbot.apps.chatbotConfig', |
||||
|
] |
||||
|
|
||||
|
MIDDLEWARE = [ |
||||
|
'django.middleware.security.SecurityMiddleware', |
||||
|
'django.contrib.sessions.middleware.SessionMiddleware', |
||||
|
'django.middleware.common.CommonMiddleware', |
||||
|
#'django.middleware.csrf.CsrfViewMiddleware', |
||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware', |
||||
|
'django.contrib.messages.middleware.MessageMiddleware', |
||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware', |
||||
|
] |
||||
|
|
||||
|
ROOT_URLCONF = 'dialogAssistent.urls' |
||||
|
|
||||
|
TEMPLATES = [ |
||||
|
{ |
||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates', |
||||
|
'DIRS': [os.path.join(BASE_DIR, 'templates')] |
||||
|
, |
||||
|
'APP_DIRS': True, |
||||
|
'OPTIONS': { |
||||
|
'context_processors': [ |
||||
|
'django.template.context_processors.debug', |
||||
|
'django.template.context_processors.request', |
||||
|
'django.contrib.auth.context_processors.auth', |
||||
|
'django.contrib.messages.context_processors.messages', |
||||
|
], |
||||
|
}, |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
WSGI_APPLICATION = 'dialogAssistent.wsgi.application' |
||||
|
|
||||
|
|
||||
|
# Database |
||||
|
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases |
||||
|
|
||||
|
DATABASES = { |
||||
|
|
||||
|
|
||||
|
#'default': { |
||||
|
# 'ENGINE': 'django.db.backends.sqlite3', |
||||
|
# 'NAME': os.path.join('/opt/chatbot_engine/models/db/', 'db.sqlite3'), |
||||
|
# } |
||||
|
|
||||
|
'default': { |
||||
|
'ENGINE': 'django.db.backends.sqlite3', |
||||
|
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# Password validation |
||||
|
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators |
||||
|
|
||||
|
AUTH_PASSWORD_VALIDATORS = [ |
||||
|
{ |
||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', |
||||
|
}, |
||||
|
{ |
||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', |
||||
|
}, |
||||
|
{ |
||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', |
||||
|
}, |
||||
|
{ |
||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
|
||||
|
# Internationalization |
||||
|
# https://docs.djangoproject.com/en/2.0/topics/i18n/ |
||||
|
|
||||
|
LANGUAGE_CODE = 'en-us' |
||||
|
|
||||
|
TIME_ZONE = 'Europe/Berlin' |
||||
|
|
||||
|
USE_I18N = True |
||||
|
|
||||
|
USE_L10N = True |
||||
|
|
||||
|
USE_TZ = True |
||||
|
|
||||
|
|
||||
|
# Static files (CSS, JavaScript, Images) |
||||
|
# https://docs.djangoproject.com/en/2.0/howto/static-files/ |
||||
|
|
||||
|
STATIC_URL = '/static/' |
||||
|
STATICFILES_DIRS = [ |
||||
|
os.path.join(BASE_DIR, "static"), |
||||
|
'/opt/chatbot_engine/static', |
||||
|
] |
@ -0,0 +1,28 @@ |
|||||
|
"""fuehrungszeugnis_chatbot URL Configuration |
||||
|
|
||||
|
The `urlpatterns` list routes URLs to views. For more information please see: |
||||
|
https://docs.djangoproject.com/en/2.0/topics/http/urls/ |
||||
|
Examples: |
||||
|
Function views |
||||
|
1. Add an import: from my_app import views |
||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home') |
||||
|
Class-based views |
||||
|
1. Add an import: from other_app.views import Home |
||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') |
||||
|
Including another URLconf |
||||
|
1. Import the include() function: from django.urls import include, path |
||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) |
||||
|
""" |
||||
|
from django.contrib import admin |
||||
|
from django.urls import path, include,re_path |
||||
|
from . import views |
||||
|
|
||||
|
urlpatterns = [ |
||||
|
path('admin/', admin.site.urls), |
||||
|
path('chatbot/', views.index_ae), |
||||
|
path('Über/', views.ueber), |
||||
|
path('Kontakt/', views.kontakt), |
||||
|
path('chatbot/Über/', views.ueber), |
||||
|
path('chatbot/Kontakt/', views.kontakt), |
||||
|
path('chatbot', include("chatbot.urls")) |
||||
|
] |
@ -0,0 +1,57 @@ |
|||||
|
|
||||
|
#def editor(request): |
||||
|
#now = datetime.datetime.now() |
||||
|
#headers = request.headers |
||||
|
#print("headers", headers) |
||||
|
#request.headers['User-Agent'] |
||||
|
#return JsonResponse({"status": "Kommunikation ok!", "sucess": "true", "time": now}) |
||||
|
|
||||
|
|
||||
|
from django.http import HttpResponse |
||||
|
from django.template import loader |
||||
|
from django.http import JsonResponse |
||||
|
import datetime |
||||
|
import json |
||||
|
import importlib |
||||
|
from django.shortcuts import redirect |
||||
|
import os |
||||
|
import inspect |
||||
|
import re |
||||
|
import platform |
||||
|
from summarize import summarize |
||||
|
|
||||
|
def creation_date(path_to_file): |
||||
|
""" |
||||
|
Try to get the date that a file was created, falling back to when it was |
||||
|
last modified if that isn't possible. |
||||
|
See http://stackoverflow.com/a/39501288/1709587 for explanation. |
||||
|
""" |
||||
|
if platform.system() == 'Windows': |
||||
|
return datetime.datetime.fromtimestamp(os.path.getctime(path_to_file)) |
||||
|
else: |
||||
|
stat = os.stat(path_to_file) |
||||
|
try: |
||||
|
return datetime.datetime.fromtimestamp(stat.st_birthtime) |
||||
|
except AttributeError: |
||||
|
# We're probably on Linux. No easy way to get creation dates here, |
||||
|
# so we'll settle for when its content was last modified. |
||||
|
return datetime.datetime.fromtimestamp(stat.st_ctime) |
||||
|
|
||||
|
|
||||
|
|
||||
|
def index_ae(request, str='chatbot/chatbot'): |
||||
|
name= request.path |
||||
|
print(name) |
||||
|
template = loader.get_template('template_ae.html') |
||||
|
return HttpResponse(template.render({}, request)) |
||||
|
|
||||
|
|
||||
|
def ueber(request): |
||||
|
template = loader.get_template('Über.html') |
||||
|
return HttpResponse(template.render({}, request)) |
||||
|
|
||||
|
def kontakt(request): |
||||
|
template = loader.get_template('Kontakt.html') |
||||
|
return HttpResponse(template.render({}, request)) |
||||
|
|
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
""" |
||||
|
WSGI config for ortena project. |
||||
|
|
||||
|
It exposes the WSGI callable as a module-level variable named ``application``. |
||||
|
|
||||
|
For more information on this file, see |
||||
|
https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ |
||||
|
""" |
||||
|
|
||||
|
import os |
||||
|
|
||||
|
from django.core.wsgi import get_wsgi_application |
||||
|
|
||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dialogAssistent.settings") |
||||
|
|
||||
|
application = get_wsgi_application() |
@ -0,0 +1,21 @@ |
|||||
|
#!/usr/bin/env python |
||||
|
"""Django's command-line utility for administrative tasks.""" |
||||
|
import os |
||||
|
import sys |
||||
|
|
||||
|
|
||||
|
def main(): |
||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dialogAssistent.settings') |
||||
|
try: |
||||
|
from django.core.management import execute_from_command_line |
||||
|
except ImportError as exc: |
||||
|
raise ImportError( |
||||
|
"Couldn't import Django. Are you sure it's installed and " |
||||
|
"available on your PYTHONPATH environment variable? Did you " |
||||
|
"forget to activate a virtual environment?" |
||||
|
) from exc |
||||
|
execute_from_command_line(sys.argv) |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
main() |
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,2 @@ |
|||||
|
model_checkpoint_path: "C:/AE/fuehrerschein_voicebot_tflearn/fuehrerschein_voicebot/containercontent/opt/chatbot_engine/prodae/models/model.tflearn" |
||||
|
all_model_checkpoint_paths: "C:/AE/fuehrerschein_voicebot_tflearn/fuehrerschein_voicebot/containercontent/opt/chatbot_engine/prodae/models/model.tflearn" |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,249 @@ |
|||||
|
import nltk |
||||
|
from nltk.stem.snowball import GermanStemmer |
||||
|
stemmer = GermanStemmer() |
||||
|
|
||||
|
from nltk.corpus import stopwords |
||||
|
|
||||
|
import numpy as np |
||||
|
import tensorflow as tf |
||||
|
import tflearn |
||||
|
import random |
||||
|
|
||||
|
import os |
||||
|
import inspect |
||||
|
|
||||
|
def getPath(file): |
||||
|
path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) |
||||
|
path = os.path.join(path, file).replace("\\", "/") |
||||
|
return path |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
import json |
||||
|
|
||||
|
def getJsonPath(): |
||||
|
path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) |
||||
|
path = os.path.join(path, 'chat.json').replace("\\", "/") |
||||
|
return path |
||||
|
|
||||
|
|
||||
|
# importiere das Dialog-design |
||||
|
with open(getJsonPath(), encoding='UTF-8') as json_data: |
||||
|
dialogflow = json.load(json_data) |
||||
|
|
||||
|
words = [] |
||||
|
classes = [] |
||||
|
documents = [] |
||||
|
stop= stopwords.words('german') |
||||
|
ignore_words = ['?', '.', ','] + stop |
||||
|
# loop durch jeden Satz in unseren dialogflow und synonym |
||||
|
for dialog in dialogflow['dialogflow']: |
||||
|
for pattern in dialog['synonym']: |
||||
|
# Tokenisieren jedes Wort im Satz |
||||
|
w = nltk.word_tokenize(pattern) |
||||
|
# füge die zu unserer Wörterliste hinzu |
||||
|
words.extend(w) |
||||
|
# füge die zu Dokumenten in unserem Korpus hinzu |
||||
|
documents.append((w, dialog['intent'])) |
||||
|
# füge die zu unserer Klassenliste hinzu |
||||
|
if dialog['intent'] not in classes: |
||||
|
classes.append(dialog['intent']) |
||||
|
|
||||
|
# stemme jedes Word und entferne Duplikate |
||||
|
words = [stemmer.stem(w.lower()) for w in words if w not in ignore_words] + ['weit', 'and', 'nicht'] |
||||
|
words = sorted(list(set(words))) |
||||
|
|
||||
|
# sortiere unsere Klassen |
||||
|
classes = sorted(list(set(classes))) |
||||
|
|
||||
|
print(len(documents), "Docs") |
||||
|
print(len(classes), "Classes", classes) |
||||
|
print(len(words), "Split words", words) |
||||
|
|
||||
|
# erstelle unsere training data |
||||
|
training = [] |
||||
|
output = [] |
||||
|
# Erstelle ein leeres Array für unsere Output |
||||
|
output_empty = [0] * len(classes) |
||||
|
|
||||
|
# generiere training set und bag of words für jeden Satz |
||||
|
for doc in documents: |
||||
|
# Initialisierung unsere bag of words |
||||
|
bag = [] |
||||
|
# Liste der tokenisierte Wörter für den synonym |
||||
|
pattern_words = doc[0] |
||||
|
# stemme jedes Wort |
||||
|
pattern_words = [stemmer.stem(word.lower()) for word in pattern_words] |
||||
|
# erstelle unsre bag of words array |
||||
|
for w in words: |
||||
|
bag.append(1) if w in pattern_words else bag.append(0) |
||||
|
# output ist '0' für jedes intent und '1' für das aktuelle intent |
||||
|
output_row = list(output_empty) |
||||
|
output_row[classes.index(doc[1])] = 1 |
||||
|
|
||||
|
training.append([bag, output_row]) |
||||
|
|
||||
|
# mische unsere Features und verwandle die in np.array |
||||
|
random.shuffle(training) |
||||
|
training = np.array(training) |
||||
|
|
||||
|
# Erstelle die Training-Liste |
||||
|
train_x = list(training[:, 0]) |
||||
|
train_y = list(training[:, 1]) |
||||
|
|
||||
|
|
||||
|
#tf.reset_default_graph() |
||||
|
tf.compat.v1.reset_default_graph() |
||||
|
# Aufbau des neuronalen Netzes |
||||
|
net = tflearn.input_data(shape=[None, len(train_x[0])]) |
||||
|
net = tflearn.fully_connected(net, 88) |
||||
|
net = tflearn.fully_connected(net, 88) |
||||
|
net = tflearn.fully_connected(net, len(train_y[0]), activation='softmax') |
||||
|
net = tflearn.regression(net) |
||||
|
|
||||
|
# Definiere das Modell und konfiguriere tensorboard |
||||
|
model = tflearn.DNN(net, tensorboard_dir=getPath('train_logs')) |
||||
|
# Starte das training des Modells |
||||
|
model.fit(train_x, train_y, n_epoch=1000, batch_size=256, show_metric=True) |
||||
|
# Speichere das trainirte Modell |
||||
|
model.save(getPath('model.tflearn')) |
||||
|
|
||||
|
|
||||
|
print("model created") |
||||
|
|
||||
|
print("model created") |
||||
|
#Bearbeitung der Benutzereingaben, um einen bag-of-words zu erzeugen |
||||
|
def frageBearbeitung(frage): |
||||
|
# tokenisiere die synonymen |
||||
|
sentence_word = nltk.word_tokenize(frage, language='german') |
||||
|
# generiere die Stopwörter |
||||
|
stop= stopwords.words('german') |
||||
|
ignore_words = ['?', '.', ','] + stop |
||||
|
######Korrektur Schreibfehler |
||||
|
sentence_words=[] |
||||
|
for word in sentence_word: |
||||
|
if word not in ignore_words or word=='weiter' or word=='andere' or word=='nicht': |
||||
|
#a=correction(word) |
||||
|
sentence_words.append(word) |
||||
|
# stemme jedes Wort |
||||
|
sentence_words = [stemmer.stem(word.lower()) for word in sentence_words] |
||||
|
return sentence_words |
||||
|
|
||||
|
# Rückgabe bag of words array: 0 oder 1 für jedes Wort in der 'bag', die im Satz existiert |
||||
|
def bow(frage, words, show_details=False): |
||||
|
sentence_words = frageBearbeitung(frage) |
||||
|
bag = [0] * len(words) |
||||
|
for s in sentence_words: |
||||
|
for i, w in enumerate(words): |
||||
|
if w == s: |
||||
|
bag[i] = 1 |
||||
|
if show_details: |
||||
|
print("found in bag: %s" % w) |
||||
|
|
||||
|
return (np.array(bag)) |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
def lowercase(obj): |
||||
|
""" Make dictionary lowercase """ |
||||
|
if isinstance(obj, dict): |
||||
|
return {k: lowercase(v) for k, v in obj.items()} |
||||
|
elif isinstance(obj, (list, set, tuple)): |
||||
|
t = type(obj) |
||||
|
return t(lowercase(o) for o in obj) |
||||
|
elif isinstance(obj, str): |
||||
|
if " " in obj: |
||||
|
object=[] |
||||
|
o=nltk.word_tokenize(obj) |
||||
|
for i in o: |
||||
|
i=stemmer.stem(i.lower()) |
||||
|
object.append(i) |
||||
|
s = ' ' |
||||
|
object = s.join(object) |
||||
|
return object |
||||
|
|
||||
|
else: |
||||
|
return stemmer.stem(obj.lower()) |
||||
|
else: |
||||
|
return obj |
||||
|
ERROR_THRESHOLD=0 |
||||
|
def klassifizieren(frage): |
||||
|
# generiere Wahrscheinlichkeiten von dem Modell |
||||
|
|
||||
|
p = bow(frage, words, show_details=False) |
||||
|
results = model.predict(np.array([p]))[0] |
||||
|
|
||||
|
# herausfiltern Vorhersagen unterhalb eines Schwellenwerts |
||||
|
results = [[i, r] for i, r in enumerate(results) if r > ERROR_THRESHOLD] |
||||
|
# nach Stärke der Wahrscheinlichkeit sortieren |
||||
|
results.sort(key=lambda x: x[1], reverse=True) |
||||
|
return_list = [] |
||||
|
for r in results: |
||||
|
return_list.append((classes[r[0]], r[1])) |
||||
|
return return_list |
||||
|
print(klassifizieren('hallo')) |
||||
|
|
||||
|
hilf_entiti = {} |
||||
|
leistung_entiti = {} |
||||
|
lebenslage_entiti = {} |
||||
|
|
||||
|
|
||||
|
|
||||
|
for entities in dialogflow['entities_hilfe']: |
||||
|
for wert in entities['wert']: |
||||
|
# Tokenisieren jedes Wort im Satz |
||||
|
w = nltk.word_tokenize(wert) |
||||
|
# füge die zu Dokumenten in unserem Korpus hinzu |
||||
|
try: |
||||
|
hilf_entiti[entities['entitie']] = lowercase(entities['wert']) |
||||
|
except KeyError: |
||||
|
hilf_entiti[entities['entitie']] = lowercase(entities['wert']) |
||||
|
|
||||
|
|
||||
|
for entities in dialogflow['entities_leistungen']: |
||||
|
for wert in entities['wert']: |
||||
|
# Tokenisieren jedes Wort im Satz |
||||
|
w = nltk.word_tokenize(wert) |
||||
|
# füge die zu Dokumenten in unserem Korpus hinzu |
||||
|
try: |
||||
|
leistung_entiti[entities['entitie']] = lowercase(entities['wert']) |
||||
|
except KeyError: |
||||
|
leistung_entiti[entities['entitie']] = lowercase(entities['wert']) |
||||
|
|
||||
|
for entities in dialogflow['entities_lebenslage']: |
||||
|
for wert in entities['wert']: |
||||
|
# Tokenisieren jedes Wort im Satz |
||||
|
w = nltk.word_tokenize(wert) |
||||
|
# füge die zu Dokumenten in unserem Korpus hinzu |
||||
|
try: |
||||
|
lebenslage_entiti[entities['entitie']] = entities['wert'] |
||||
|
except KeyError: |
||||
|
lebenslage_entiti[entities['entitie']] = entities['wert'] |
||||
|
|
||||
|
|
||||
|
import pickle |
||||
|
|
||||
|
#pickle.dump(model, open(getPath('model.keras'), "wb")) |
||||
|
|
||||
|
#pickle.dump(model, getPath("katana-assistant-model.pkl", "wb")) |
||||
|
|
||||
|
# speichere alle unsere Datenstrukturen |
||||
|
pickle.dump({'words': words, 'classes': classes, 'train_x': train_x, 'train_y': train_y}, |
||||
|
open(getPath('trained_data'), "wb")) |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
with open(getPath('hilfe_data'), "wb") as filehandlehilfe: |
||||
|
# store the data as binary data stream |
||||
|
pickle.dump(hilf_entiti, filehandlehilfe) |
||||
|
|
||||
|
with open(getPath('leistung_data'), "wb") as filehandleleistung: |
||||
|
# store the data as binary data stream |
||||
|
pickle.dump(leistung_entiti, filehandleleistung) |
||||
|
|
||||
|
with open(getPath('lebenslage_data'), "wb") as filehandlelebenslage: |
||||
|
# store the data as binary data stream |
||||
|
pickle.dump(lebenslage_entiti, filehandlelebenslage) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,94 @@ |
|||||
|
body { |
||||
|
padding-top: 50px; |
||||
|
padding-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
/* Set padding to keep content from hitting the edges */ |
||||
|
.body-content { |
||||
|
padding-left: 15px; |
||||
|
padding-right: 15px; |
||||
|
} |
||||
|
|
||||
|
/* Override the default bootstrap behavior where horizontal description lists |
||||
|
will truncate terms that are too long to fit in the left column |
||||
|
*/ |
||||
|
.dl-horizontal dt { |
||||
|
white-space: normal; |
||||
|
} |
||||
|
|
||||
|
/* Set width on the form input elements since they're 100% wide by default */ |
||||
|
input, |
||||
|
select, |
||||
|
textarea { |
||||
|
max-width: 280px; |
||||
|
} |
||||
|
|
||||
|
.round { |
||||
|
border-radius: 15px; |
||||
|
border: 1px solid #afb2ac; |
||||
|
padding: 20px; |
||||
|
width: 50%; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
.inline-div { |
||||
|
width: auto; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
|
||||
|
.left-side { |
||||
|
float: left; |
||||
|
width: 48%; |
||||
|
} |
||||
|
|
||||
|
.right-side { |
||||
|
float: right; |
||||
|
width: 48%; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.field-validation-error { |
||||
|
color: red; |
||||
|
} |
||||
|
.validation-summary-errors { |
||||
|
color: red; |
||||
|
} |
||||
|
|
||||
|
.green-text { |
||||
|
color: green; |
||||
|
} |
||||
|
.red-text { |
||||
|
color: red; |
||||
|
} |
||||
|
ul li { |
||||
|
opacity: .8; |
||||
|
text-align: left; |
||||
|
} |
||||
|
ul li a { |
||||
|
color: #96978E; |
||||
|
text-decoration: none; |
||||
|
display: block; |
||||
|
} |
||||
|
ul li a:hover { |
||||
|
color: white; |
||||
|
text-decoration: none; |
||||
|
display: block; |
||||
|
} |
||||
|
ul li ul li { |
||||
|
display: none; |
||||
|
} |
||||
|
ul li:hover ul li{ |
||||
|
display: block; |
||||
|
} |
||||
|
.not-save { |
||||
|
color: red; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.sup { |
||||
|
position: relative; |
||||
|
bottom: 1ex; |
||||
|
font-size: 80%; |
||||
|
} |
||||
|
.blue-text { |
||||
|
color: #428bca; |
||||
|
} |
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,73 @@ |
|||||
|
// |
||||
|
// Alerts |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Base styles |
||||
|
// ------------------------- |
||||
|
|
||||
|
.alert { |
||||
|
padding: @alert-padding; |
||||
|
margin-bottom: @line-height-computed; |
||||
|
border: 1px solid transparent; |
||||
|
border-radius: @alert-border-radius; |
||||
|
|
||||
|
// Headings for larger alerts |
||||
|
h4 { |
||||
|
margin-top: 0; |
||||
|
// Specified for the h4 to prevent conflicts of changing @headings-color |
||||
|
color: inherit; |
||||
|
} |
||||
|
|
||||
|
// Provide class for links that match alerts |
||||
|
.alert-link { |
||||
|
font-weight: @alert-link-font-weight; |
||||
|
} |
||||
|
|
||||
|
// Improve alignment and spacing of inner content |
||||
|
> p, |
||||
|
> ul { |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
> p + p { |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Dismissible alerts |
||||
|
// |
||||
|
// Expand the right padding and account for the close button's positioning. |
||||
|
|
||||
|
.alert-dismissable, // The misspelled .alert-dismissable was deprecated in 3.2.0. |
||||
|
.alert-dismissible { |
||||
|
padding-right: (@alert-padding + 20); |
||||
|
|
||||
|
// Adjust close link position |
||||
|
.close { |
||||
|
position: relative; |
||||
|
top: -2px; |
||||
|
right: -21px; |
||||
|
color: inherit; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Alternate styles |
||||
|
// |
||||
|
// Generate contextual modifier classes for colorizing the alert. |
||||
|
|
||||
|
.alert-success { |
||||
|
.alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text); |
||||
|
} |
||||
|
|
||||
|
.alert-info { |
||||
|
.alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text); |
||||
|
} |
||||
|
|
||||
|
.alert-warning { |
||||
|
.alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text); |
||||
|
} |
||||
|
|
||||
|
.alert-danger { |
||||
|
.alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text); |
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
// |
||||
|
// Badges |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Base class |
||||
|
.badge { |
||||
|
display: inline-block; |
||||
|
min-width: 10px; |
||||
|
padding: 3px 7px; |
||||
|
font-size: @font-size-small; |
||||
|
font-weight: @badge-font-weight; |
||||
|
color: @badge-color; |
||||
|
line-height: @badge-line-height; |
||||
|
vertical-align: middle; |
||||
|
white-space: nowrap; |
||||
|
text-align: center; |
||||
|
background-color: @badge-bg; |
||||
|
border-radius: @badge-border-radius; |
||||
|
|
||||
|
// Empty badges collapse automatically (not available in IE8) |
||||
|
&:empty { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
// Quick fix for badges in buttons |
||||
|
.btn & { |
||||
|
position: relative; |
||||
|
top: -1px; |
||||
|
} |
||||
|
|
||||
|
.btn-xs &, |
||||
|
.btn-group-xs > .btn & { |
||||
|
top: 0; |
||||
|
padding: 1px 5px; |
||||
|
} |
||||
|
|
||||
|
// Hover state, but only for links |
||||
|
a& { |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
color: @badge-link-hover-color; |
||||
|
text-decoration: none; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Account for badges in navs |
||||
|
.list-group-item.active > &, |
||||
|
.nav-pills > .active > a > & { |
||||
|
color: @badge-active-color; |
||||
|
background-color: @badge-active-bg; |
||||
|
} |
||||
|
|
||||
|
.list-group-item > & { |
||||
|
float: right; |
||||
|
} |
||||
|
|
||||
|
.list-group-item > & + & { |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
|
||||
|
.nav-pills > li > a > & { |
||||
|
margin-left: 3px; |
||||
|
} |
||||
|
} |
@ -0,0 +1,56 @@ |
|||||
|
/*! |
||||
|
* Bootstrap v3.3.5 (http://getbootstrap.com) |
||||
|
* Copyright 2011-2015 Twitter, Inc. |
||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
||||
|
*/ |
||||
|
|
||||
|
// Core variables and mixins |
||||
|
@import "variables.less"; |
||||
|
@import "mixins.less"; |
||||
|
|
||||
|
// Reset and dependencies |
||||
|
@import "normalize.less"; |
||||
|
@import "print.less"; |
||||
|
@import "glyphicons.less"; |
||||
|
|
||||
|
// Core CSS |
||||
|
@import "scaffolding.less"; |
||||
|
@import "type.less"; |
||||
|
@import "code.less"; |
||||
|
@import "grid.less"; |
||||
|
@import "tables.less"; |
||||
|
@import "forms.less"; |
||||
|
@import "buttons.less"; |
||||
|
|
||||
|
// Components |
||||
|
@import "component-animations.less"; |
||||
|
@import "dropdowns.less"; |
||||
|
@import "button-groups.less"; |
||||
|
@import "input-groups.less"; |
||||
|
@import "navs.less"; |
||||
|
@import "navbar.less"; |
||||
|
@import "breadcrumbs.less"; |
||||
|
@import "pagination.less"; |
||||
|
@import "pager.less"; |
||||
|
@import "labels.less"; |
||||
|
@import "badges.less"; |
||||
|
@import "jumbotron.less"; |
||||
|
@import "thumbnails.less"; |
||||
|
@import "alerts.less"; |
||||
|
@import "progress-bars.less"; |
||||
|
@import "media.less"; |
||||
|
@import "list-group.less"; |
||||
|
@import "panels.less"; |
||||
|
@import "responsive-embed.less"; |
||||
|
@import "wells.less"; |
||||
|
@import "close.less"; |
||||
|
|
||||
|
// Components w/ JavaScript |
||||
|
@import "modals.less"; |
||||
|
@import "tooltip.less"; |
||||
|
@import "popovers.less"; |
||||
|
@import "carousel.less"; |
||||
|
|
||||
|
// Utility classes |
||||
|
@import "utilities.less"; |
||||
|
@import "responsive-utilities.less"; |
@ -0,0 +1,26 @@ |
|||||
|
// |
||||
|
// Breadcrumbs |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
.breadcrumb { |
||||
|
padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal; |
||||
|
margin-bottom: @line-height-computed; |
||||
|
list-style: none; |
||||
|
background-color: @breadcrumb-bg; |
||||
|
border-radius: @border-radius-base; |
||||
|
|
||||
|
> li { |
||||
|
display: inline-block; |
||||
|
|
||||
|
+ li:before { |
||||
|
content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space |
||||
|
padding: 0 5px; |
||||
|
color: @breadcrumb-color; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
> .active { |
||||
|
color: @breadcrumb-active-color; |
||||
|
} |
||||
|
} |
@ -0,0 +1,244 @@ |
|||||
|
// |
||||
|
// Button groups |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
// Make the div behave like a button |
||||
|
.btn-group, |
||||
|
.btn-group-vertical { |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; // match .btn alignment given font-size hack above |
||||
|
> .btn { |
||||
|
position: relative; |
||||
|
float: left; |
||||
|
// Bring the "active" button to the front |
||||
|
&:hover, |
||||
|
&:focus, |
||||
|
&:active, |
||||
|
&.active { |
||||
|
z-index: 2; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Prevent double borders when buttons are next to each other |
||||
|
.btn-group { |
||||
|
.btn + .btn, |
||||
|
.btn + .btn-group, |
||||
|
.btn-group + .btn, |
||||
|
.btn-group + .btn-group { |
||||
|
margin-left: -1px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Optional: Group multiple button groups together for a toolbar |
||||
|
.btn-toolbar { |
||||
|
margin-left: -5px; // Offset the first child's margin |
||||
|
&:extend(.clearfix all); |
||||
|
|
||||
|
.btn, |
||||
|
.btn-group, |
||||
|
.input-group { |
||||
|
float: left; |
||||
|
} |
||||
|
> .btn, |
||||
|
> .btn-group, |
||||
|
> .input-group { |
||||
|
margin-left: 5px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { |
||||
|
border-radius: 0; |
||||
|
} |
||||
|
|
||||
|
// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match |
||||
|
.btn-group > .btn:first-child { |
||||
|
margin-left: 0; |
||||
|
&:not(:last-child):not(.dropdown-toggle) { |
||||
|
.border-right-radius(0); |
||||
|
} |
||||
|
} |
||||
|
// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it |
||||
|
.btn-group > .btn:last-child:not(:first-child), |
||||
|
.btn-group > .dropdown-toggle:not(:first-child) { |
||||
|
.border-left-radius(0); |
||||
|
} |
||||
|
|
||||
|
// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) |
||||
|
.btn-group > .btn-group { |
||||
|
float: left; |
||||
|
} |
||||
|
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { |
||||
|
border-radius: 0; |
||||
|
} |
||||
|
.btn-group > .btn-group:first-child:not(:last-child) { |
||||
|
> .btn:last-child, |
||||
|
> .dropdown-toggle { |
||||
|
.border-right-radius(0); |
||||
|
} |
||||
|
} |
||||
|
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { |
||||
|
.border-left-radius(0); |
||||
|
} |
||||
|
|
||||
|
// On active and open, don't show outline |
||||
|
.btn-group .dropdown-toggle:active, |
||||
|
.btn-group.open .dropdown-toggle { |
||||
|
outline: 0; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Sizing |
||||
|
// |
||||
|
// Remix the default button sizing classes into new ones for easier manipulation. |
||||
|
|
||||
|
.btn-group-xs > .btn { &:extend(.btn-xs); } |
||||
|
.btn-group-sm > .btn { &:extend(.btn-sm); } |
||||
|
.btn-group-lg > .btn { &:extend(.btn-lg); } |
||||
|
|
||||
|
|
||||
|
// Split button dropdowns |
||||
|
// ---------------------- |
||||
|
|
||||
|
// Give the line between buttons some depth |
||||
|
.btn-group > .btn + .dropdown-toggle { |
||||
|
padding-left: 8px; |
||||
|
padding-right: 8px; |
||||
|
} |
||||
|
.btn-group > .btn-lg + .dropdown-toggle { |
||||
|
padding-left: 12px; |
||||
|
padding-right: 12px; |
||||
|
} |
||||
|
|
||||
|
// The clickable button for toggling the menu |
||||
|
// Remove the gradient and set the same inset shadow as the :active state |
||||
|
.btn-group.open .dropdown-toggle { |
||||
|
.box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); |
||||
|
|
||||
|
// Show no shadow for `.btn-link` since it has no other button styles. |
||||
|
&.btn-link { |
||||
|
.box-shadow(none); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Reposition the caret |
||||
|
.btn .caret { |
||||
|
margin-left: 0; |
||||
|
} |
||||
|
// Carets in other button sizes |
||||
|
.btn-lg .caret { |
||||
|
border-width: @caret-width-large @caret-width-large 0; |
||||
|
border-bottom-width: 0; |
||||
|
} |
||||
|
// Upside down carets for .dropup |
||||
|
.dropup .btn-lg .caret { |
||||
|
border-width: 0 @caret-width-large @caret-width-large; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Vertical button groups |
||||
|
// ---------------------- |
||||
|
|
||||
|
.btn-group-vertical { |
||||
|
> .btn, |
||||
|
> .btn-group, |
||||
|
> .btn-group > .btn { |
||||
|
display: block; |
||||
|
float: none; |
||||
|
width: 100%; |
||||
|
max-width: 100%; |
||||
|
} |
||||
|
|
||||
|
// Clear floats so dropdown menus can be properly placed |
||||
|
> .btn-group { |
||||
|
&:extend(.clearfix all); |
||||
|
> .btn { |
||||
|
float: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
> .btn + .btn, |
||||
|
> .btn + .btn-group, |
||||
|
> .btn-group + .btn, |
||||
|
> .btn-group + .btn-group { |
||||
|
margin-top: -1px; |
||||
|
margin-left: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.btn-group-vertical > .btn { |
||||
|
&:not(:first-child):not(:last-child) { |
||||
|
border-radius: 0; |
||||
|
} |
||||
|
&:first-child:not(:last-child) { |
||||
|
border-top-right-radius: @btn-border-radius-base; |
||||
|
.border-bottom-radius(0); |
||||
|
} |
||||
|
&:last-child:not(:first-child) { |
||||
|
border-bottom-left-radius: @btn-border-radius-base; |
||||
|
.border-top-radius(0); |
||||
|
} |
||||
|
} |
||||
|
.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { |
||||
|
border-radius: 0; |
||||
|
} |
||||
|
.btn-group-vertical > .btn-group:first-child:not(:last-child) { |
||||
|
> .btn:last-child, |
||||
|
> .dropdown-toggle { |
||||
|
.border-bottom-radius(0); |
||||
|
} |
||||
|
} |
||||
|
.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { |
||||
|
.border-top-radius(0); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Justified button groups |
||||
|
// ---------------------- |
||||
|
|
||||
|
.btn-group-justified { |
||||
|
display: table; |
||||
|
width: 100%; |
||||
|
table-layout: fixed; |
||||
|
border-collapse: separate; |
||||
|
> .btn, |
||||
|
> .btn-group { |
||||
|
float: none; |
||||
|
display: table-cell; |
||||
|
width: 1%; |
||||
|
} |
||||
|
> .btn-group .btn { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
> .btn-group .dropdown-menu { |
||||
|
left: auto; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Checkbox and radio options |
||||
|
// |
||||
|
// In order to support the browser's form validation feedback, powered by the |
||||
|
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use |
||||
|
// `display: none;` or `visibility: hidden;` as that also hides the popover. |
||||
|
// Simply visually hiding the inputs via `opacity` would leave them clickable in |
||||
|
// certain cases which is prevented by using `clip` and `pointer-events`. |
||||
|
// This way, we ensure a DOM element is visible to position the popover from. |
||||
|
// |
||||
|
// See https://github.com/twbs/bootstrap/pull/12794 and |
||||
|
// https://github.com/twbs/bootstrap/pull/14559 for more information. |
||||
|
|
||||
|
[data-toggle="buttons"] { |
||||
|
> .btn, |
||||
|
> .btn-group > .btn { |
||||
|
input[type="radio"], |
||||
|
input[type="checkbox"] { |
||||
|
position: absolute; |
||||
|
clip: rect(0,0,0,0); |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,166 @@ |
|||||
|
// |
||||
|
// Buttons |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Base styles |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
.btn { |
||||
|
display: inline-block; |
||||
|
margin-bottom: 0; // For input.btn |
||||
|
font-weight: @btn-font-weight; |
||||
|
text-align: center; |
||||
|
vertical-align: middle; |
||||
|
touch-action: manipulation; |
||||
|
cursor: pointer; |
||||
|
background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 |
||||
|
border: 1px solid transparent; |
||||
|
white-space: nowrap; |
||||
|
.button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @btn-border-radius-base); |
||||
|
.user-select(none); |
||||
|
|
||||
|
&, |
||||
|
&:active, |
||||
|
&.active { |
||||
|
&:focus, |
||||
|
&.focus { |
||||
|
.tab-focus(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&:hover, |
||||
|
&:focus, |
||||
|
&.focus { |
||||
|
color: @btn-default-color; |
||||
|
text-decoration: none; |
||||
|
} |
||||
|
|
||||
|
&:active, |
||||
|
&.active { |
||||
|
outline: 0; |
||||
|
background-image: none; |
||||
|
.box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); |
||||
|
} |
||||
|
|
||||
|
&.disabled, |
||||
|
&[disabled], |
||||
|
fieldset[disabled] & { |
||||
|
cursor: @cursor-disabled; |
||||
|
.opacity(.65); |
||||
|
.box-shadow(none); |
||||
|
} |
||||
|
|
||||
|
a& { |
||||
|
&.disabled, |
||||
|
fieldset[disabled] & { |
||||
|
pointer-events: none; // Future-proof disabling of clicks on `<a>` elements |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Alternate buttons |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
.btn-default { |
||||
|
.button-variant(@btn-default-color; @btn-default-bg; @btn-default-border); |
||||
|
} |
||||
|
.btn-primary { |
||||
|
.button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border); |
||||
|
} |
||||
|
// Success appears as green |
||||
|
.btn-success { |
||||
|
.button-variant(@btn-success-color; @btn-success-bg; @btn-success-border); |
||||
|
} |
||||
|
// Info appears as blue-green |
||||
|
.btn-info { |
||||
|
.button-variant(@btn-info-color; @btn-info-bg; @btn-info-border); |
||||
|
} |
||||
|
// Warning appears as orange |
||||
|
.btn-warning { |
||||
|
.button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border); |
||||
|
} |
||||
|
// Danger and error appear as red |
||||
|
.btn-danger { |
||||
|
.button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Link buttons |
||||
|
// ------------------------- |
||||
|
|
||||
|
// Make a button look and behave like a link |
||||
|
.btn-link { |
||||
|
color: @link-color; |
||||
|
font-weight: normal; |
||||
|
border-radius: 0; |
||||
|
|
||||
|
&, |
||||
|
&:active, |
||||
|
&.active, |
||||
|
&[disabled], |
||||
|
fieldset[disabled] & { |
||||
|
background-color: transparent; |
||||
|
.box-shadow(none); |
||||
|
} |
||||
|
&, |
||||
|
&:hover, |
||||
|
&:focus, |
||||
|
&:active { |
||||
|
border-color: transparent; |
||||
|
} |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
color: @link-hover-color; |
||||
|
text-decoration: @link-hover-decoration; |
||||
|
background-color: transparent; |
||||
|
} |
||||
|
&[disabled], |
||||
|
fieldset[disabled] & { |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
color: @btn-link-disabled-color; |
||||
|
text-decoration: none; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Button Sizes |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
.btn-lg { |
||||
|
// line-height: ensure even-numbered height of button next to large input |
||||
|
.button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @btn-border-radius-large); |
||||
|
} |
||||
|
.btn-sm { |
||||
|
// line-height: ensure proper height of button next to small input |
||||
|
.button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small); |
||||
|
} |
||||
|
.btn-xs { |
||||
|
.button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @btn-border-radius-small); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Block button |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
.btn-block { |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
// Vertically space out multiple block buttons |
||||
|
.btn-block + .btn-block { |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
|
||||
|
// Specificity overrides |
||||
|
input[type="submit"], |
||||
|
input[type="reset"], |
||||
|
input[type="button"] { |
||||
|
&.btn-block { |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
@ -0,0 +1,269 @@ |
|||||
|
// |
||||
|
// Carousel |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Wrapper for the slide container and indicators |
||||
|
.carousel { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.carousel-inner { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
width: 100%; |
||||
|
|
||||
|
> .item { |
||||
|
display: none; |
||||
|
position: relative; |
||||
|
.transition(.6s ease-in-out left); |
||||
|
|
||||
|
// Account for jankitude on images |
||||
|
> img, |
||||
|
> a > img { |
||||
|
&:extend(.img-responsive); |
||||
|
line-height: 1; |
||||
|
} |
||||
|
|
||||
|
// WebKit CSS3 transforms for supported devices |
||||
|
@media all and (transform-3d), (-webkit-transform-3d) { |
||||
|
.transition-transform(~'0.6s ease-in-out'); |
||||
|
.backface-visibility(~'hidden'); |
||||
|
.perspective(1000px); |
||||
|
|
||||
|
&.next, |
||||
|
&.active.right { |
||||
|
.translate3d(100%, 0, 0); |
||||
|
left: 0; |
||||
|
} |
||||
|
&.prev, |
||||
|
&.active.left { |
||||
|
.translate3d(-100%, 0, 0); |
||||
|
left: 0; |
||||
|
} |
||||
|
&.next.left, |
||||
|
&.prev.right, |
||||
|
&.active { |
||||
|
.translate3d(0, 0, 0); |
||||
|
left: 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
> .active, |
||||
|
> .next, |
||||
|
> .prev { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
> .active { |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
> .next, |
||||
|
> .prev { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
> .next { |
||||
|
left: 100%; |
||||
|
} |
||||
|
> .prev { |
||||
|
left: -100%; |
||||
|
} |
||||
|
> .next.left, |
||||
|
> .prev.right { |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
> .active.left { |
||||
|
left: -100%; |
||||
|
} |
||||
|
> .active.right { |
||||
|
left: 100%; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// Left/right controls for nav |
||||
|
// --------------------------- |
||||
|
|
||||
|
.carousel-control { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
bottom: 0; |
||||
|
width: @carousel-control-width; |
||||
|
.opacity(@carousel-control-opacity); |
||||
|
font-size: @carousel-control-font-size; |
||||
|
color: @carousel-control-color; |
||||
|
text-align: center; |
||||
|
text-shadow: @carousel-text-shadow; |
||||
|
// We can't have this transition here because WebKit cancels the carousel |
||||
|
// animation if you trip this while in the middle of another animation. |
||||
|
|
||||
|
// Set gradients for backgrounds |
||||
|
&.left { |
||||
|
#gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001)); |
||||
|
} |
||||
|
&.right { |
||||
|
left: auto; |
||||
|
right: 0; |
||||
|
#gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5)); |
||||
|
} |
||||
|
|
||||
|
// Hover/focus state |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
outline: 0; |
||||
|
color: @carousel-control-color; |
||||
|
text-decoration: none; |
||||
|
.opacity(.9); |
||||
|
} |
||||
|
|
||||
|
// Toggles |
||||
|
.icon-prev, |
||||
|
.icon-next, |
||||
|
.glyphicon-chevron-left, |
||||
|
.glyphicon-chevron-right { |
||||
|
position: absolute; |
||||
|
top: 50%; |
||||
|
margin-top: -10px; |
||||
|
z-index: 5; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
.icon-prev, |
||||
|
.glyphicon-chevron-left { |
||||
|
left: 50%; |
||||
|
margin-left: -10px; |
||||
|
} |
||||
|
.icon-next, |
||||
|
.glyphicon-chevron-right { |
||||
|
right: 50%; |
||||
|
margin-right: -10px; |
||||
|
} |
||||
|
.icon-prev, |
||||
|
.icon-next { |
||||
|
width: 20px; |
||||
|
height: 20px; |
||||
|
line-height: 1; |
||||
|
font-family: serif; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.icon-prev { |
||||
|
&:before { |
||||
|
content: '\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) |
||||
|
} |
||||
|
} |
||||
|
.icon-next { |
||||
|
&:before { |
||||
|
content: '\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Optional indicator pips |
||||
|
// |
||||
|
// Add an unordered list with the following class and add a list item for each |
||||
|
// slide your carousel holds. |
||||
|
|
||||
|
.carousel-indicators { |
||||
|
position: absolute; |
||||
|
bottom: 10px; |
||||
|
left: 50%; |
||||
|
z-index: 15; |
||||
|
width: 60%; |
||||
|
margin-left: -30%; |
||||
|
padding-left: 0; |
||||
|
list-style: none; |
||||
|
text-align: center; |
||||
|
|
||||
|
li { |
||||
|
display: inline-block; |
||||
|
width: 10px; |
||||
|
height: 10px; |
||||
|
margin: 1px; |
||||
|
text-indent: -999px; |
||||
|
border: 1px solid @carousel-indicator-border-color; |
||||
|
border-radius: 10px; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
// IE8-9 hack for event handling |
||||
|
// |
||||
|
// Internet Explorer 8-9 does not support clicks on elements without a set |
||||
|
// `background-color`. We cannot use `filter` since that's not viewed as a |
||||
|
// background color by the browser. Thus, a hack is needed. |
||||
|
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer |
||||
|
// |
||||
|
// For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we |
||||
|
// set alpha transparency for the best results possible. |
||||
|
background-color: #000 \9; // IE8 |
||||
|
background-color: rgba(0,0,0,0); // IE9 |
||||
|
} |
||||
|
.active { |
||||
|
margin: 0; |
||||
|
width: 12px; |
||||
|
height: 12px; |
||||
|
background-color: @carousel-indicator-active-bg; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Optional captions |
||||
|
// ----------------------------- |
||||
|
// Hidden by default for smaller viewports |
||||
|
.carousel-caption { |
||||
|
position: absolute; |
||||
|
left: 15%; |
||||
|
right: 15%; |
||||
|
bottom: 20px; |
||||
|
z-index: 10; |
||||
|
padding-top: 20px; |
||||
|
padding-bottom: 20px; |
||||
|
color: @carousel-caption-color; |
||||
|
text-align: center; |
||||
|
text-shadow: @carousel-text-shadow; |
||||
|
& .btn { |
||||
|
text-shadow: none; // No shadow for button elements in carousel-caption |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Scale up controls for tablets and up |
||||
|
@media screen and (min-width: @screen-sm-min) { |
||||
|
|
||||
|
// Scale up the controls a smidge |
||||
|
.carousel-control { |
||||
|
.glyphicon-chevron-left, |
||||
|
.glyphicon-chevron-right, |
||||
|
.icon-prev, |
||||
|
.icon-next { |
||||
|
width: 30px; |
||||
|
height: 30px; |
||||
|
margin-top: -15px; |
||||
|
font-size: 30px; |
||||
|
} |
||||
|
.glyphicon-chevron-left, |
||||
|
.icon-prev { |
||||
|
margin-left: -15px; |
||||
|
} |
||||
|
.glyphicon-chevron-right, |
||||
|
.icon-next { |
||||
|
margin-right: -15px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Show and left align the captions |
||||
|
.carousel-caption { |
||||
|
left: 20%; |
||||
|
right: 20%; |
||||
|
padding-bottom: 30px; |
||||
|
} |
||||
|
|
||||
|
// Move up the indicators |
||||
|
.carousel-indicators { |
||||
|
bottom: 20px; |
||||
|
} |
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
// |
||||
|
// Close icons |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
.close { |
||||
|
float: right; |
||||
|
font-size: (@font-size-base * 1.5); |
||||
|
font-weight: @close-font-weight; |
||||
|
line-height: 1; |
||||
|
color: @close-color; |
||||
|
text-shadow: @close-text-shadow; |
||||
|
.opacity(.2); |
||||
|
|
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
color: @close-color; |
||||
|
text-decoration: none; |
||||
|
cursor: pointer; |
||||
|
.opacity(.5); |
||||
|
} |
||||
|
|
||||
|
// Additional properties for button version |
||||
|
// iOS requires the button element instead of an anchor tag. |
||||
|
// If you want the anchor version, it requires `href="#"`. |
||||
|
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile |
||||
|
button& { |
||||
|
padding: 0; |
||||
|
cursor: pointer; |
||||
|
background: transparent; |
||||
|
border: 0; |
||||
|
-webkit-appearance: none; |
||||
|
} |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
// |
||||
|
// Code (inline and block) |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Inline and block code styles |
||||
|
code, |
||||
|
kbd, |
||||
|
pre, |
||||
|
samp { |
||||
|
font-family: @font-family-monospace; |
||||
|
} |
||||
|
|
||||
|
// Inline code |
||||
|
code { |
||||
|
padding: 2px 4px; |
||||
|
font-size: 90%; |
||||
|
color: @code-color; |
||||
|
background-color: @code-bg; |
||||
|
border-radius: @border-radius-base; |
||||
|
} |
||||
|
|
||||
|
// User input typically entered via keyboard |
||||
|
kbd { |
||||
|
padding: 2px 4px; |
||||
|
font-size: 90%; |
||||
|
color: @kbd-color; |
||||
|
background-color: @kbd-bg; |
||||
|
border-radius: @border-radius-small; |
||||
|
box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); |
||||
|
|
||||
|
kbd { |
||||
|
padding: 0; |
||||
|
font-size: 100%; |
||||
|
font-weight: bold; |
||||
|
box-shadow: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Blocks of code |
||||
|
pre { |
||||
|
display: block; |
||||
|
padding: ((@line-height-computed - 1) / 2); |
||||
|
margin: 0 0 (@line-height-computed / 2); |
||||
|
font-size: (@font-size-base - 1); // 14px to 13px |
||||
|
line-height: @line-height-base; |
||||
|
word-break: break-all; |
||||
|
word-wrap: break-word; |
||||
|
color: @pre-color; |
||||
|
background-color: @pre-bg; |
||||
|
border: 1px solid @pre-border-color; |
||||
|
border-radius: @border-radius-base; |
||||
|
|
||||
|
// Account for some code outputs that place code tags in pre tags |
||||
|
code { |
||||
|
padding: 0; |
||||
|
font-size: inherit; |
||||
|
color: inherit; |
||||
|
white-space: pre-wrap; |
||||
|
background-color: transparent; |
||||
|
border-radius: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Enable scrollable blocks of code |
||||
|
.pre-scrollable { |
||||
|
max-height: @pre-scrollable-max-height; |
||||
|
overflow-y: scroll; |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
// |
||||
|
// Component animations |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
// Heads up! |
||||
|
// |
||||
|
// We don't use the `.opacity()` mixin here since it causes a bug with text |
||||
|
// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552. |
||||
|
|
||||
|
.fade { |
||||
|
opacity: 0; |
||||
|
.transition(opacity .15s linear); |
||||
|
&.in { |
||||
|
opacity: 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.collapse { |
||||
|
display: none; |
||||
|
|
||||
|
&.in { display: block; } |
||||
|
tr&.in { display: table-row; } |
||||
|
tbody&.in { display: table-row-group; } |
||||
|
} |
||||
|
|
||||
|
.collapsing { |
||||
|
position: relative; |
||||
|
height: 0; |
||||
|
overflow: hidden; |
||||
|
.transition-property(~"height, visibility"); |
||||
|
.transition-duration(.35s); |
||||
|
.transition-timing-function(ease); |
||||
|
} |
@ -0,0 +1,216 @@ |
|||||
|
// |
||||
|
// Dropdown menus |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Dropdown arrow/caret |
||||
|
.caret { |
||||
|
display: inline-block; |
||||
|
width: 0; |
||||
|
height: 0; |
||||
|
margin-left: 2px; |
||||
|
vertical-align: middle; |
||||
|
border-top: @caret-width-base dashed; |
||||
|
border-top: @caret-width-base solid ~"\9"; // IE8 |
||||
|
border-right: @caret-width-base solid transparent; |
||||
|
border-left: @caret-width-base solid transparent; |
||||
|
} |
||||
|
|
||||
|
// The dropdown wrapper (div) |
||||
|
.dropup, |
||||
|
.dropdown { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
// Prevent the focus on the dropdown toggle when closing dropdowns |
||||
|
.dropdown-toggle:focus { |
||||
|
outline: 0; |
||||
|
} |
||||
|
|
||||
|
// The dropdown menu (ul) |
||||
|
.dropdown-menu { |
||||
|
position: absolute; |
||||
|
top: 100%; |
||||
|
left: 0; |
||||
|
z-index: @zindex-dropdown; |
||||
|
display: none; // none by default, but block on "open" of the menu |
||||
|
float: left; |
||||
|
min-width: 160px; |
||||
|
padding: 5px 0; |
||||
|
margin: 2px 0 0; // override default ul |
||||
|
list-style: none; |
||||
|
font-size: @font-size-base; |
||||
|
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) |
||||
|
background-color: @dropdown-bg; |
||||
|
border: 1px solid @dropdown-fallback-border; // IE8 fallback |
||||
|
border: 1px solid @dropdown-border; |
||||
|
border-radius: @border-radius-base; |
||||
|
.box-shadow(0 6px 12px rgba(0,0,0,.175)); |
||||
|
background-clip: padding-box; |
||||
|
|
||||
|
// Aligns the dropdown menu to right |
||||
|
// |
||||
|
// Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]` |
||||
|
&.pull-right { |
||||
|
right: 0; |
||||
|
left: auto; |
||||
|
} |
||||
|
|
||||
|
// Dividers (basically an hr) within the dropdown |
||||
|
.divider { |
||||
|
.nav-divider(@dropdown-divider-bg); |
||||
|
} |
||||
|
|
||||
|
// Links within the dropdown menu |
||||
|
> li > a { |
||||
|
display: block; |
||||
|
padding: 3px 20px; |
||||
|
clear: both; |
||||
|
font-weight: normal; |
||||
|
line-height: @line-height-base; |
||||
|
color: @dropdown-link-color; |
||||
|
white-space: nowrap; // prevent links from randomly breaking onto new lines |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Hover/Focus state |
||||
|
.dropdown-menu > li > a { |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
text-decoration: none; |
||||
|
color: @dropdown-link-hover-color; |
||||
|
background-color: @dropdown-link-hover-bg; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Active state |
||||
|
.dropdown-menu > .active > a { |
||||
|
&, |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
color: @dropdown-link-active-color; |
||||
|
text-decoration: none; |
||||
|
outline: 0; |
||||
|
background-color: @dropdown-link-active-bg; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Disabled state |
||||
|
// |
||||
|
// Gray out text and ensure the hover/focus state remains gray |
||||
|
|
||||
|
.dropdown-menu > .disabled > a { |
||||
|
&, |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
color: @dropdown-link-disabled-color; |
||||
|
} |
||||
|
|
||||
|
// Nuke hover/focus effects |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
text-decoration: none; |
||||
|
background-color: transparent; |
||||
|
background-image: none; // Remove CSS gradient |
||||
|
.reset-filter(); |
||||
|
cursor: @cursor-disabled; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Open state for the dropdown |
||||
|
.open { |
||||
|
// Show the menu |
||||
|
> .dropdown-menu { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
// Remove the outline when :focus is triggered |
||||
|
> a { |
||||
|
outline: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Menu positioning |
||||
|
// |
||||
|
// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown |
||||
|
// menu with the parent. |
||||
|
.dropdown-menu-right { |
||||
|
left: auto; // Reset the default from `.dropdown-menu` |
||||
|
right: 0; |
||||
|
} |
||||
|
// With v3, we enabled auto-flipping if you have a dropdown within a right |
||||
|
// aligned nav component. To enable the undoing of that, we provide an override |
||||
|
// to restore the default dropdown menu alignment. |
||||
|
// |
||||
|
// This is only for left-aligning a dropdown menu within a `.navbar-right` or |
||||
|
// `.pull-right` nav component. |
||||
|
.dropdown-menu-left { |
||||
|
left: 0; |
||||
|
right: auto; |
||||
|
} |
||||
|
|
||||
|
// Dropdown section headers |
||||
|
.dropdown-header { |
||||
|
display: block; |
||||
|
padding: 3px 20px; |
||||
|
font-size: @font-size-small; |
||||
|
line-height: @line-height-base; |
||||
|
color: @dropdown-header-color; |
||||
|
white-space: nowrap; // as with > li > a |
||||
|
} |
||||
|
|
||||
|
// Backdrop to catch body clicks on mobile, etc. |
||||
|
.dropdown-backdrop { |
||||
|
position: fixed; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
top: 0; |
||||
|
z-index: (@zindex-dropdown - 10); |
||||
|
} |
||||
|
|
||||
|
// Right aligned dropdowns |
||||
|
.pull-right > .dropdown-menu { |
||||
|
right: 0; |
||||
|
left: auto; |
||||
|
} |
||||
|
|
||||
|
// Allow for dropdowns to go bottom up (aka, dropup-menu) |
||||
|
// |
||||
|
// Just add .dropup after the standard .dropdown class and you're set, bro. |
||||
|
// TODO: abstract this so that the navbar fixed styles are not placed here? |
||||
|
|
||||
|
.dropup, |
||||
|
.navbar-fixed-bottom .dropdown { |
||||
|
// Reverse the caret |
||||
|
.caret { |
||||
|
border-top: 0; |
||||
|
border-bottom: @caret-width-base dashed; |
||||
|
border-bottom: @caret-width-base solid ~"\9"; // IE8 |
||||
|
content: ""; |
||||
|
} |
||||
|
// Different positioning for bottom up menu |
||||
|
.dropdown-menu { |
||||
|
top: auto; |
||||
|
bottom: 100%; |
||||
|
margin-bottom: 2px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Component alignment |
||||
|
// |
||||
|
// Reiterate per navbar.less and the modified component alignment there. |
||||
|
|
||||
|
@media (min-width: @grid-float-breakpoint) { |
||||
|
.navbar-right { |
||||
|
.dropdown-menu { |
||||
|
.dropdown-menu-right(); |
||||
|
} |
||||
|
// Necessary for overrides of the default right aligned menu. |
||||
|
// Will remove come v4 in all likelihood. |
||||
|
.dropdown-menu-left { |
||||
|
.dropdown-menu-left(); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,607 @@ |
|||||
|
// |
||||
|
// Forms |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Normalize non-controls |
||||
|
// |
||||
|
// Restyle and baseline non-control form elements. |
||||
|
|
||||
|
fieldset { |
||||
|
padding: 0; |
||||
|
margin: 0; |
||||
|
border: 0; |
||||
|
// Chrome and Firefox set a `min-width: min-content;` on fieldsets, |
||||
|
// so we reset that to ensure it behaves more like a standard block element. |
||||
|
// See https://github.com/twbs/bootstrap/issues/12359. |
||||
|
min-width: 0; |
||||
|
} |
||||
|
|
||||
|
legend { |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
padding: 0; |
||||
|
margin-bottom: @line-height-computed; |
||||
|
font-size: (@font-size-base * 1.5); |
||||
|
line-height: inherit; |
||||
|
color: @legend-color; |
||||
|
border: 0; |
||||
|
border-bottom: 1px solid @legend-border-color; |
||||
|
} |
||||
|
|
||||
|
label { |
||||
|
display: inline-block; |
||||
|
max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141) |
||||
|
margin-bottom: 5px; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Normalize form controls |
||||
|
// |
||||
|
// While most of our form styles require extra classes, some basic normalization |
||||
|
// is required to ensure optimum display with or without those classes to better |
||||
|
// address browser inconsistencies. |
||||
|
|
||||
|
// Override content-box in Normalize (* isn't specific enough) |
||||
|
input[type="search"] { |
||||
|
.box-sizing(border-box); |
||||
|
} |
||||
|
|
||||
|
// Position radios and checkboxes better |
||||
|
input[type="radio"], |
||||
|
input[type="checkbox"] { |
||||
|
margin: 4px 0 0; |
||||
|
margin-top: 1px \9; // IE8-9 |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
input[type="file"] { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
// Make range inputs behave like textual form controls |
||||
|
input[type="range"] { |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
// Make multiple select elements height not fixed |
||||
|
select[multiple], |
||||
|
select[size] { |
||||
|
height: auto; |
||||
|
} |
||||
|
|
||||
|
// Focus for file, radio, and checkbox |
||||
|
input[type="file"]:focus, |
||||
|
input[type="radio"]:focus, |
||||
|
input[type="checkbox"]:focus { |
||||
|
.tab-focus(); |
||||
|
} |
||||
|
|
||||
|
// Adjust output element |
||||
|
output { |
||||
|
display: block; |
||||
|
padding-top: (@padding-base-vertical + 1); |
||||
|
font-size: @font-size-base; |
||||
|
line-height: @line-height-base; |
||||
|
color: @input-color; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Common form controls |
||||
|
// |
||||
|
// Shared size and type resets for form controls. Apply `.form-control` to any |
||||
|
// of the following form controls: |
||||
|
// |
||||
|
// select |
||||
|
// textarea |
||||
|
// input[type="text"] |
||||
|
// input[type="password"] |
||||
|
// input[type="datetime"] |
||||
|
// input[type="datetime-local"] |
||||
|
// input[type="date"] |
||||
|
// input[type="month"] |
||||
|
// input[type="time"] |
||||
|
// input[type="week"] |
||||
|
// input[type="number"] |
||||
|
// input[type="email"] |
||||
|
// input[type="url"] |
||||
|
// input[type="search"] |
||||
|
// input[type="tel"] |
||||
|
// input[type="color"] |
||||
|
|
||||
|
.form-control { |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border) |
||||
|
padding: @padding-base-vertical @padding-base-horizontal; |
||||
|
font-size: @font-size-base; |
||||
|
line-height: @line-height-base; |
||||
|
color: @input-color; |
||||
|
background-color: @input-bg; |
||||
|
background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 |
||||
|
border: 1px solid @input-border; |
||||
|
border-radius: @input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS. |
||||
|
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); |
||||
|
.transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s"); |
||||
|
|
||||
|
// Customize the `:focus` state to imitate native WebKit styles. |
||||
|
.form-control-focus(); |
||||
|
|
||||
|
// Placeholder |
||||
|
.placeholder(); |
||||
|
|
||||
|
// Disabled and read-only inputs |
||||
|
// |
||||
|
// HTML5 says that controls under a fieldset > legend:first-child won't be |
||||
|
// disabled if the fieldset is disabled. Due to implementation difficulty, we |
||||
|
// don't honor that edge case; we style them as disabled anyway. |
||||
|
&[disabled], |
||||
|
&[readonly], |
||||
|
fieldset[disabled] & { |
||||
|
background-color: @input-bg-disabled; |
||||
|
opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655 |
||||
|
} |
||||
|
|
||||
|
&[disabled], |
||||
|
fieldset[disabled] & { |
||||
|
cursor: @cursor-disabled; |
||||
|
} |
||||
|
|
||||
|
// Reset height for `textarea`s |
||||
|
textarea& { |
||||
|
height: auto; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Search inputs in iOS |
||||
|
// |
||||
|
// This overrides the extra rounded corners on search inputs in iOS so that our |
||||
|
// `.form-control` class can properly style them. Note that this cannot simply |
||||
|
// be added to `.form-control` as it's not specific enough. For details, see |
||||
|
// https://github.com/twbs/bootstrap/issues/11586. |
||||
|
|
||||
|
input[type="search"] { |
||||
|
-webkit-appearance: none; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Special styles for iOS temporal inputs |
||||
|
// |
||||
|
// In Mobile Safari, setting `display: block` on temporal inputs causes the |
||||
|
// text within the input to become vertically misaligned. As a workaround, we |
||||
|
// set a pixel line-height that matches the given height of the input, but only |
||||
|
// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848 |
||||
|
// |
||||
|
// Note that as of 8.3, iOS doesn't support `datetime` or `week`. |
||||
|
|
||||
|
@media screen and (-webkit-min-device-pixel-ratio: 0) { |
||||
|
input[type="date"], |
||||
|
input[type="time"], |
||||
|
input[type="datetime-local"], |
||||
|
input[type="month"] { |
||||
|
&.form-control { |
||||
|
line-height: @input-height-base; |
||||
|
} |
||||
|
|
||||
|
&.input-sm, |
||||
|
.input-group-sm & { |
||||
|
line-height: @input-height-small; |
||||
|
} |
||||
|
|
||||
|
&.input-lg, |
||||
|
.input-group-lg & { |
||||
|
line-height: @input-height-large; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Form groups |
||||
|
// |
||||
|
// Designed to help with the organization and spacing of vertical forms. For |
||||
|
// horizontal forms, use the predefined grid classes. |
||||
|
|
||||
|
.form-group { |
||||
|
margin-bottom: @form-group-margin-bottom; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Checkboxes and radios |
||||
|
// |
||||
|
// Indent the labels to position radios/checkboxes as hanging controls. |
||||
|
|
||||
|
.radio, |
||||
|
.checkbox { |
||||
|
position: relative; |
||||
|
display: block; |
||||
|
margin-top: 10px; |
||||
|
margin-bottom: 10px; |
||||
|
|
||||
|
label { |
||||
|
min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text |
||||
|
padding-left: 20px; |
||||
|
margin-bottom: 0; |
||||
|
font-weight: normal; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
.radio input[type="radio"], |
||||
|
.radio-inline input[type="radio"], |
||||
|
.checkbox input[type="checkbox"], |
||||
|
.checkbox-inline input[type="checkbox"] { |
||||
|
position: absolute; |
||||
|
margin-left: -20px; |
||||
|
margin-top: 4px \9; |
||||
|
} |
||||
|
|
||||
|
.radio + .radio, |
||||
|
.checkbox + .checkbox { |
||||
|
margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing |
||||
|
} |
||||
|
|
||||
|
// Radios and checkboxes on same line |
||||
|
.radio-inline, |
||||
|
.checkbox-inline { |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
padding-left: 20px; |
||||
|
margin-bottom: 0; |
||||
|
vertical-align: middle; |
||||
|
font-weight: normal; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.radio-inline + .radio-inline, |
||||
|
.checkbox-inline + .checkbox-inline { |
||||
|
margin-top: 0; |
||||
|
margin-left: 10px; // space out consecutive inline controls |
||||
|
} |
||||
|
|
||||
|
// Apply same disabled cursor tweak as for inputs |
||||
|
// Some special care is needed because <label>s don't inherit their parent's `cursor`. |
||||
|
// |
||||
|
// Note: Neither radios nor checkboxes can be readonly. |
||||
|
input[type="radio"], |
||||
|
input[type="checkbox"] { |
||||
|
&[disabled], |
||||
|
&.disabled, |
||||
|
fieldset[disabled] & { |
||||
|
cursor: @cursor-disabled; |
||||
|
} |
||||
|
} |
||||
|
// These classes are used directly on <label>s |
||||
|
.radio-inline, |
||||
|
.checkbox-inline { |
||||
|
&.disabled, |
||||
|
fieldset[disabled] & { |
||||
|
cursor: @cursor-disabled; |
||||
|
} |
||||
|
} |
||||
|
// These classes are used on elements with <label> descendants |
||||
|
.radio, |
||||
|
.checkbox { |
||||
|
&.disabled, |
||||
|
fieldset[disabled] & { |
||||
|
label { |
||||
|
cursor: @cursor-disabled; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Static form control text |
||||
|
// |
||||
|
// Apply class to a `p` element to make any string of text align with labels in |
||||
|
// a horizontal form layout. |
||||
|
|
||||
|
.form-control-static { |
||||
|
// Size it appropriately next to real form controls |
||||
|
padding-top: (@padding-base-vertical + 1); |
||||
|
padding-bottom: (@padding-base-vertical + 1); |
||||
|
// Remove default margin from `p` |
||||
|
margin-bottom: 0; |
||||
|
min-height: (@line-height-computed + @font-size-base); |
||||
|
|
||||
|
&.input-lg, |
||||
|
&.input-sm { |
||||
|
padding-left: 0; |
||||
|
padding-right: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Form control sizing |
||||
|
// |
||||
|
// Build on `.form-control` with modifier classes to decrease or increase the |
||||
|
// height and font-size of form controls. |
||||
|
// |
||||
|
// The `.form-group-* form-control` variations are sadly duplicated to avoid the |
||||
|
// issue documented in https://github.com/twbs/bootstrap/issues/15074. |
||||
|
|
||||
|
.input-sm { |
||||
|
.input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small); |
||||
|
} |
||||
|
.form-group-sm { |
||||
|
.form-control { |
||||
|
height: @input-height-small; |
||||
|
padding: @padding-small-vertical @padding-small-horizontal; |
||||
|
font-size: @font-size-small; |
||||
|
line-height: @line-height-small; |
||||
|
border-radius: @input-border-radius-small; |
||||
|
} |
||||
|
select.form-control { |
||||
|
height: @input-height-small; |
||||
|
line-height: @input-height-small; |
||||
|
} |
||||
|
textarea.form-control, |
||||
|
select[multiple].form-control { |
||||
|
height: auto; |
||||
|
} |
||||
|
.form-control-static { |
||||
|
height: @input-height-small; |
||||
|
min-height: (@line-height-computed + @font-size-small); |
||||
|
padding: (@padding-small-vertical + 1) @padding-small-horizontal; |
||||
|
font-size: @font-size-small; |
||||
|
line-height: @line-height-small; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.input-lg { |
||||
|
.input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large); |
||||
|
} |
||||
|
.form-group-lg { |
||||
|
.form-control { |
||||
|
height: @input-height-large; |
||||
|
padding: @padding-large-vertical @padding-large-horizontal; |
||||
|
font-size: @font-size-large; |
||||
|
line-height: @line-height-large; |
||||
|
border-radius: @input-border-radius-large; |
||||
|
} |
||||
|
select.form-control { |
||||
|
height: @input-height-large; |
||||
|
line-height: @input-height-large; |
||||
|
} |
||||
|
textarea.form-control, |
||||
|
select[multiple].form-control { |
||||
|
height: auto; |
||||
|
} |
||||
|
.form-control-static { |
||||
|
height: @input-height-large; |
||||
|
min-height: (@line-height-computed + @font-size-large); |
||||
|
padding: (@padding-large-vertical + 1) @padding-large-horizontal; |
||||
|
font-size: @font-size-large; |
||||
|
line-height: @line-height-large; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Form control feedback states |
||||
|
// |
||||
|
// Apply contextual and semantic states to individual form controls. |
||||
|
|
||||
|
.has-feedback { |
||||
|
// Enable absolute positioning |
||||
|
position: relative; |
||||
|
|
||||
|
// Ensure icons don't overlap text |
||||
|
.form-control { |
||||
|
padding-right: (@input-height-base * 1.25); |
||||
|
} |
||||
|
} |
||||
|
// Feedback icon (requires .glyphicon classes) |
||||
|
.form-control-feedback { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
z-index: 2; // Ensure icon is above input groups |
||||
|
display: block; |
||||
|
width: @input-height-base; |
||||
|
height: @input-height-base; |
||||
|
line-height: @input-height-base; |
||||
|
text-align: center; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
.input-lg + .form-control-feedback, |
||||
|
.input-group-lg + .form-control-feedback, |
||||
|
.form-group-lg .form-control + .form-control-feedback { |
||||
|
width: @input-height-large; |
||||
|
height: @input-height-large; |
||||
|
line-height: @input-height-large; |
||||
|
} |
||||
|
.input-sm + .form-control-feedback, |
||||
|
.input-group-sm + .form-control-feedback, |
||||
|
.form-group-sm .form-control + .form-control-feedback { |
||||
|
width: @input-height-small; |
||||
|
height: @input-height-small; |
||||
|
line-height: @input-height-small; |
||||
|
} |
||||
|
|
||||
|
// Feedback states |
||||
|
.has-success { |
||||
|
.form-control-validation(@state-success-text; @state-success-text; @state-success-bg); |
||||
|
} |
||||
|
.has-warning { |
||||
|
.form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg); |
||||
|
} |
||||
|
.has-error { |
||||
|
.form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg); |
||||
|
} |
||||
|
|
||||
|
// Reposition feedback icon if input has visible label above |
||||
|
.has-feedback label { |
||||
|
|
||||
|
& ~ .form-control-feedback { |
||||
|
top: (@line-height-computed + 5); // Height of the `label` and its margin |
||||
|
} |
||||
|
&.sr-only ~ .form-control-feedback { |
||||
|
top: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Help text |
||||
|
// |
||||
|
// Apply to any element you wish to create light text for placement immediately |
||||
|
// below a form control. Use for general help, formatting, or instructional text. |
||||
|
|
||||
|
.help-block { |
||||
|
display: block; // account for any element using help-block |
||||
|
margin-top: 5px; |
||||
|
margin-bottom: 10px; |
||||
|
color: lighten(@text-color, 25%); // lighten the text some for contrast |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Inline forms |
||||
|
// |
||||
|
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline |
||||
|
// forms begin stacked on extra small (mobile) devices and then go inline when |
||||
|
// viewports reach <768px. |
||||
|
// |
||||
|
// Requires wrapping inputs and labels with `.form-group` for proper display of |
||||
|
// default HTML form controls and our custom form controls (e.g., input groups). |
||||
|
// |
||||
|
// Heads up! This is mixin-ed into `.navbar-form` in navbars.less. |
||||
|
|
||||
|
.form-inline { |
||||
|
|
||||
|
// Kick in the inline |
||||
|
@media (min-width: @screen-sm-min) { |
||||
|
// Inline-block all the things for "inline" |
||||
|
.form-group { |
||||
|
display: inline-block; |
||||
|
margin-bottom: 0; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
// In navbar-form, allow folks to *not* use `.form-group` |
||||
|
.form-control { |
||||
|
display: inline-block; |
||||
|
width: auto; // Prevent labels from stacking above inputs in `.form-group` |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
// Make static controls behave like regular ones |
||||
|
.form-control-static { |
||||
|
display: inline-block; |
||||
|
} |
||||
|
|
||||
|
.input-group { |
||||
|
display: inline-table; |
||||
|
vertical-align: middle; |
||||
|
|
||||
|
.input-group-addon, |
||||
|
.input-group-btn, |
||||
|
.form-control { |
||||
|
width: auto; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Input groups need that 100% width though |
||||
|
.input-group > .form-control { |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.control-label { |
||||
|
margin-bottom: 0; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
// Remove default margin on radios/checkboxes that were used for stacking, and |
||||
|
// then undo the floating of radios and checkboxes to match. |
||||
|
.radio, |
||||
|
.checkbox { |
||||
|
display: inline-block; |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 0; |
||||
|
vertical-align: middle; |
||||
|
|
||||
|
label { |
||||
|
padding-left: 0; |
||||
|
} |
||||
|
} |
||||
|
.radio input[type="radio"], |
||||
|
.checkbox input[type="checkbox"] { |
||||
|
position: relative; |
||||
|
margin-left: 0; |
||||
|
} |
||||
|
|
||||
|
// Re-override the feedback icon. |
||||
|
.has-feedback .form-control-feedback { |
||||
|
top: 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Horizontal forms |
||||
|
// |
||||
|
// Horizontal forms are built on grid classes and allow you to create forms with |
||||
|
// labels on the left and inputs on the right. |
||||
|
|
||||
|
.form-horizontal { |
||||
|
|
||||
|
// Consistent vertical alignment of radios and checkboxes |
||||
|
// |
||||
|
// Labels also get some reset styles, but that is scoped to a media query below. |
||||
|
.radio, |
||||
|
.checkbox, |
||||
|
.radio-inline, |
||||
|
.checkbox-inline { |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 0; |
||||
|
padding-top: (@padding-base-vertical + 1); // Default padding plus a border |
||||
|
} |
||||
|
// Account for padding we're adding to ensure the alignment and of help text |
||||
|
// and other content below items |
||||
|
.radio, |
||||
|
.checkbox { |
||||
|
min-height: (@line-height-computed + (@padding-base-vertical + 1)); |
||||
|
} |
||||
|
|
||||
|
// Make form groups behave like rows |
||||
|
.form-group { |
||||
|
.make-row(); |
||||
|
} |
||||
|
|
||||
|
// Reset spacing and right align labels, but scope to media queries so that |
||||
|
// labels on narrow viewports stack the same as a default form example. |
||||
|
@media (min-width: @screen-sm-min) { |
||||
|
.control-label { |
||||
|
text-align: right; |
||||
|
margin-bottom: 0; |
||||
|
padding-top: (@padding-base-vertical + 1); // Default padding plus a border |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Validation states |
||||
|
// |
||||
|
// Reposition the icon because it's now within a grid column and columns have |
||||
|
// `position: relative;` on them. Also accounts for the grid gutter padding. |
||||
|
.has-feedback .form-control-feedback { |
||||
|
right: floor((@grid-gutter-width / 2)); |
||||
|
} |
||||
|
|
||||
|
// Form group sizes |
||||
|
// |
||||
|
// Quick utility class for applying `.input-lg` and `.input-sm` styles to the |
||||
|
// inputs and labels within a `.form-group`. |
||||
|
.form-group-lg { |
||||
|
@media (min-width: @screen-sm-min) { |
||||
|
.control-label { |
||||
|
padding-top: ((@padding-large-vertical * @line-height-large) + 1); |
||||
|
font-size: @font-size-large; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.form-group-sm { |
||||
|
@media (min-width: @screen-sm-min) { |
||||
|
.control-label { |
||||
|
padding-top: (@padding-small-vertical + 1); |
||||
|
font-size: @font-size-small; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,305 @@ |
|||||
|
// |
||||
|
// Glyphicons for Bootstrap |
||||
|
// |
||||
|
// Since icons are fonts, they can be placed anywhere text is placed and are |
||||
|
// thus automatically sized to match the surrounding child. To use, create an |
||||
|
// inline element with the appropriate classes, like so: |
||||
|
// |
||||
|
// <a href="#"><span class="glyphicon glyphicon-star"></span> Star</a> |
||||
|
|
||||
|
// Import the fonts |
||||
|
@font-face { |
||||
|
font-family: 'Glyphicons Halflings'; |
||||
|
src: url('@{icon-font-path}@{icon-font-name}.eot'); |
||||
|
src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'), |
||||
|
url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'), |
||||
|
url('@{icon-font-path}@{icon-font-name}.woff') format('woff'), |
||||
|
url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'), |
||||
|
url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg'); |
||||
|
} |
||||
|
|
||||
|
// Catchall baseclass |
||||
|
.glyphicon { |
||||
|
position: relative; |
||||
|
top: 1px; |
||||
|
display: inline-block; |
||||
|
font-family: 'Glyphicons Halflings'; |
||||
|
font-style: normal; |
||||
|
font-weight: normal; |
||||
|
line-height: 1; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
|
||||
|
// Individual icons |
||||
|
.glyphicon-asterisk { &:before { content: "\2a"; } } |
||||
|
.glyphicon-plus { &:before { content: "\2b"; } } |
||||
|
.glyphicon-euro, |
||||
|
.glyphicon-eur { &:before { content: "\20ac"; } } |
||||
|
.glyphicon-minus { &:before { content: "\2212"; } } |
||||
|
.glyphicon-cloud { &:before { content: "\2601"; } } |
||||
|
.glyphicon-envelope { &:before { content: "\2709"; } } |
||||
|
.glyphicon-pencil { &:before { content: "\270f"; } } |
||||
|
.glyphicon-glass { &:before { content: "\e001"; } } |
||||
|
.glyphicon-music { &:before { content: "\e002"; } } |
||||
|
.glyphicon-search { &:before { content: "\e003"; } } |
||||
|
.glyphicon-heart { &:before { content: "\e005"; } } |
||||
|
.glyphicon-star { &:before { content: "\e006"; } } |
||||
|
.glyphicon-star-empty { &:before { content: "\e007"; } } |
||||
|
.glyphicon-user { &:before { content: "\e008"; } } |
||||
|
.glyphicon-film { &:before { content: "\e009"; } } |
||||
|
.glyphicon-th-large { &:before { content: "\e010"; } } |
||||
|
.glyphicon-th { &:before { content: "\e011"; } } |
||||
|
.glyphicon-th-list { &:before { content: "\e012"; } } |
||||
|
.glyphicon-ok { &:before { content: "\e013"; } } |
||||
|
.glyphicon-remove { &:before { content: "\e014"; } } |
||||
|
.glyphicon-zoom-in { &:before { content: "\e015"; } } |
||||
|
.glyphicon-zoom-out { &:before { content: "\e016"; } } |
||||
|
.glyphicon-off { &:before { content: "\e017"; } } |
||||
|
.glyphicon-signal { &:before { content: "\e018"; } } |
||||
|
.glyphicon-cog { &:before { content: "\e019"; } } |
||||
|
.glyphicon-trash { &:before { content: "\e020"; } } |
||||
|
.glyphicon-home { &:before { content: "\e021"; } } |
||||
|
.glyphicon-file { &:before { content: "\e022"; } } |
||||
|
.glyphicon-time { &:before { content: "\e023"; } } |
||||
|
.glyphicon-road { &:before { content: "\e024"; } } |
||||
|
.glyphicon-download-alt { &:before { content: "\e025"; } } |
||||
|
.glyphicon-download { &:before { content: "\e026"; } } |
||||
|
.glyphicon-upload { &:before { content: "\e027"; } } |
||||
|
.glyphicon-inbox { &:before { content: "\e028"; } } |
||||
|
.glyphicon-play-circle { &:before { content: "\e029"; } } |
||||
|
.glyphicon-repeat { &:before { content: "\e030"; } } |
||||
|
.glyphicon-refresh { &:before { content: "\e031"; } } |
||||
|
.glyphicon-list-alt { &:before { content: "\e032"; } } |
||||
|
.glyphicon-lock { &:before { content: "\e033"; } } |
||||
|
.glyphicon-flag { &:before { content: "\e034"; } } |
||||
|
.glyphicon-headphones { &:before { content: "\e035"; } } |
||||
|
.glyphicon-volume-off { &:before { content: "\e036"; } } |
||||
|
.glyphicon-volume-down { &:before { content: "\e037"; } } |
||||
|
.glyphicon-volume-up { &:before { content: "\e038"; } } |
||||
|
.glyphicon-qrcode { &:before { content: "\e039"; } } |
||||
|
.glyphicon-barcode { &:before { content: "\e040"; } } |
||||
|
.glyphicon-tag { &:before { content: "\e041"; } } |
||||
|
.glyphicon-tags { &:before { content: "\e042"; } } |
||||
|
.glyphicon-book { &:before { content: "\e043"; } } |
||||
|
.glyphicon-bookmark { &:before { content: "\e044"; } } |
||||
|
.glyphicon-print { &:before { content: "\e045"; } } |
||||
|
.glyphicon-camera { &:before { content: "\e046"; } } |
||||
|
.glyphicon-font { &:before { content: "\e047"; } } |
||||
|
.glyphicon-bold { &:before { content: "\e048"; } } |
||||
|
.glyphicon-italic { &:before { content: "\e049"; } } |
||||
|
.glyphicon-text-height { &:before { content: "\e050"; } } |
||||
|
.glyphicon-text-width { &:before { content: "\e051"; } } |
||||
|
.glyphicon-align-left { &:before { content: "\e052"; } } |
||||
|
.glyphicon-align-center { &:before { content: "\e053"; } } |
||||
|
.glyphicon-align-right { &:before { content: "\e054"; } } |
||||
|
.glyphicon-align-justify { &:before { content: "\e055"; } } |
||||
|
.glyphicon-list { &:before { content: "\e056"; } } |
||||
|
.glyphicon-indent-left { &:before { content: "\e057"; } } |
||||
|
.glyphicon-indent-right { &:before { content: "\e058"; } } |
||||
|
.glyphicon-facetime-video { &:before { content: "\e059"; } } |
||||
|
.glyphicon-picture { &:before { content: "\e060"; } } |
||||
|
.glyphicon-map-marker { &:before { content: "\e062"; } } |
||||
|
.glyphicon-adjust { &:before { content: "\e063"; } } |
||||
|
.glyphicon-tint { &:before { content: "\e064"; } } |
||||
|
.glyphicon-edit { &:before { content: "\e065"; } } |
||||
|
.glyphicon-share { &:before { content: "\e066"; } } |
||||
|
.glyphicon-check { &:before { content: "\e067"; } } |
||||
|
.glyphicon-move { &:before { content: "\e068"; } } |
||||
|
.glyphicon-step-backward { &:before { content: "\e069"; } } |
||||
|
.glyphicon-fast-backward { &:before { content: "\e070"; } } |
||||
|
.glyphicon-backward { &:before { content: "\e071"; } } |
||||
|
.glyphicon-play { &:before { content: "\e072"; } } |
||||
|
.glyphicon-pause { &:before { content: "\e073"; } } |
||||
|
.glyphicon-stop { &:before { content: "\e074"; } } |
||||
|
.glyphicon-forward { &:before { content: "\e075"; } } |
||||
|
.glyphicon-fast-forward { &:before { content: "\e076"; } } |
||||
|
.glyphicon-step-forward { &:before { content: "\e077"; } } |
||||
|
.glyphicon-eject { &:before { content: "\e078"; } } |
||||
|
.glyphicon-chevron-left { &:before { content: "\e079"; } } |
||||
|
.glyphicon-chevron-right { &:before { content: "\e080"; } } |
||||
|
.glyphicon-plus-sign { &:before { content: "\e081"; } } |
||||
|
.glyphicon-minus-sign { &:before { content: "\e082"; } } |
||||
|
.glyphicon-remove-sign { &:before { content: "\e083"; } } |
||||
|
.glyphicon-ok-sign { &:before { content: "\e084"; } } |
||||
|
.glyphicon-question-sign { &:before { content: "\e085"; } } |
||||
|
.glyphicon-info-sign { &:before { content: "\e086"; } } |
||||
|
.glyphicon-screenshot { &:before { content: "\e087"; } } |
||||
|
.glyphicon-remove-circle { &:before { content: "\e088"; } } |
||||
|
.glyphicon-ok-circle { &:before { content: "\e089"; } } |
||||
|
.glyphicon-ban-circle { &:before { content: "\e090"; } } |
||||
|
.glyphicon-arrow-left { &:before { content: "\e091"; } } |
||||
|
.glyphicon-arrow-right { &:before { content: "\e092"; } } |
||||
|
.glyphicon-arrow-up { &:before { content: "\e093"; } } |
||||
|
.glyphicon-arrow-down { &:before { content: "\e094"; } } |
||||
|
.glyphicon-share-alt { &:before { content: "\e095"; } } |
||||
|
.glyphicon-resize-full { &:before { content: "\e096"; } } |
||||
|
.glyphicon-resize-small { &:before { content: "\e097"; } } |
||||
|
.glyphicon-exclamation-sign { &:before { content: "\e101"; } } |
||||
|
.glyphicon-gift { &:before { content: "\e102"; } } |
||||
|
.glyphicon-leaf { &:before { content: "\e103"; } } |
||||
|
.glyphicon-fire { &:before { content: "\e104"; } } |
||||
|
.glyphicon-eye-open { &:before { content: "\e105"; } } |
||||
|
.glyphicon-eye-close { &:before { content: "\e106"; } } |
||||
|
.glyphicon-warning-sign { &:before { content: "\e107"; } } |
||||
|
.glyphicon-plane { &:before { content: "\e108"; } } |
||||
|
.glyphicon-calendar { &:before { content: "\e109"; } } |
||||
|
.glyphicon-random { &:before { content: "\e110"; } } |
||||
|
.glyphicon-comment { &:before { content: "\e111"; } } |
||||
|
.glyphicon-magnet { &:before { content: "\e112"; } } |
||||
|
.glyphicon-chevron-up { &:before { content: "\e113"; } } |
||||
|
.glyphicon-chevron-down { &:before { content: "\e114"; } } |
||||
|
.glyphicon-retweet { &:before { content: "\e115"; } } |
||||
|
.glyphicon-shopping-cart { &:before { content: "\e116"; } } |
||||
|
.glyphicon-folder-close { &:before { content: "\e117"; } } |
||||
|
.glyphicon-folder-open { &:before { content: "\e118"; } } |
||||
|
.glyphicon-resize-vertical { &:before { content: "\e119"; } } |
||||
|
.glyphicon-resize-horizontal { &:before { content: "\e120"; } } |
||||
|
.glyphicon-hdd { &:before { content: "\e121"; } } |
||||
|
.glyphicon-bullhorn { &:before { content: "\e122"; } } |
||||
|
.glyphicon-bell { &:before { content: "\e123"; } } |
||||
|
.glyphicon-certificate { &:before { content: "\e124"; } } |
||||
|
.glyphicon-thumbs-up { &:before { content: "\e125"; } } |
||||
|
.glyphicon-thumbs-down { &:before { content: "\e126"; } } |
||||
|
.glyphicon-hand-right { &:before { content: "\e127"; } } |
||||
|
.glyphicon-hand-left { &:before { content: "\e128"; } } |
||||
|
.glyphicon-hand-up { &:before { content: "\e129"; } } |
||||
|
.glyphicon-hand-down { &:before { content: "\e130"; } } |
||||
|
.glyphicon-circle-arrow-right { &:before { content: "\e131"; } } |
||||
|
.glyphicon-circle-arrow-left { &:before { content: "\e132"; } } |
||||
|
.glyphicon-circle-arrow-up { &:before { content: "\e133"; } } |
||||
|
.glyphicon-circle-arrow-down { &:before { content: "\e134"; } } |
||||
|
.glyphicon-globe { &:before { content: "\e135"; } } |
||||
|
.glyphicon-wrench { &:before { content: "\e136"; } } |
||||
|
.glyphicon-tasks { &:before { content: "\e137"; } } |
||||
|
.glyphicon-filter { &:before { content: "\e138"; } } |
||||
|
.glyphicon-briefcase { &:before { content: "\e139"; } } |
||||
|
.glyphicon-fullscreen { &:before { content: "\e140"; } } |
||||
|
.glyphicon-dashboard { &:before { content: "\e141"; } } |
||||
|
.glyphicon-paperclip { &:before { content: "\e142"; } } |
||||
|
.glyphicon-heart-empty { &:before { content: "\e143"; } } |
||||
|
.glyphicon-link { &:before { content: "\e144"; } } |
||||
|
.glyphicon-phone { &:before { content: "\e145"; } } |
||||
|
.glyphicon-pushpin { &:before { content: "\e146"; } } |
||||
|
.glyphicon-usd { &:before { content: "\e148"; } } |
||||
|
.glyphicon-gbp { &:before { content: "\e149"; } } |
||||
|
.glyphicon-sort { &:before { content: "\e150"; } } |
||||
|
.glyphicon-sort-by-alphabet { &:before { content: "\e151"; } } |
||||
|
.glyphicon-sort-by-alphabet-alt { &:before { content: "\e152"; } } |
||||
|
.glyphicon-sort-by-order { &:before { content: "\e153"; } } |
||||
|
.glyphicon-sort-by-order-alt { &:before { content: "\e154"; } } |
||||
|
.glyphicon-sort-by-attributes { &:before { content: "\e155"; } } |
||||
|
.glyphicon-sort-by-attributes-alt { &:before { content: "\e156"; } } |
||||
|
.glyphicon-unchecked { &:before { content: "\e157"; } } |
||||
|
.glyphicon-expand { &:before { content: "\e158"; } } |
||||
|
.glyphicon-collapse-down { &:before { content: "\e159"; } } |
||||
|
.glyphicon-collapse-up { &:before { content: "\e160"; } } |
||||
|
.glyphicon-log-in { &:before { content: "\e161"; } } |
||||
|
.glyphicon-flash { &:before { content: "\e162"; } } |
||||
|
.glyphicon-log-out { &:before { content: "\e163"; } } |
||||
|
.glyphicon-new-window { &:before { content: "\e164"; } } |
||||
|
.glyphicon-record { &:before { content: "\e165"; } } |
||||
|
.glyphicon-save { &:before { content: "\e166"; } } |
||||
|
.glyphicon-open { &:before { content: "\e167"; } } |
||||
|
.glyphicon-saved { &:before { content: "\e168"; } } |
||||
|
.glyphicon-import { &:before { content: "\e169"; } } |
||||
|
.glyphicon-export { &:before { content: "\e170"; } } |
||||
|
.glyphicon-send { &:before { content: "\e171"; } } |
||||
|
.glyphicon-floppy-disk { &:before { content: "\e172"; } } |
||||
|
.glyphicon-floppy-saved { &:before { content: "\e173"; } } |
||||
|
.glyphicon-floppy-remove { &:before { content: "\e174"; } } |
||||
|
.glyphicon-floppy-save { &:before { content: "\e175"; } } |
||||
|
.glyphicon-floppy-open { &:before { content: "\e176"; } } |
||||
|
.glyphicon-credit-card { &:before { content: "\e177"; } } |
||||
|
.glyphicon-transfer { &:before { content: "\e178"; } } |
||||
|
.glyphicon-cutlery { &:before { content: "\e179"; } } |
||||
|
.glyphicon-header { &:before { content: "\e180"; } } |
||||
|
.glyphicon-compressed { &:before { content: "\e181"; } } |
||||
|
.glyphicon-earphone { &:before { content: "\e182"; } } |
||||
|
.glyphicon-phone-alt { &:before { content: "\e183"; } } |
||||
|
.glyphicon-tower { &:before { content: "\e184"; } } |
||||
|
.glyphicon-stats { &:before { content: "\e185"; } } |
||||
|
.glyphicon-sd-video { &:before { content: "\e186"; } } |
||||
|
.glyphicon-hd-video { &:before { content: "\e187"; } } |
||||
|
.glyphicon-subtitles { &:before { content: "\e188"; } } |
||||
|
.glyphicon-sound-stereo { &:before { content: "\e189"; } } |
||||
|
.glyphicon-sound-dolby { &:before { content: "\e190"; } } |
||||
|
.glyphicon-sound-5-1 { &:before { content: "\e191"; } } |
||||
|
.glyphicon-sound-6-1 { &:before { content: "\e192"; } } |
||||
|
.glyphicon-sound-7-1 { &:before { content: "\e193"; } } |
||||
|
.glyphicon-copyright-mark { &:before { content: "\e194"; } } |
||||
|
.glyphicon-registration-mark { &:before { content: "\e195"; } } |
||||
|
.glyphicon-cloud-download { &:before { content: "\e197"; } } |
||||
|
.glyphicon-cloud-upload { &:before { content: "\e198"; } } |
||||
|
.glyphicon-tree-conifer { &:before { content: "\e199"; } } |
||||
|
.glyphicon-tree-deciduous { &:before { content: "\e200"; } } |
||||
|
.glyphicon-cd { &:before { content: "\e201"; } } |
||||
|
.glyphicon-save-file { &:before { content: "\e202"; } } |
||||
|
.glyphicon-open-file { &:before { content: "\e203"; } } |
||||
|
.glyphicon-level-up { &:before { content: "\e204"; } } |
||||
|
.glyphicon-copy { &:before { content: "\e205"; } } |
||||
|
.glyphicon-paste { &:before { content: "\e206"; } } |
||||
|
// The following 2 Glyphicons are omitted for the time being because |
||||
|
// they currently use Unicode codepoints that are outside the |
||||
|
// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle |
||||
|
// non-BMP codepoints in CSS string escapes, and thus can't display these two icons. |
||||
|
// Notably, the bug affects some older versions of the Android Browser. |
||||
|
// More info: https://github.com/twbs/bootstrap/issues/10106 |
||||
|
// .glyphicon-door { &:before { content: "\1f6aa"; } } |
||||
|
// .glyphicon-key { &:before { content: "\1f511"; } } |
||||
|
.glyphicon-alert { &:before { content: "\e209"; } } |
||||
|
.glyphicon-equalizer { &:before { content: "\e210"; } } |
||||
|
.glyphicon-king { &:before { content: "\e211"; } } |
||||
|
.glyphicon-queen { &:before { content: "\e212"; } } |
||||
|
.glyphicon-pawn { &:before { content: "\e213"; } } |
||||
|
.glyphicon-bishop { &:before { content: "\e214"; } } |
||||
|
.glyphicon-knight { &:before { content: "\e215"; } } |
||||
|
.glyphicon-baby-formula { &:before { content: "\e216"; } } |
||||
|
.glyphicon-tent { &:before { content: "\26fa"; } } |
||||
|
.glyphicon-blackboard { &:before { content: "\e218"; } } |
||||
|
.glyphicon-bed { &:before { content: "\e219"; } } |
||||
|
.glyphicon-apple { &:before { content: "\f8ff"; } } |
||||
|
.glyphicon-erase { &:before { content: "\e221"; } } |
||||
|
.glyphicon-hourglass { &:before { content: "\231b"; } } |
||||
|
.glyphicon-lamp { &:before { content: "\e223"; } } |
||||
|
.glyphicon-duplicate { &:before { content: "\e224"; } } |
||||
|
.glyphicon-piggy-bank { &:before { content: "\e225"; } } |
||||
|
.glyphicon-scissors { &:before { content: "\e226"; } } |
||||
|
.glyphicon-bitcoin { &:before { content: "\e227"; } } |
||||
|
.glyphicon-btc { &:before { content: "\e227"; } } |
||||
|
.glyphicon-xbt { &:before { content: "\e227"; } } |
||||
|
.glyphicon-yen { &:before { content: "\00a5"; } } |
||||
|
.glyphicon-jpy { &:before { content: "\00a5"; } } |
||||
|
.glyphicon-ruble { &:before { content: "\20bd"; } } |
||||
|
.glyphicon-rub { &:before { content: "\20bd"; } } |
||||
|
.glyphicon-scale { &:before { content: "\e230"; } } |
||||
|
.glyphicon-ice-lolly { &:before { content: "\e231"; } } |
||||
|
.glyphicon-ice-lolly-tasted { &:before { content: "\e232"; } } |
||||
|
.glyphicon-education { &:before { content: "\e233"; } } |
||||
|
.glyphicon-option-horizontal { &:before { content: "\e234"; } } |
||||
|
.glyphicon-option-vertical { &:before { content: "\e235"; } } |
||||
|
.glyphicon-menu-hamburger { &:before { content: "\e236"; } } |
||||
|
.glyphicon-modal-window { &:before { content: "\e237"; } } |
||||
|
.glyphicon-oil { &:before { content: "\e238"; } } |
||||
|
.glyphicon-grain { &:before { content: "\e239"; } } |
||||
|
.glyphicon-sunglasses { &:before { content: "\e240"; } } |
||||
|
.glyphicon-text-size { &:before { content: "\e241"; } } |
||||
|
.glyphicon-text-color { &:before { content: "\e242"; } } |
||||
|
.glyphicon-text-background { &:before { content: "\e243"; } } |
||||
|
.glyphicon-object-align-top { &:before { content: "\e244"; } } |
||||
|
.glyphicon-object-align-bottom { &:before { content: "\e245"; } } |
||||
|
.glyphicon-object-align-horizontal{ &:before { content: "\e246"; } } |
||||
|
.glyphicon-object-align-left { &:before { content: "\e247"; } } |
||||
|
.glyphicon-object-align-vertical { &:before { content: "\e248"; } } |
||||
|
.glyphicon-object-align-right { &:before { content: "\e249"; } } |
||||
|
.glyphicon-triangle-right { &:before { content: "\e250"; } } |
||||
|
.glyphicon-triangle-left { &:before { content: "\e251"; } } |
||||
|
.glyphicon-triangle-bottom { &:before { content: "\e252"; } } |
||||
|
.glyphicon-triangle-top { &:before { content: "\e253"; } } |
||||
|
.glyphicon-console { &:before { content: "\e254"; } } |
||||
|
.glyphicon-superscript { &:before { content: "\e255"; } } |
||||
|
.glyphicon-subscript { &:before { content: "\e256"; } } |
||||
|
.glyphicon-menu-left { &:before { content: "\e257"; } } |
||||
|
.glyphicon-menu-right { &:before { content: "\e258"; } } |
||||
|
.glyphicon-menu-down { &:before { content: "\e259"; } } |
||||
|
.glyphicon-menu-up { &:before { content: "\e260"; } } |
@ -0,0 +1,84 @@ |
|||||
|
// |
||||
|
// Grid system |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Container widths |
||||
|
// |
||||
|
// Set the container width, and override it for fixed navbars in media queries. |
||||
|
|
||||
|
.container { |
||||
|
.container-fixed(); |
||||
|
|
||||
|
@media (min-width: @screen-sm-min) { |
||||
|
width: @container-sm; |
||||
|
} |
||||
|
@media (min-width: @screen-md-min) { |
||||
|
width: @container-md; |
||||
|
} |
||||
|
@media (min-width: @screen-lg-min) { |
||||
|
width: @container-lg; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Fluid container |
||||
|
// |
||||
|
// Utilizes the mixin meant for fixed width containers, but without any defined |
||||
|
// width for fluid, full width layouts. |
||||
|
|
||||
|
.container-fluid { |
||||
|
.container-fixed(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Row |
||||
|
// |
||||
|
// Rows contain and clear the floats of your columns. |
||||
|
|
||||
|
.row { |
||||
|
.make-row(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Columns |
||||
|
// |
||||
|
// Common styles for small and large grid columns |
||||
|
|
||||
|
.make-grid-columns(); |
||||
|
|
||||
|
|
||||
|
// Extra small grid |
||||
|
// |
||||
|
// Columns, offsets, pushes, and pulls for extra small devices like |
||||
|
// smartphones. |
||||
|
|
||||
|
.make-grid(xs); |
||||
|
|
||||
|
|
||||
|
// Small grid |
||||
|
// |
||||
|
// Columns, offsets, pushes, and pulls for the small device range, from phones |
||||
|
// to tablets. |
||||
|
|
||||
|
@media (min-width: @screen-sm-min) { |
||||
|
.make-grid(sm); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Medium grid |
||||
|
// |
||||
|
// Columns, offsets, pushes, and pulls for the desktop device range. |
||||
|
|
||||
|
@media (min-width: @screen-md-min) { |
||||
|
.make-grid(md); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Large grid |
||||
|
// |
||||
|
// Columns, offsets, pushes, and pulls for the large desktop device range. |
||||
|
|
||||
|
@media (min-width: @screen-lg-min) { |
||||
|
.make-grid(lg); |
||||
|
} |
@ -0,0 +1,167 @@ |
|||||
|
// |
||||
|
// Input groups |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
// Base styles |
||||
|
// ------------------------- |
||||
|
.input-group { |
||||
|
position: relative; // For dropdowns |
||||
|
display: table; |
||||
|
border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table |
||||
|
|
||||
|
// Undo padding and float of grid classes |
||||
|
&[class*="col-"] { |
||||
|
float: none; |
||||
|
padding-left: 0; |
||||
|
padding-right: 0; |
||||
|
} |
||||
|
|
||||
|
.form-control { |
||||
|
// Ensure that the input is always above the *appended* addon button for |
||||
|
// proper border colors. |
||||
|
position: relative; |
||||
|
z-index: 2; |
||||
|
|
||||
|
// IE9 fubars the placeholder attribute in text inputs and the arrows on |
||||
|
// select elements in input groups. To fix it, we float the input. Details: |
||||
|
// https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855 |
||||
|
float: left; |
||||
|
|
||||
|
width: 100%; |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Sizing options |
||||
|
// |
||||
|
// Remix the default form control sizing classes into new ones for easier |
||||
|
// manipulation. |
||||
|
|
||||
|
.input-group-lg > .form-control, |
||||
|
.input-group-lg > .input-group-addon, |
||||
|
.input-group-lg > .input-group-btn > .btn { |
||||
|
.input-lg(); |
||||
|
} |
||||
|
.input-group-sm > .form-control, |
||||
|
.input-group-sm > .input-group-addon, |
||||
|
.input-group-sm > .input-group-btn > .btn { |
||||
|
.input-sm(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Display as table-cell |
||||
|
// ------------------------- |
||||
|
.input-group-addon, |
||||
|
.input-group-btn, |
||||
|
.input-group .form-control { |
||||
|
display: table-cell; |
||||
|
|
||||
|
&:not(:first-child):not(:last-child) { |
||||
|
border-radius: 0; |
||||
|
} |
||||
|
} |
||||
|
// Addon and addon wrapper for buttons |
||||
|
.input-group-addon, |
||||
|
.input-group-btn { |
||||
|
width: 1%; |
||||
|
white-space: nowrap; |
||||
|
vertical-align: middle; // Match the inputs |
||||
|
} |
||||
|
|
||||
|
// Text input groups |
||||
|
// ------------------------- |
||||
|
.input-group-addon { |
||||
|
padding: @padding-base-vertical @padding-base-horizontal; |
||||
|
font-size: @font-size-base; |
||||
|
font-weight: normal; |
||||
|
line-height: 1; |
||||
|
color: @input-color; |
||||
|
text-align: center; |
||||
|
background-color: @input-group-addon-bg; |
||||
|
border: 1px solid @input-group-addon-border-color; |
||||
|
border-radius: @border-radius-base; |
||||
|
|
||||
|
// Sizing |
||||
|
&.input-sm { |
||||
|
padding: @padding-small-vertical @padding-small-horizontal; |
||||
|
font-size: @font-size-small; |
||||
|
border-radius: @border-radius-small; |
||||
|
} |
||||
|
&.input-lg { |
||||
|
padding: @padding-large-vertical @padding-large-horizontal; |
||||
|
font-size: @font-size-large; |
||||
|
border-radius: @border-radius-large; |
||||
|
} |
||||
|
|
||||
|
// Nuke default margins from checkboxes and radios to vertically center within. |
||||
|
input[type="radio"], |
||||
|
input[type="checkbox"] { |
||||
|
margin-top: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Reset rounded corners |
||||
|
.input-group .form-control:first-child, |
||||
|
.input-group-addon:first-child, |
||||
|
.input-group-btn:first-child > .btn, |
||||
|
.input-group-btn:first-child > .btn-group > .btn, |
||||
|
.input-group-btn:first-child > .dropdown-toggle, |
||||
|
.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), |
||||
|
.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { |
||||
|
.border-right-radius(0); |
||||
|
} |
||||
|
.input-group-addon:first-child { |
||||
|
border-right: 0; |
||||
|
} |
||||
|
.input-group .form-control:last-child, |
||||
|
.input-group-addon:last-child, |
||||
|
.input-group-btn:last-child > .btn, |
||||
|
.input-group-btn:last-child > .btn-group > .btn, |
||||
|
.input-group-btn:last-child > .dropdown-toggle, |
||||
|
.input-group-btn:first-child > .btn:not(:first-child), |
||||
|
.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { |
||||
|
.border-left-radius(0); |
||||
|
} |
||||
|
.input-group-addon:last-child { |
||||
|
border-left: 0; |
||||
|
} |
||||
|
|
||||
|
// Button input groups |
||||
|
// ------------------------- |
||||
|
.input-group-btn { |
||||
|
position: relative; |
||||
|
// Jankily prevent input button groups from wrapping with `white-space` and |
||||
|
// `font-size` in combination with `inline-block` on buttons. |
||||
|
font-size: 0; |
||||
|
white-space: nowrap; |
||||
|
|
||||
|
// Negative margin for spacing, position for bringing hovered/focused/actived |
||||
|
// element above the siblings. |
||||
|
> .btn { |
||||
|
position: relative; |
||||
|
+ .btn { |
||||
|
margin-left: -1px; |
||||
|
} |
||||
|
// Bring the "active" button to the front |
||||
|
&:hover, |
||||
|
&:focus, |
||||
|
&:active { |
||||
|
z-index: 2; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Negative margin to only have a 1px border between the two |
||||
|
&:first-child { |
||||
|
> .btn, |
||||
|
> .btn-group { |
||||
|
margin-right: -1px; |
||||
|
} |
||||
|
} |
||||
|
&:last-child { |
||||
|
> .btn, |
||||
|
> .btn-group { |
||||
|
z-index: 2; |
||||
|
margin-left: -1px; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,52 @@ |
|||||
|
// |
||||
|
// Jumbotron |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
.jumbotron { |
||||
|
padding-top: @jumbotron-padding; |
||||
|
padding-bottom: @jumbotron-padding; |
||||
|
margin-bottom: @jumbotron-padding; |
||||
|
color: @jumbotron-color; |
||||
|
background-color: @jumbotron-bg; |
||||
|
|
||||
|
h1, |
||||
|
.h1 { |
||||
|
color: @jumbotron-heading-color; |
||||
|
} |
||||
|
|
||||
|
p { |
||||
|
margin-bottom: (@jumbotron-padding / 2); |
||||
|
font-size: @jumbotron-font-size; |
||||
|
font-weight: 200; |
||||
|
} |
||||
|
|
||||
|
> hr { |
||||
|
border-top-color: darken(@jumbotron-bg, 10%); |
||||
|
} |
||||
|
|
||||
|
.container &, |
||||
|
.container-fluid & { |
||||
|
border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container |
||||
|
} |
||||
|
|
||||
|
.container { |
||||
|
max-width: 100%; |
||||
|
} |
||||
|
|
||||
|
@media screen and (min-width: @screen-sm-min) { |
||||
|
padding-top: (@jumbotron-padding * 1.6); |
||||
|
padding-bottom: (@jumbotron-padding * 1.6); |
||||
|
|
||||
|
.container &, |
||||
|
.container-fluid & { |
||||
|
padding-left: (@jumbotron-padding * 2); |
||||
|
padding-right: (@jumbotron-padding * 2); |
||||
|
} |
||||
|
|
||||
|
h1, |
||||
|
.h1 { |
||||
|
font-size: @jumbotron-heading-font-size; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,64 @@ |
|||||
|
// |
||||
|
// Labels |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
.label { |
||||
|
display: inline; |
||||
|
padding: .2em .6em .3em; |
||||
|
font-size: 75%; |
||||
|
font-weight: bold; |
||||
|
line-height: 1; |
||||
|
color: @label-color; |
||||
|
text-align: center; |
||||
|
white-space: nowrap; |
||||
|
vertical-align: baseline; |
||||
|
border-radius: .25em; |
||||
|
|
||||
|
// Add hover effects, but only for links |
||||
|
a& { |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
color: @label-link-hover-color; |
||||
|
text-decoration: none; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Empty labels collapse automatically (not available in IE8) |
||||
|
&:empty { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
// Quick fix for labels in buttons |
||||
|
.btn & { |
||||
|
position: relative; |
||||
|
top: -1px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Colors |
||||
|
// Contextual variations (linked labels get darker on :hover) |
||||
|
|
||||
|
.label-default { |
||||
|
.label-variant(@label-default-bg); |
||||
|
} |
||||
|
|
||||
|
.label-primary { |
||||
|
.label-variant(@label-primary-bg); |
||||
|
} |
||||
|
|
||||
|
.label-success { |
||||
|
.label-variant(@label-success-bg); |
||||
|
} |
||||
|
|
||||
|
.label-info { |
||||
|
.label-variant(@label-info-bg); |
||||
|
} |
||||
|
|
||||
|
.label-warning { |
||||
|
.label-variant(@label-warning-bg); |
||||
|
} |
||||
|
|
||||
|
.label-danger { |
||||
|
.label-variant(@label-danger-bg); |
||||
|
} |
@ -0,0 +1,130 @@ |
|||||
|
// |
||||
|
// List groups |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
|
||||
|
// Base class |
||||
|
// |
||||
|
// Easily usable on <ul>, <ol>, or <div>. |
||||
|
|
||||
|
.list-group { |
||||
|
// No need to set list-style: none; since .list-group-item is block level |
||||
|
margin-bottom: 20px; |
||||
|
padding-left: 0; // reset padding because ul and ol |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Individual list items |
||||
|
// |
||||
|
// Use on `li`s or `div`s within the `.list-group` parent. |
||||
|
|
||||
|
.list-group-item { |
||||
|
position: relative; |
||||
|
display: block; |
||||
|
padding: 10px 15px; |
||||
|
// Place the border on the list items and negative margin up for better styling |
||||
|
margin-bottom: -1px; |
||||
|
background-color: @list-group-bg; |
||||
|
border: 1px solid @list-group-border; |
||||
|
|
||||
|
// Round the first and last items |
||||
|
&:first-child { |
||||
|
.border-top-radius(@list-group-border-radius); |
||||
|
} |
||||
|
&:last-child { |
||||
|
margin-bottom: 0; |
||||
|
.border-bottom-radius(@list-group-border-radius); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Interactive list items |
||||
|
// |
||||
|
// Use anchor or button elements instead of `li`s or `div`s to create interactive items. |
||||
|
// Includes an extra `.active` modifier class for showing selected items. |
||||
|
|
||||
|
a.list-group-item, |
||||
|
button.list-group-item { |
||||
|
color: @list-group-link-color; |
||||
|
|
||||
|
.list-group-item-heading { |
||||
|
color: @list-group-link-heading-color; |
||||
|
} |
||||
|
|
||||
|
// Hover state |
||||
|
&:hover, |
||||
|
&:focus { |
||||
|
text-decoration: none; |
||||
|
color: @list-group-link-hover-color; |
||||
|
background-color: @list-group-hover-bg; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
button.list-group-item { |
||||
|
width: 100%; |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
.list-group-item { |
||||
|
// Disabled state |
||||
|
&.disabled, |
||||
|
&.disabled:hover, |
||||
|
&.disabled:focus { |
||||
|
background-color: @list-group-disabled-bg; |
||||
|
color: @list-group-disabled-color; |
||||
|
cursor: @cursor-disabled; |
||||
|
|
||||
|
// Force color to inherit for custom content |
||||
|
.list-group-item-heading { |
||||
|
color: inherit; |
||||
|
} |
||||
|
.list-group-item-text { |
||||
|
color: @list-group-disabled-text-color; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Active class on item itself, not parent |
||||
|
&.active, |
||||
|
&.active:hover, |
||||
|
&.active:focus { |
||||
|
z-index: 2; // Place active items above their siblings for proper border styling |
||||
|
color: @list-group-active-color; |
||||
|
background-color: @list-group-active-bg; |
||||
|
border-color: @list-group-active-border; |
||||
|
|
||||
|
// Force color to inherit for custom content |
||||
|
.list-group-item-heading, |
||||
|
.list-group-item-heading > small, |
||||
|
.list-group-item-heading > .small { |
||||
|
color: inherit; |
||||
|
} |
||||
|
.list-group-item-text { |
||||
|
color: @list-group-active-text-color; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Contextual variants |
||||
|
// |
||||
|
// Add modifier classes to change text and background color on individual items. |
||||
|
// Organizationally, this must come after the `:hover` states. |
||||
|
|
||||
|
.list-group-item-variant(success; @state-success-bg; @state-success-text); |
||||
|
.list-group-item-variant(info; @state-info-bg; @state-info-text); |
||||
|
.list-group-item-variant(warning; @state-warning-bg; @state-warning-text); |
||||
|
.list-group-item-variant(danger; @state-danger-bg; @state-danger-text); |
||||
|
|
||||
|
|
||||
|
// Custom content options |
||||
|
// |
||||
|
// Extra classes for creating well-formatted content within `.list-group-item`s. |
||||
|
|
||||
|
.list-group-item-heading { |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 5px; |
||||
|
} |
||||
|
.list-group-item-text { |
||||
|
margin-bottom: 0; |
||||
|
line-height: 1.3; |
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
.media { |
||||
|
// Proper spacing between instances of .media |
||||
|
margin-top: 15px; |
||||
|
|
||||
|
&:first-child { |
||||
|
margin-top: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.media, |
||||
|
.media-body { |
||||
|
zoom: 1; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.media-body { |
||||
|
width: 10000px; |
||||
|
} |
||||
|
|
||||
|
.media-object { |
||||
|
display: block; |
||||
|
|
||||
|
// Fix collapse in webkit from max-width: 100% and display: table-cell. |
||||
|
&.img-thumbnail { |
||||
|
max-width: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.media-right, |
||||
|
.media > .pull-right { |
||||
|
padding-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.media-left, |
||||
|
.media > .pull-left { |
||||
|
padding-right: 10px; |
||||
|
} |
||||
|
|
||||
|
.media-left, |
||||
|
.media-right, |
||||
|
.media-body { |
||||
|
display: table-cell; |
||||
|
vertical-align: top; |
||||
|
} |
||||
|
|
||||
|
.media-middle { |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
.media-bottom { |
||||
|
vertical-align: bottom; |
||||
|
} |
||||
|
|
||||
|
// Reset margins on headings for tighter default spacing |
||||
|
.media-heading { |
||||
|
margin-top: 0; |
||||
|
margin-bottom: 5px; |
||||
|
} |
||||
|
|
||||
|
// Media list variation |
||||
|
// |
||||
|
// Undo default ul/ol styles |
||||
|
.media-list { |
||||
|
padding-left: 0; |
||||
|
list-style: none; |
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
// Mixins |
||||
|
// -------------------------------------------------- |
||||
|
|
||||
|
// Utilities |
||||
|
@import "mixins/hide-text.less"; |
||||
|
@import "mixins/opacity.less"; |
||||
|
@import "mixins/image.less"; |
||||
|
@import "mixins/labels.less"; |
||||
|
@import "mixins/reset-filter.less"; |
||||
|
@import "mixins/resize.less"; |
||||
|
@import "mixins/responsive-visibility.less"; |
||||
|
@import "mixins/size.less"; |
||||
|
@import "mixins/tab-focus.less"; |
||||
|
@import "mixins/reset-text.less"; |
||||
|
@import "mixins/text-emphasis.less"; |
||||
|
@import "mixins/text-overflow.less"; |
||||
|
@import "mixins/vendor-prefixes.less"; |
||||
|
|
||||
|
// Components |
||||
|
@import "mixins/alerts.less"; |
||||
|
@import "mixins/buttons.less"; |
||||
|
@import "mixins/panels.less"; |
||||
|
@import "mixins/pagination.less"; |
||||
|
@import "mixins/list-group.less"; |
||||
|
@import "mixins/nav-divider.less"; |
||||
|
@import "mixins/forms.less"; |
||||
|
@import "mixins/progress-bar.less"; |
||||
|
@import "mixins/table-row.less"; |
||||
|
|
||||
|
// Skins |
||||
|
@import "mixins/background-variant.less"; |
||||
|
@import "mixins/border-radius.less"; |
||||
|
@import "mixins/gradients.less"; |
||||
|
|
||||
|
// Layout |
||||
|
@import "mixins/clearfix.less"; |
||||
|
@import "mixins/center-block.less"; |
||||
|
@import "mixins/nav-vertical-align.less"; |
||||
|
@import "mixins/grid-framework.less"; |
||||
|
@import "mixins/grid.less"; |
@ -0,0 +1,14 @@ |
|||||
|
// Alerts |
||||
|
|
||||
|
.alert-variant(@background; @border; @text-color) { |
||||
|
background-color: @background; |
||||
|
border-color: @border; |
||||
|
color: @text-color; |
||||
|
|
||||
|
hr { |
||||
|
border-top-color: darken(@border, 5%); |
||||
|
} |
||||
|
.alert-link { |
||||
|
color: darken(@text-color, 10%); |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
// Contextual backgrounds |
||||
|
|
||||
|
.bg-variant(@color) { |
||||
|
background-color: @color; |
||||
|
a&:hover, |
||||
|
a&:focus { |
||||
|
background-color: darken(@color, 10%); |
||||
|
} |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
// Single side border-radius |
||||
|
|
||||
|
.border-top-radius(@radius) { |
||||
|
border-top-right-radius: @radius; |
||||
|
border-top-left-radius: @radius; |
||||
|
} |
||||
|
.border-right-radius(@radius) { |
||||
|
border-bottom-right-radius: @radius; |
||||
|
border-top-right-radius: @radius; |
||||
|
} |
||||
|
.border-bottom-radius(@radius) { |
||||
|
border-bottom-right-radius: @radius; |
||||
|
border-bottom-left-radius: @radius; |
||||
|
} |
||||
|
.border-left-radius(@radius) { |
||||
|
border-bottom-left-radius: @radius; |
||||
|
border-top-left-radius: @radius; |
||||
|
} |
@ -0,0 +1,68 @@ |
|||||
|
// Button variants |
||||
|
// |
||||
|
// Easily pump out default styles, as well as :hover, :focus, :active, |
||||
|
// and disabled options for all buttons |
||||
|
|
||||
|
.button-variant(@color; @background; @border) { |
||||
|
color: @color; |
||||
|
background-color: @background; |
||||
|
border-color: @border; |
||||
|
|
||||
|
&:focus, |
||||
|
&.focus { |
||||
|
color: @color; |
||||
|
background-color: darken(@background, 10%); |
||||
|
border-color: darken(@border, 25%); |
||||
|
} |
||||
|
&:hover { |
||||
|
color: @color; |
||||
|
background-color: darken(@background, 10%); |
||||
|
border-color: darken(@border, 12%); |
||||
|
} |
||||
|
&:active, |
||||
|
&.active, |
||||
|
.open > .dropdown-toggle& { |
||||
|
color: @color; |
||||
|
background-color: darken(@background, 10%); |
||||
|
border-color: darken(@border, 12%); |
||||
|
|
||||
|
&:hover, |
||||
|
&:focus, |
||||
|
&.focus { |
||||
|
color: @color; |
||||
|
background-color: darken(@background, 17%); |
||||
|
border-color: darken(@border, 25%); |
||||
|
} |
||||
|
} |
||||
|
&:active, |
||||
|
&.active, |
||||
|
.open > .dropdown-toggle& { |
||||
|
background-image: none; |
||||
|
} |
||||
|
&.disabled, |
||||
|
&[disabled], |
||||
|
fieldset[disabled] & { |
||||
|
&, |
||||
|
&:hover, |
||||
|
&:focus, |
||||
|
&.focus, |
||||
|
&:active, |
||||
|
&.active { |
||||
|
background-color: @background; |
||||
|
border-color: @border; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.badge { |
||||
|
color: @background; |
||||
|
background-color: @color; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Button sizes |
||||
|
.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { |
||||
|
padding: @padding-vertical @padding-horizontal; |
||||
|
font-size: @font-size; |
||||
|
line-height: @line-height; |
||||
|
border-radius: @border-radius; |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
// Center-align a block level element |
||||
|
|
||||
|
.center-block() { |
||||
|
display: block; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
// Clearfix |
||||
|
// |
||||
|
// For modern browsers |
||||
|
// 1. The space content is one way to avoid an Opera bug when the |
||||
|
// contenteditable attribute is included anywhere else in the document. |
||||
|
// Otherwise it causes space to appear at the top and bottom of elements |
||||
|
// that are clearfixed. |
||||
|
// 2. The use of `table` rather than `block` is only necessary if using |
||||
|
// `:before` to contain the top-margins of child elements. |
||||
|
// |
||||
|
// Source: http://nicolasgallagher.com/micro-clearfix-hack/ |
||||
|
|
||||
|
.clearfix() { |
||||
|
&:before, |
||||
|
&:after { |
||||
|
content: " "; // 1 |
||||
|
display: table; // 2 |
||||
|
} |
||||
|
&:after { |
||||
|
clear: both; |
||||
|
} |
||||
|
} |
@ -0,0 +1,85 @@ |
|||||
|
// Form validation states |
||||
|
// |
||||
|
// Used in forms.less to generate the form validation CSS for warnings, errors, |
||||
|
// and successes. |
||||
|
|
||||
|
.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) { |
||||
|
// Color the label and help text |
||||
|
.help-block, |
||||
|
.control-label, |
||||
|
.radio, |
||||
|
.checkbox, |
||||
|
.radio-inline, |
||||
|
.checkbox-inline, |
||||
|
&.radio label, |
||||
|
&.checkbox label, |
||||
|
&.radio-inline label, |
||||
|
&.checkbox-inline label { |
||||
|
color: @text-color; |
||||
|
} |
||||
|
// Set the border and box shadow on specific inputs to match |
||||
|
.form-control { |
||||
|
border-color: @border-color; |
||||
|
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work |
||||
|
&:focus { |
||||
|
border-color: darken(@border-color, 10%); |
||||
|
@shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%); |
||||
|
.box-shadow(@shadow); |
||||
|
} |
||||
|
} |
||||
|
// Set validation states also for addons |
||||
|
.input-group-addon { |
||||
|
color: @text-color; |
||||
|
border-color: @border-color; |
||||
|
background-color: @background-color; |
||||
|
} |
||||
|
// Optional feedback icon |
||||
|
.form-control-feedback { |
||||
|
color: @text-color; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Form control focus state |
||||
|
// |
||||
|
// Generate a customized focus state and for any input with the specified color, |
||||
|
// which defaults to the `@input-border-focus` variable. |
||||
|
// |
||||
|
// We highly encourage you to not customize the default value, but instead use |
||||
|
// this to tweak colors on an as-needed basis. This aesthetic change is based on |
||||
|
// WebKit's default styles, but applicable to a wider range of browsers. Its |
||||
|
// usability and accessibility should be taken into account with any change. |
||||
|
// |
||||
|
// Example usage: change the default blue border and shadow to white for better |
||||
|
// contrast against a dark gray background. |
||||
|
.form-control-focus(@color: @input-border-focus) { |
||||
|
@color-rgba: rgba(red(@color), green(@color), blue(@color), .6); |
||||
|
&:focus { |
||||
|
border-color: @color; |
||||
|
outline: 0; |
||||
|
.box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Form control sizing |
||||
|
// |
||||
|
// Relative text size, padding, and border-radii changes for form controls. For |
||||
|
// horizontal sizing, wrap controls in the predefined grid classes. `<select>` |
||||
|
// element gets special love because it's special, and that's a fact! |
||||
|
.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) { |
||||
|
height: @input-height; |
||||
|
padding: @padding-vertical @padding-horizontal; |
||||
|
font-size: @font-size; |
||||
|
line-height: @line-height; |
||||
|
border-radius: @border-radius; |
||||
|
|
||||
|
select& { |
||||
|
height: @input-height; |
||||
|
line-height: @input-height; |
||||
|
} |
||||
|
|
||||
|
textarea&, |
||||
|
select[multiple]& { |
||||
|
height: auto; |
||||
|
} |
||||
|
} |
@ -0,0 +1,59 @@ |
|||||
|
// Gradients |
||||
|
|
||||
|
#gradient { |
||||
|
|
||||
|
// Horizontal gradient, from left to right |
||||
|
// |
||||
|
// Creates two color stops, start and end, by specifying a color and position for each color stop. |
||||
|
// Color stops are not available in IE9 and below. |
||||
|
.horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) { |
||||
|
background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+ |
||||
|
background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12 |
||||
|
background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ |
||||
|
background-repeat: repeat-x; |
||||
|
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down |
||||
|
} |
||||
|
|
||||
|
// Vertical gradient, from top to bottom |
||||
|
// |
||||
|
// Creates two color stops, start and end, by specifying a color and position for each color stop. |
||||
|
// Color stops are not available in IE9 and below. |
||||
|
.vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) { |
||||
|
background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+ |
||||
|
background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12 |
||||
|
background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ |
||||
|
background-repeat: repeat-x; |
||||
|
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down |
||||
|
} |
||||
|
|
||||
|
.directional(@start-color: #555; @end-color: #333; @deg: 45deg) { |
||||
|
background-repeat: repeat-x; |
||||
|
background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+ |
||||
|
background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12 |
||||
|
background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ |
||||
|
} |
||||
|
.horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) { |
||||
|
background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color); |
||||
|
background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color); |
||||
|
background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color); |
||||
|
background-repeat: no-repeat; |
||||
|
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback |
||||
|
} |
||||
|
.vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) { |
||||
|
background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color); |
||||
|
background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color); |
||||
|
background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color); |
||||
|
background-repeat: no-repeat; |
||||
|
filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback |
||||
|
} |
||||
|
.radial(@inner-color: #555; @outer-color: #333) { |
||||
|
background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color); |
||||
|
background-image: radial-gradient(circle, @inner-color, @outer-color); |
||||
|
background-repeat: no-repeat; |
||||
|
} |
||||
|
.striped(@color: rgba(255,255,255,.15); @angle: 45deg) { |
||||
|
background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent); |
||||
|
background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent); |
||||
|
background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent); |
||||
|
} |
||||
|
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue