aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore9
-rw-r--r--NOTES.txt5
-rw-r--r--README.md13
-rw-r--r--account/__init__.py0
-rw-r--r--account/admin.py3
-rw-r--r--account/forms.py54
-rw-r--r--account/models.py81
-rw-r--r--account/templates/account/login.html24
-rw-r--r--account/templates/account/logout.html19
-rw-r--r--account/templates/account/password_change.html24
-rw-r--r--account/templates/account/password_change_done.html21
-rw-r--r--account/templates/account/profile.html83
-rw-r--r--account/templates/account/profile_update.html24
-rw-r--r--account/templates/account/profile_update_done.html21
-rw-r--r--account/tests.py3
-rw-r--r--account/urls.py81
-rw-r--r--account/views.py68
-rw-r--r--db.sqlite3bin0 -> 35840 bytes
-rw-r--r--demo/__init__.py0
-rw-r--r--demo/forms.py37
-rw-r--r--demo/templates/demo/base.html25
-rw-r--r--demo/templates/demo/bootstrap.html3
-rw-r--r--demo/templates/demo/form.html17
-rw-r--r--demo/templates/demo/form_horizontal.html17
-rw-r--r--demo/templates/demo/form_inline.html17
-rw-r--r--demo/templates/demo/form_with_files.html17
-rw-r--r--demo/templates/demo/home.html7
-rw-r--r--demo/templates/demo/pagination.html25
-rw-r--r--demo/urls.py32
-rw-r--r--demo/views.py79
-rw-r--r--django_skaschool/__init__.py0
-rw-r--r--django_skaschool/settings.py165
-rw-r--r--django_skaschool/urls.py39
-rw-r--r--django_skaschool/wsgi.py14
-rw-r--r--manage.py10
-rw-r--r--notice/README.txt4
-rw-r--r--notice/__init__.py0
-rw-r--r--notice/admin.py3
-rw-r--r--notice/models.py3
-rw-r--r--notice/tests.py3
-rw-r--r--notice/views.py3
-rw-r--r--page/README.txt5
-rw-r--r--page/__init__.py0
-rw-r--r--page/admin.py3
-rw-r--r--page/models.py3
-rw-r--r--page/tests.py3
-rw-r--r--page/urls.py17
-rw-r--r--page/views.py15
-rw-r--r--requirements.txt5
-rw-r--r--static/css/base.css16
-rw-r--r--static/css/index.css101
-rw-r--r--static/images/apple-touch-icon-144-precomposed.pngbin0 -> 14210 bytes
-rw-r--r--static/images/favicon.pngbin0 -> 1976 bytes
-rw-r--r--static/images/skaschool-bg.jpgbin0 -> 485639 bytes
-rw-r--r--static/images/skaschool-bg2.jpgbin0 -> 508774 bytes
-rw-r--r--static/js/index.js17
-rw-r--r--static/third-party/bootstrap-glyphicons/README.md16
-rw-r--r--static/third-party/bootstrap-glyphicons/css/bootstrap.icon-large.css411
-rw-r--r--static/third-party/bootstrap-glyphicons/css/bootstrap.icon-large.min.css1
-rw-r--r--static/third-party/bootstrap-glyphicons/glyphicons.pngbin0 -> 111199 bytes
l---------static/third-party/bootstrap-glyphicons/img/glyphicons.png1
-rw-r--r--templates/base.html76
-rw-r--r--templates/favicon.html5
-rw-r--r--templates/index.html50
-rw-r--r--templates/navbar.html49
-rw-r--r--templates/registration/activate.html24
-rw-r--r--templates/registration/activation_complete.html22
-rw-r--r--templates/registration/activation_email.txt14
-rw-r--r--templates/registration/activation_email_subject.txt1
-rw-r--r--templates/registration/registration_closed.html19
-rw-r--r--templates/registration/registration_complete.html27
-rw-r--r--templates/registration/registration_form.html25
-rw-r--r--templates/test.html3
73 files changed, 1982 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a7bf707
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+# .gitignore
+
+*~
+*.pyc
+*.swp
+
+#
+django_skaschool/settings_email.py
+
diff --git a/NOTES.txt b/NOTES.txt
new file mode 100644
index 0000000..34e5177
--- /dev/null
+++ b/NOTES.txt
@@ -0,0 +1,5 @@
+Notes and Documents on django
+
+1. Django Class Based Generic Views (The Good, The Bad, And the Ugly)
+http://glitterbug.in/blog/django-class-based-generic-views-the-good-the-bad-/show/
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0f0b01c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+django_skaschool
+
+2014 SKA Summer School website
+with django
+
+Weitian LI <liweitianux@gmail.com>
+2014/04/17
+
+django admin:
+user: admin
+email: admin@localhost.com
+passwd: admin
+
diff --git a/account/__init__.py b/account/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/account/__init__.py
diff --git a/account/admin.py b/account/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/account/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/account/forms.py b/account/forms.py
new file mode 100644
index 0000000..ca54711
--- /dev/null
+++ b/account/forms.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+
+"""
+account/forms.py for skaschool
+"""
+
+from django import forms
+from registration.forms import RegistrationFormUniqueEmail
+from django.utils.translation import ugettext_lazy as _
+
+from account.models import UserProfile
+
+
+class UserRegForm(RegistrationFormUniqueEmail):
+ """
+ based on 'django-registration' RegistrationFormUniqueEmail
+ add fields 'realname', 'gender', 'institute' and 'captcha'
+ """
+ # XXX: keep consistent with GENDERS in 'models.UserProfile'
+ GENDERS = (
+ ('M', _("Male")),
+ ('F', _("Female")),
+ ('X', _("Secret")),
+ )
+ realname = forms.CharField(max_length=30, label=_("Name"))
+ gender = forms.ChoiceField(choices=GENDERS, label=_("Gender"))
+ institute = forms.CharField(max_length=100, label=_("Institute"))
+
+ def __init__(self, *args, **kw):
+ super(UserRegForm, self).__init__(*args, **kw)
+ # order form fields
+ self.fields.keyOrder = [
+ 'username',
+ 'email',
+ 'password1',
+ 'password2',
+ 'realname',
+ 'gender',
+ 'institute',
+ ]
+
+
+class UpdateProfileForm(forms.ModelForm):
+ """
+ ModelForm of 'UserProfile' used in 'UpdateProfileView'
+ """
+ # extra email field
+ email = forms.EmailField(label=_("E-mail"))
+
+ class Meta:
+ model = UserProfile
+ fields = ('realname', 'gender', 'institute')
+
+
diff --git a/account/models.py b/account/models.py
new file mode 100644
index 0000000..38047d6
--- /dev/null
+++ b/account/models.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+#
+# app 'account' models
+# registration
+#
+
+from django.db import models
+from django.contrib.auth.models import User
+from django.contrib import admin
+
+from django.utils.translation import ugettext_lazy as _
+
+from registration.signals import user_registered
+
+
+class UserProfile(models.Model):
+ """
+ custom user profile
+ connected with signal 'user_registered' sent by 'django-registration'
+ """
+ # XXX: keep consistent with GENDERS in 'forms.UserRegForm'
+ GENDERS = (
+ ('M', _("Male")),
+ ('F', _("Female")),
+ ('X', _("Secret")),
+ )
+ # status choices of is_approved
+ APPROVED_STATUS = (
+ ('Y', _("Yes")),
+ ('N', _("No")),
+ ('C', _("Checking")),
+ )
+ # status choices of is_sponsored
+ SPONSORED_STATUS = (
+ ('Y', _("Yes")),
+ ('N', _("No")),
+ ('C', _("Checking")),
+ )
+ # model fields
+ # FK default backward manager name 'userprofile_set'
+ user = models.ForeignKey(User, unique=True, verbose_name=_("Username"))
+ realname = models.CharField(_("Name"), max_length=30)
+ gender = models.CharField(_("Gender"), max_length=1, choices=GENDERS)
+ institute = models.CharField(_("Institute"), max_length=100)
+ # store the infomation about approval and sponsorship
+ is_approved = models.CharField(_("Is approved"), max_length=1,
+ choices=APPROVED_STATUS, default='C')
+ is_sponsored = models.CharField(_("Is sponsored"), max_length=1,
+ choices=SPONSORED_STATUS, default='C')
+
+ class Meta:
+ verbose_name = _('user profile')
+ verbose_name_plural = _('user profiles')
+
+ def __unicode__(self):
+ return u'UserProfile for %s' % self.user
+
+
+###### signal callback ######
+def user_registered_callback(sender, user, request, **kwargs):
+ """
+ callback of signal 'user_registered' from 'django-registration'
+ to create custom user profile
+ ref: http://johnparsons.net/index.php/2013/06/28/creating-profiles-with-django-registration/
+ """
+ profile = UserProfile(user = user)
+ profile.realname = request.POST['realname']
+ profile.gender = request.POST['gender']
+ profile.institute = request.POST['institute']
+ profile.save()
+
+### connect 'user_registered_callback' to signal
+user_registered.connect(user_registered_callback)
+
+
+### add to adim
+admin.site.register([
+ UserProfile,
+])
+
+
diff --git a/account/templates/account/login.html b/account/templates/account/login.html
new file mode 100644
index 0000000..4fee972
--- /dev/null
+++ b/account/templates/account/login.html
@@ -0,0 +1,24 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# login template #}
+
+{% block title %}
+登录 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>登录</h2>
+ <br>
+ <form role="form" class="form-horizontal" method="post">
+ {% csrf_token %}
+ {% bootstrap_form form layout='horizontal' %}
+ {% buttons submit='提交' reset='重置' layout='horizontal' %}{% endbuttons %}
+ </form>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/account/templates/account/logout.html b/account/templates/account/logout.html
new file mode 100644
index 0000000..7e3ac4a
--- /dev/null
+++ b/account/templates/account/logout.html
@@ -0,0 +1,19 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# login template #}
+
+{% block title %}
+已退出 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>已退出</h2>
+ <p class="lead">您已成功退出。</p>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/account/templates/account/password_change.html b/account/templates/account/password_change.html
new file mode 100644
index 0000000..f4e2e90
--- /dev/null
+++ b/account/templates/account/password_change.html
@@ -0,0 +1,24 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# login template #}
+
+{% block title %}
+修改密码 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>修改密码</h2>
+ <br>
+ <form role="form" class="form-horizontal" method="post">
+ {% csrf_token %}
+ {% bootstrap_form form layout='horizontal' %}
+ {% buttons submit='提交' reset='重置' layout='horizontal' %}{% endbuttons %}
+ </form>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/account/templates/account/password_change_done.html b/account/templates/account/password_change_done.html
new file mode 100644
index 0000000..e8770ca
--- /dev/null
+++ b/account/templates/account/password_change_done.html
@@ -0,0 +1,21 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# login template #}
+
+{% block title %}
+密码修改成功 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>密码修改成功</h2>
+ <p class="lead">您已成功修改密码。</p>
+ <br>
+ <p><a href="{% url 'profile' %}" class="btn btn-default">返回个人主页</a></p>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/account/templates/account/profile.html b/account/templates/account/profile.html
new file mode 100644
index 0000000..e8d295c
--- /dev/null
+++ b/account/templates/account/profile.html
@@ -0,0 +1,83 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# login template #}
+
+{% block title %}
+个人主页 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>个人主页</h2>
+ <br>
+
+ <table class="table table-striped table-bordered table-hover">
+ <tbody>
+ <tr>
+ <th class="profile-name">姓名</th>
+ <td class="profile-name-data">{{ profile.realname }}</td>
+ </tr>
+ <tr>
+ <th class="profile-gender">性别</th>
+ <td class="profile-gender-data">
+ {% if profile.gender == 'M' %}
+ 男
+ {% elif profile.gender == 'F' %}
+ 女
+ {% elif profile.gender == 'X' %}
+ <span class="glyphicon glyphicon-ban-circle"></span>
+ {% else %}
+ <span class="glyphicon glyphicon-warning-sign"></span> <span class="label label-danger">系统错误</span>
+ {% endif %}
+ </td>
+ </tr>
+ <tr>
+ <th class="profile-email">邮箱</th>
+ <td class="profile-email-data">{{ user.email }}</td>
+ </tr>
+ <tr>
+ <th class="profile-institute">单位</th>
+ <td class="profile-institute-data">{{ profile.institute }}</td>
+ </tr>
+ <tr>
+ <th class="profile-approval">是否审定</th>
+ <td class="profile-approval-data">
+ {% if profile.is_approved == 'Y' %}
+ <span class="glyphicon glyphicon-ok"></span> <span class="label label-success">是</span>
+ {% elif profile.is_approved == 'N' %}
+ <span class="glyphicon glyphicon-remove"></span> <span class="label label-warning">否</span>
+ {% elif profile.is_approved == 'C' %}
+ <span class="glyphicon glyphicon-question-sign"></span> <span class="label label-default">审核中</span>
+ {% else %}
+ <span class="glyphicon glyphicon-warning-sign"></span> <span class="label label-danger">系统错误</span>
+ {% endif %}
+ </td>
+ </tr>
+ <tr>
+ <th class="profile-sponsorship">是否资助</th>
+ <td class="profile-sponsorship-data">
+ {% if profile.is_sponsored == 'Y' %}
+ <span class="glyphicon glyphicon-ok"></span> <span class="label label-success">是</span>
+ {% elif profile.is_sponsored == 'N' %}
+ <span class="glyphicon glyphicon-remove"></span> <span class="label label-warning">否</span>
+ {% elif profile.is_sponsored == 'C' %}
+ <span class="glyphicon glyphicon-question-sign"></span> <span class="label label-default">审核中</span>
+ {% else %}
+ <span class="glyphicon glyphicon-warning-sign"></span> <span class="label label-danger">系统错误</span>
+ {% endif %}
+ </td>
+ </tr>
+ </table>
+
+ <br>
+ <p>
+ <a href="{% url 'profile_update' %}" class="btn btn-default">更新个人信息</a>
+ <a href="{% url 'password_change' %}" class="btn btn-default">修改密码</a>
+ </p>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/account/templates/account/profile_update.html b/account/templates/account/profile_update.html
new file mode 100644
index 0000000..1802bb0
--- /dev/null
+++ b/account/templates/account/profile_update.html
@@ -0,0 +1,24 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# login template #}
+
+{% block title %}
+更新个人信息 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>更新个人信息</h2>
+ <br>
+ <form role="form" class="form-horizontal" method="post">
+ {% csrf_token %}
+ {% bootstrap_form form layout='horizontal' %}
+ {% buttons submit='提交' reset='重置' layout='horizontal' %}{% endbuttons %}
+ </form>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/account/templates/account/profile_update_done.html b/account/templates/account/profile_update_done.html
new file mode 100644
index 0000000..5b10eb2
--- /dev/null
+++ b/account/templates/account/profile_update_done.html
@@ -0,0 +1,21 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# login template #}
+
+{% block title %}
+信息已更新 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>信息已更新</h2>
+ <p class="lead">您的个人信息已更新。</p>
+ <br>
+ <p><a href="{% url 'profile' %}" class="btn btn-default">返回个人主页</a></p>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/account/tests.py b/account/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/account/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/account/urls.py b/account/urls.py
new file mode 100644
index 0000000..b61e0e2
--- /dev/null
+++ b/account/urls.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+
+"""
+urls.py for app 'account'
+customize 'registration.backends.default.urls' to use custom form
+"""
+
+from django.conf.urls import patterns, include, url
+from django.views.generic.base import TemplateView
+from django.contrib.auth.decorators import login_required
+
+from registration.backends.default.views import ActivationView
+from registration.backends.default.views import RegistrationView
+
+from account.views import ProfileView, UpdateProfileView
+from account.forms import UserRegForm
+
+
+urlpatterns = patterns('',
+ ## profile
+ url(r'^profile/$',
+ login_required(ProfileView.as_view()),
+ name='profile'),
+ # update profile
+ url(r'^profile/update/$',
+ login_required(UpdateProfileView.as_view()),
+ name='profile_update'),
+ # update profile done
+ url(r'^profile/update/done/$',
+ login_required(TemplateView.as_view(template_name='account/profile_update_done.html')),
+ name='profile_update_done'),
+ ## django auth views
+ # login
+ url(r'^login/$', 'django.contrib.auth.views.login',
+ {'template_name': 'account/login.html'},
+ name='login'),
+ # logout
+ url(r'^logout/$', 'django.contrib.auth.views.logout',
+ {'template_name': 'account/logout.html'},
+ name='logout'),
+ # change password
+ # If 'post_change_redirect' not provided,
+ # then redirect to url 'password_change_done'.
+ url(r'^password/change/$', 'django.contrib.auth.views.password_change',
+ {'template_name': 'account/password_change.html'},
+ name='password_change'),
+ # change password done
+ url(r'^password/change/done$', 'django.contrib.auth.views.password_change_done',
+ {'template_name': 'account/password_change_done.html'},
+ name='password_change_done'),
+)
+
+urlpatterns += patterns('',
+ ## django-registration
+ # 0. registration_disallowed
+ url(r'^register/closed/$',
+ TemplateView.as_view(template_name='registration/registration_closed.html'),
+ name='registration_disallowed'),
+ # 1. registration_register
+ url(r'^register/$',
+ RegistrationView.as_view(form_class=UserRegForm),
+ name='registration_register'),
+ # 2. registration_complete
+ url(r'^register/complete/$',
+ TemplateView.as_view(template_name='registration/registration_complete.html'),
+ name='registration_complete'),
+ # 4. registration_activation_complete
+ url(r'^activate/complete/$',
+ TemplateView.as_view(template_name='registration/activation_complete.html'),
+ name='registration_activation_complete'),
+ # 3. registration_activate (place this section *AFTER* step 4)
+ # Activation keys get matched by \w+ instead of the more specific
+ # [a-fA-F0-9]{40} because a bad activation key should still get to the view;
+ # that way it can return a sensible "invalid key" message instead of a
+ # confusing 404.
+ url(r'^activate/(?P<activation_key>\w+)/$',
+ ActivationView.as_view(),
+ name='registration_activate'),
+)
+
+
diff --git a/account/views.py b/account/views.py
new file mode 100644
index 0000000..e6b90b1
--- /dev/null
+++ b/account/views.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+"""
+views.py of app 'account'
+"""
+
+from django.shortcuts import render
+from django.views.generic.base import TemplateView
+from django.views.generic.edit import UpdateView
+from django.core.urlresolvers import reverse_lazy
+from django.http import HttpResponseRedirect
+
+from account.models import UserProfile
+from account.forms import UpdateProfileForm
+
+
+###### Class-based views ######
+class ProfileView(TemplateView):
+ """
+ class view to show profile page
+ """
+ template_name = 'account/profile.html'
+
+ def get_context_data(self, **kwargs):
+ context = super(ProfileView, self).get_context_data(**kwargs)
+ user = self.request.user
+ profile = user.userprofile_set.get(user=user)
+ context['user'] = user
+ context['profile'] = profile
+ return context
+
+class UpdateProfileView(UpdateView):
+ form_class = UpdateProfileForm
+ model = UserProfile
+ template_name = 'account/profile_update.html'
+ success_url = reverse_lazy('profile_update_done')
+
+ # get profile object
+ def get_object(self, queryset=None):
+ user = self.request.user
+ profile = user.userprofile_set.get(user=user)
+ return profile
+
+ def get(self, request, *args, **kwargs):
+ """
+ Returns the keyword arguments for instantiating the form.
+ modify this method to add 'email' data
+ """
+ self.object = self.get_object()
+ form_class = self.get_form_class()
+ form = self.get_form(form_class)
+ # initialize form 'email' field
+ user = self.request.user
+ form.fields['email'].initial = user.email
+ return self.render_to_response(self.get_context_data(form=form))
+
+ def form_valid(self, form):
+ """
+ modify 'form_valid' to update email field
+ """
+ form_data = form.cleaned_data
+ # update email and save
+ user = self.request.user
+ user.email = form_data.get('email', user.email)
+ user.save()
+ return super(UpdateProfileView, self).form_valid(form)
+
+
diff --git a/db.sqlite3 b/db.sqlite3
new file mode 100644
index 0000000..67c2663
--- /dev/null
+++ b/db.sqlite3
Binary files differ
diff --git a/demo/__init__.py b/demo/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/demo/__init__.py
diff --git a/demo/forms.py b/demo/forms.py
new file mode 100644
index 0000000..aea1ce7
--- /dev/null
+++ b/demo/forms.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django import forms
+
+from bootstrap3.tests import TestForm
+
+RADIO_CHOICES = (
+ ('1', 'Radio 1'),
+ ('2', 'Radio 2'),
+)
+
+MEDIA_CHOICES = (
+ ('Audio', (
+ ('vinyl', 'Vinyl'),
+ ('cd', 'CD'),
+ )
+ ),
+ ('Video', (
+ ('vhs', 'VHS Tape'),
+ ('dvd', 'DVD'),
+ )
+ ),
+ ('unknown', 'Unknown'),
+)
+
+
+class ContactForm(TestForm):
+ pass
+
+
+class FilesForm(forms.Form):
+ text1 = forms.CharField()
+ file1 = forms.FileField()
+ file2 = forms.FileField(required=False)
+ file3 = forms.FileField(widget=forms.ClearableFileInput)
+ file4 = forms.FileField(required=False, widget=forms.ClearableFileInput)
diff --git a/demo/templates/demo/base.html b/demo/templates/demo/base.html
new file mode 100644
index 0000000..06dc6e3
--- /dev/null
+++ b/demo/templates/demo/base.html
@@ -0,0 +1,25 @@
+{% extends 'demo/bootstrap.html' %}
+
+{% load url from future %}
+
+{% load bootstrap3 %}
+
+{% block bootstrap3_content %}
+ <div class="container">
+ <h1>{% block title %}(no title){% endblock %}</h1>
+
+ <p>
+ <a href="{% url 'home' %}">home</a>
+ <a href="{% url 'form_default' %}">form</a>
+ <a href="{% url 'form_horizontal' %}">form_horizontal</a>
+ <a href="{% url 'form_inline' %}">form_inline</a>
+ <a href="{% url 'form_with_files' %}">form_with_files</a>
+ <a href="{% url 'pagination' %}">pagination</a>
+ </p>
+
+ {% bootstrap_messages %}
+
+ {% block content %}(no content){% endblock %}
+ </div>
+
+{% endblock %}
diff --git a/demo/templates/demo/bootstrap.html b/demo/templates/demo/bootstrap.html
new file mode 100644
index 0000000..5e5b581
--- /dev/null
+++ b/demo/templates/demo/bootstrap.html
@@ -0,0 +1,3 @@
+{% extends 'bootstrap3/bootstrap3.html' %}
+
+{% block bootstrap3_title %}{% block title %}{% endblock %}{% endblock %}
diff --git a/demo/templates/demo/form.html b/demo/templates/demo/form.html
new file mode 100644
index 0000000..d89672f
--- /dev/null
+++ b/demo/templates/demo/form.html
@@ -0,0 +1,17 @@
+{% extends 'demo/base.html' %}
+
+{% load bootstrap3 %}
+
+{% block title %}
+ Forms
+{% endblock %}
+
+{% block content %}
+
+ <form role="form" method="post">
+ {% csrf_token %}
+ {% bootstrap_form form %}
+ {% buttons submit='OK' reset="Cancel" %}{% endbuttons %}
+ </form>
+
+{% endblock %}
diff --git a/demo/templates/demo/form_horizontal.html b/demo/templates/demo/form_horizontal.html
new file mode 100644
index 0000000..229d400
--- /dev/null
+++ b/demo/templates/demo/form_horizontal.html
@@ -0,0 +1,17 @@
+{% extends 'demo/base.html' %}
+
+{% load bootstrap3 %}
+
+{% block title %}
+ Forms
+{% endblock %}
+
+{% block content %}
+
+ <form role="form" class="form-horizontal" method="post">
+ {% csrf_token %}
+ {% bootstrap_form form layout="horizontal" %}
+ {% buttons submit='OK' reset='Cancel' layout='horizontal' %}{% endbuttons %}
+ </form>
+
+{% endblock %}
diff --git a/demo/templates/demo/form_inline.html b/demo/templates/demo/form_inline.html
new file mode 100644
index 0000000..9f76c1e
--- /dev/null
+++ b/demo/templates/demo/form_inline.html
@@ -0,0 +1,17 @@
+{% extends 'demo/base.html' %}
+
+{% load bootstrap3 %}
+
+{% block title %}
+ Forms
+{% endblock %}
+
+{% block content %}
+
+ <form role="form" class="form-inline" method="post">
+ {% csrf_token %}
+ {% bootstrap_form form layout='inline' %}
+ {% buttons submit='OK' reset='Cancel' layout='inline' %}{% endbuttons %}
+ </form>
+
+{% endblock %}
diff --git a/demo/templates/demo/form_with_files.html b/demo/templates/demo/form_with_files.html
new file mode 100644
index 0000000..3e5e83f
--- /dev/null
+++ b/demo/templates/demo/form_with_files.html
@@ -0,0 +1,17 @@
+{% extends 'demo/base.html' %}
+
+{% load bootstrap3 %}
+
+{% block title %}
+ Forms
+{% endblock %}
+
+{% block content %}
+
+ <form role="form" method="post" enctype="multipart/form-data" {% if layout != 'vertical' %}class="form-{{ layout }}"{% endif %}>
+ {% csrf_token %}
+ {% bootstrap_form form layout=layout %}
+ {% buttons submit='OK' reset="Cancel" %}{% endbuttons %}
+ </form>
+
+{% endblock %}
diff --git a/demo/templates/demo/home.html b/demo/templates/demo/home.html
new file mode 100644
index 0000000..7166062
--- /dev/null
+++ b/demo/templates/demo/home.html
@@ -0,0 +1,7 @@
+{% extends 'demo/base.html' %}
+
+{% block title %}django-bootstrap3{% endblock %}
+
+{% block content %}
+ This is <em>bootstrap3</em> for <strong>Django</strong>.
+{% endblock %} \ No newline at end of file
diff --git a/demo/templates/demo/pagination.html b/demo/templates/demo/pagination.html
new file mode 100644
index 0000000..e7c1ed3
--- /dev/null
+++ b/demo/templates/demo/pagination.html
@@ -0,0 +1,25 @@
+{% extends 'demo/base.html' %}
+
+{% load bootstrap3 %}
+
+{% block title %}
+ Pagination
+{% endblock %}
+
+{% block content %}
+
+ <table class="table">
+ {% for line in lines %}
+ <tr>
+ <td>{{ line }}</td>
+ </tr>
+ {% endfor %}
+ </table>
+
+ <hr>
+
+ {% bootstrap_pagination lines url="/pagination?page=1&flop=flip" extra="q=foo" size="small" %}
+
+ {% bootstrap_pagination lines url="/pagination?page=1" size="large" %}
+
+{% endblock %} \ No newline at end of file
diff --git a/demo/urls.py b/demo/urls.py
new file mode 100644
index 0000000..b45a57a
--- /dev/null
+++ b/demo/urls.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf.urls import patterns, url
+
+from .views import HomePageView, FormHorizontalView, FormInlineView, PaginationView, FormWithFilesView, \
+ DefaultFormView
+
+# Uncomment the next two lines to enable the admin:
+# from django.contrib import admin
+# admin.autodiscover()
+
+# urlpatterns = patterns('',
+# # Examples:
+# # url(r'^$', 'demo.views.home', name='home'),
+# # url(r'^demo/', include('demo.foo.urls')),
+#
+# # Uncomment the admin/doc line below to enable admin documentation:
+# # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
+#
+# # Uncomment the next line to enable the admin:
+# # url(r'^admin/', include(admin.site.urls)),
+# )
+
+urlpatterns = patterns('',
+ url(r'^$', HomePageView.as_view(), name='home'),
+ url(r'^form$', DefaultFormView.as_view(), name='form_default'),
+ url(r'^form_horizontal$', FormHorizontalView.as_view(), name='form_horizontal'),
+ url(r'^form_inline$', FormInlineView.as_view(), name='form_inline'),
+ url(r'^pagination$', PaginationView.as_view(), name='pagination'),
+ url(r'^form_with_files$', FormWithFilesView.as_view(), name='form_with_files'),
+)
diff --git a/demo/views.py b/demo/views.py
new file mode 100644
index 0000000..07c25f0
--- /dev/null
+++ b/demo/views.py
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from django.core.files.storage import default_storage
+
+from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
+from django.db.models.fields.files import FieldFile
+from django.views.generic import FormView
+from django.views.generic.base import TemplateView
+from django.contrib import messages
+
+from .forms import ContactForm, FilesForm
+
+
+# http://yuji.wordpress.com/2013/01/30/django-form-field-in-initial-data-requires-a-fieldfile-instance/
+class FakeField(object):
+ storage = default_storage
+
+
+fieldfile = FieldFile(None, FakeField, 'dummy.txt')
+
+
+class HomePageView(TemplateView):
+ template_name = 'demo/home.html'
+
+ def get_context_data(self, **kwargs):
+ context = super(HomePageView, self).get_context_data(**kwargs)
+ messages.info(self.request, 'This is a demo of a message.')
+ return context
+
+
+class DefaultFormView(FormView):
+ template_name = 'demo/form.html'
+ form_class = ContactForm
+
+
+class FormHorizontalView(FormView):
+ template_name = 'demo/form_horizontal.html'
+ form_class = ContactForm
+
+
+class FormInlineView(FormView):
+ template_name = 'demo/form_inline.html'
+ form_class = ContactForm
+
+
+class FormWithFilesView(FormView):
+ template_name = 'demo/form_with_files.html'
+ form_class = FilesForm
+
+ def get_context_data(self, **kwargs):
+ context = super(FormWithFilesView, self).get_context_data(**kwargs)
+ context['layout'] = self.request.GET.get('layout', 'vertical')
+ return context
+
+ def get_initial(self):
+ return {
+ 'file4': fieldfile,
+ }
+
+class PaginationView(TemplateView):
+ template_name = 'demo/pagination.html'
+
+ def get_context_data(self, **kwargs):
+ context = super(PaginationView, self).get_context_data(**kwargs)
+ lines = []
+ for i in range(10000):
+ lines.append('Line %s' % (i + 1))
+ paginator = Paginator(lines, 10)
+ page = self.request.GET.get('page')
+ try:
+ show_lines = paginator.page(page)
+ except PageNotAnInteger:
+ # If page is not an integer, deliver first page.
+ show_lines = paginator.page(1)
+ except EmptyPage:
+ # If page is out of range (e.g. 9999), deliver last page of results.
+ show_lines = paginator.page(paginator.num_pages)
+ context['lines'] = show_lines
+ return context
diff --git a/django_skaschool/__init__.py b/django_skaschool/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/django_skaschool/__init__.py
diff --git a/django_skaschool/settings.py b/django_skaschool/settings.py
new file mode 100644
index 0000000..2054819
--- /dev/null
+++ b/django_skaschool/settings.py
@@ -0,0 +1,165 @@
+"""
+Django settings for django_skaschool project.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.6/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.6/ref/settings/
+"""
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+import os
+BASE_DIR = os.path.dirname(os.path.dirname(__file__))
+PROJECT_DIR = os.path.dirname(__file__)
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '3!73+$)!f&z@li7gg^^6w13&*vk#zbw*pue#9u+0l@_(5wocb@'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+TEMPLATE_DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+# DEFAULT_APPS: django framework apps
+DEFAULT_APPS = (
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.sites',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+)
+# THIRD_PARTY_APPS
+THIRD_PARTY_APPS = (
+ #'south',
+ 'bootstrap3',
+ 'registration',
+)
+# LOCAL_APPS
+LOCAL_APPS = (
+ 'account',
+ 'page',
+ 'notice',
+)
+# INSTALLED_APPS
+INSTALLED_APPS = DEFAULT_APPS + THIRD_PARTY_APPS + LOCAL_APPS
+
+MIDDLEWARE_CLASSES = (
+ '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 = 'django_skaschool.urls'
+
+WSGI_APPLICATION = 'django_skaschool.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ }
+}
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.6/topics/i18n/
+
+#LANGUAGE_CODE = 'en-us'
+LANGUAGE_CODE = 'zh-cn'
+
+#TIME_ZONE = 'UTC'
+TIME_ZONE = 'Asia/Shanghai'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+# contrib.sites
+SITE_ID = 1
+
+# The URL where requests are redirected after login when the
+# 'contrib.auth.login' view gets no 'next' parameter.
+LOGIN_REDIRECT_URL = '/accounts/profile/'
+
+# The URL where requests are redirected for login,
+# especially when using the 'login_required()' decorator.
+LOGIN_URL = '/accounts/login/'
+
+# The URL redirected to after logout
+LOGOUT_URL = '/accounts/logout/'
+
+
+## template directories
+TEMPLATE_DIRS = (
+ # Don't forget to use absolute paths, not relative paths.
+ os.path.join(BASE_DIR, 'templates'),
+)
+
+## static directories
+STATICFILES_DIRS = (
+ # Don't forget to use absolute paths, not relative paths.
+ os.path.join(BASE_DIR, 'static'),
+)
+
+## static root
+# absolute path to the directory where 'collectstatic' will collect
+# static files for deployment
+#STATIC_ROOT = '/var/www/example.com/static/'
+STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.6/howto/static-files/
+STATIC_URL = '/static/'
+
+## media root
+# absolute filesystem path to the directory that hold user-uploaded files
+#MEDIA_ROOT = '/var/www/example.com/media/'
+# media url
+MEDIA_URL = '/media/'
+
+## email settings
+try:
+ from settings_email import *
+except ImportError:
+ pass
+
+
+#################################################
+## bootstrap3
+BOOTSTRAP3 = {
+ 'jquery_url': '//code.jquery.com/jquery-1.11.0.min.js',
+ 'base_url': '//netdna.bootstrapcdn.com/bootstrap/3.1.1/',
+ 'css_url': None,
+ 'theme_url': None,
+ 'javascript_url': None,
+ 'javascript_in_head': False,
+ 'horizontal_label_class': 'col-md-2',
+ 'horizontal_field_class': 'col-md-4',
+}
+
+## django-registration
+# One-week activation window
+ACCOUNT_ACTIVATION_DAYS = 7
+# whether registration of new accounts if currently permitted
+REGISTRATION_OPEN = True
+
+# vim: set ts=4 sw=4 tw=0 fenc=utf-8 ft=python:
diff --git a/django_skaschool/urls.py b/django_skaschool/urls.py
new file mode 100644
index 0000000..65b05c4
--- /dev/null
+++ b/django_skaschool/urls.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+from django.conf.urls import patterns, include, url
+from django.conf import settings
+
+from django.contrib import admin
+admin.autodiscover()
+
+from django.contrib.staticfiles.urls import staticfiles_urlpatterns
+from django.views.generic.base import TemplateView
+
+
+urlpatterns = patterns('',
+ # admin
+ url(r'^admin/', include(admin.site.urls)),
+ # index page
+ url(r'^$', TemplateView.as_view(template_name='index.html'),
+ name='index'),
+ # app 'page'
+ url(r'^page/', include('page.urls')),
+)
+
+## django-registration
+urlpatterns += patterns('',
+ # url(r'^accounts/', include('registration.backends.default.urls')),
+ url(r'^accounts/', include('account.urls')),
+)
+
+
+## demo
+urlpatterns += patterns('',
+ url(r'^demo/', include('demo.urls')),
+)
+
+## staticfiles
+if settings.DEBUG:
+ urlpatterns += staticfiles_urlpatterns()
+
+
diff --git a/django_skaschool/wsgi.py b/django_skaschool/wsgi.py
new file mode 100644
index 0000000..e881f1e
--- /dev/null
+++ b/django_skaschool/wsgi.py
@@ -0,0 +1,14 @@
+"""
+WSGI config for django_skaschool 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/1.6/howto/deployment/wsgi/
+"""
+
+import os
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_skaschool.settings")
+
+from django.core.wsgi import get_wsgi_application
+application = get_wsgi_application()
diff --git a/manage.py b/manage.py
new file mode 100644
index 0000000..7a8a1e7
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_skaschool.settings")
+
+ from django.core.management import execute_from_command_line
+
+ execute_from_command_line(sys.argv)
diff --git a/notice/README.txt b/notice/README.txt
new file mode 100644
index 0000000..0a44112
--- /dev/null
+++ b/notice/README.txt
@@ -0,0 +1,4 @@
+App notice
+
+This app deals with notice and pages of skaschool.
+
diff --git a/notice/__init__.py b/notice/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/notice/__init__.py
diff --git a/notice/admin.py b/notice/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/notice/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/notice/models.py b/notice/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/notice/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/notice/tests.py b/notice/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/notice/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/notice/views.py b/notice/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/notice/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/page/README.txt b/page/README.txt
new file mode 100644
index 0000000..37360b3
--- /dev/null
+++ b/page/README.txt
@@ -0,0 +1,5 @@
+App page
+
+Places skaschool pages.
+There is also an app 'notice' to deal with notice and related pages.
+
diff --git a/page/__init__.py b/page/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/page/__init__.py
diff --git a/page/admin.py b/page/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/page/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/page/models.py b/page/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/page/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/page/tests.py b/page/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/page/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/page/urls.py b/page/urls.py
new file mode 100644
index 0000000..8c195e9
--- /dev/null
+++ b/page/urls.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+#
+# urls.py for app 'page'
+#
+
+from django.conf.urls import patterns, include, url
+from django.views.generic.base import TemplateView, RedirectView
+from django.core.urlresolvers import reverse_lazy
+
+urlpatterns = patterns('',
+ # test page
+ url(r'^test/$', TemplateView.as_view(template_name='test.html'),
+ name='test'),
+ # index page
+ url(r'^$', RedirectView.as_view(url=reverse_lazy('index'))),
+)
+
diff --git a/page/views.py b/page/views.py
new file mode 100644
index 0000000..15b7575
--- /dev/null
+++ b/page/views.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+
+"""
+App 'page' views
+"""
+
+from django.shortcuts import render
+from django.views.generic.base import TemplateView
+
+
+###### class-based views ######
+## IndexView: used in 'django_skaschool/urls' as index
+
+
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..ae1d743
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+Django==1.6.2
+South==0.8.4
+django-bootstrap3==4.2.0
+django-registration==1.0
+wsgiref==0.1.2
diff --git a/static/css/base.css b/static/css/base.css
new file mode 100644
index 0000000..dd08deb
--- /dev/null
+++ b/static/css/base.css
@@ -0,0 +1,16 @@
+/*
+ * skaschool website custom css
+ * base.css (linked in 'base.html')
+ *
+ * Weitian LI
+ */
+
+body {
+ position: relative; /* For scrollyspy */
+ padding-top: 52px; /* Account for fixed navbar */
+}
+
+.navbar-btn {
+ margin-left: 8px;
+}
+
diff --git a/static/css/index.css b/static/css/index.css
new file mode 100644
index 0000000..344ff07
--- /dev/null
+++ b/static/css/index.css
@@ -0,0 +1,101 @@
+/*
+ * skaschool website custom css
+ * index.css
+ *
+ * Weitian LI
+ */
+
+.skaschool-home {
+ background: url(../images/skaschool-bg.jpg) no-repeat center center fixed;
+ -webkit-background-size: cover;
+ -moz-background-size: cover;
+ -o-background-size: cover;
+ background-size: cover;
+ filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/skaschool-bg.jpg', sizingMethod='scale');
+ -ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/skaschool-bg.jpg', sizingMethod='scale')";
+}
+
+.masthead {
+ color: #CCCCCC;
+ padding: 30px 15px;
+ position: relative;
+ text-align: center;
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.15);
+}
+.masthead h1 {
+ color: #EEEEEE;
+}
+.masthead .btn-outline-inverse {
+ margin: 10px;
+}
+.masthead-links {
+ list-style: none outside none;
+ margin-top: 10px;
+ margin-bottom: 20px;
+ padding: 0 15px;
+ text-align: center;
+}
+.masthead-links li {
+ display: inline;
+}
+.masthead-links li + li {
+ margin-left: 10px;
+}
+.masthead-links a {
+ color: #EEEEEE;
+}
+@media (min-width: 768px) {
+ .masthead {
+ padding-top: 80px;
+ padding-bottom: 140px;
+ text-align: left;
+ }
+ .masthead .lead {
+ font-size: 20px;
+ margin-right: 25%;
+ }
+ .masthead .btn-outline-inverse {
+ font-size: 18px;
+ margin: 18px 5px 18px 0;
+ padding: 16px 20px;
+ width: auto;
+ }
+ .masthead-links {
+ padding: 0;
+ text-align: left;
+ }
+}
+
+/* Outline button for use within the docs */
+.btn-outline {
+ color: #563d7c;
+ background-color: #FFFFFF;
+ border-color: #e5e5e5;
+}
+.btn-outline:hover,
+.btn-outline:focus,
+.btn-outline:active {
+ color: #fff;
+ background-color: #563d7c;
+ border-color: #563d7c;
+}
+
+/* Inverted outline button (white on dark) */
+.btn-outline-inverse {
+ color: #E5E5E5;
+ background-color: transparent;
+ border-color: #E5E5E5;
+}
+.btn-outline-inverse:hover,
+.btn-outline-inverse:focus,
+.btn-outline-inverse:active {
+ color: #252525;
+ text-shadow: none;
+ background-color: #E5E5E5;
+ border-color: #E5E5E5;
+}
+
+footer {
+ color: #CCCCCC;
+}
+
diff --git a/static/images/apple-touch-icon-144-precomposed.png b/static/images/apple-touch-icon-144-precomposed.png
new file mode 100644
index 0000000..1486856
--- /dev/null
+++ b/static/images/apple-touch-icon-144-precomposed.png
Binary files differ
diff --git a/static/images/favicon.png b/static/images/favicon.png
new file mode 100644
index 0000000..928ba9b
--- /dev/null
+++ b/static/images/favicon.png
Binary files differ
diff --git a/static/images/skaschool-bg.jpg b/static/images/skaschool-bg.jpg
new file mode 100644
index 0000000..fc27544
--- /dev/null
+++ b/static/images/skaschool-bg.jpg
Binary files differ
diff --git a/static/images/skaschool-bg2.jpg b/static/images/skaschool-bg2.jpg
new file mode 100644
index 0000000..1c2fdb3
--- /dev/null
+++ b/static/images/skaschool-bg2.jpg
Binary files differ
diff --git a/static/js/index.js b/static/js/index.js
new file mode 100644
index 0000000..1f955a2
--- /dev/null
+++ b/static/js/index.js
@@ -0,0 +1,17 @@
+/*
+ * js code for 'index.html' page
+ *
+ * Weitian LI
+ */
+
+$(document).ready(function() {
+ // add class "skaschool-home" to "body"
+ if (! $("body").hasClass("skaschool-home")) {
+ $("body").addClass("skaschool-home");
+ }
+ // add class "masthead" to "main"
+ if (! $("main").hasClass("masthead")) {
+ $("main").addClass("masthead");
+ }
+});
+
diff --git a/static/third-party/bootstrap-glyphicons/README.md b/static/third-party/bootstrap-glyphicons/README.md
new file mode 100644
index 0000000..b5182d7
--- /dev/null
+++ b/static/third-party/bootstrap-glyphicons/README.md
@@ -0,0 +1,16 @@
+Bootstrap Glyphicons Support
+============================
+
+[Twitter's Bootstrap v2](http://twitter.github.com/bootstrap) project already uses GLYPHICONS halflings (created by [Jan Kovařík](http://glyphicons.com/)) and are released for Bootstrap under the Apache 2.0 License. What this project aims to accomplish is add seamless support for the 400+ GLYPHICONS (available for free under the [Creative Commons Attribution 3.0 Unported (CC BY 3.0)](http://creativecommons.org/licenses/by/3.0/deed.en) license) to Bootstrap so "large" icons can be used. To achieve this I've combined the over 400 24x24 GLYPHICONS in to a Sprite and added icon-large definitions.
+
+Whenever possible larger GLYPHICONS halflings names have been mapped. Otherwise the CSS class definition follows the names set by the files in the zip.
+
+To use this within your site you **NEED** to do the following:
+
+ 1. Download `bootstrap.icon-large.min.css` and place it in the same directory as bootstrap.css file
+ 2. Download `glyphicons.png` and place it in the same directory as glyphicons-halflings.png
+ 3. Add the following CSS definition under the bootstrap.css call
+ `<link href="css/bootstrap.icon-large.min.css" rel="stylesheet">`
+ 4. Clearly visible on the site (like the footer) add a link to [glyphicons.com](http://www.glyphicons.com/). This is a [requirement by the artist](http://glyphicons.com/glyphicons-licenses/) unless you purchase the GLYPHICONS ALL or GLYPHICONS PRO plans. If you don't want to give attribution to the artist, at least pay him for his fantastic work.
+
+That's it. You can find an entire listing of all the GLYPHICONS
diff --git a/static/third-party/bootstrap-glyphicons/css/bootstrap.icon-large.css b/static/third-party/bootstrap-glyphicons/css/bootstrap.icon-large.css
new file mode 100644
index 0000000..4a6b1ef
--- /dev/null
+++ b/static/third-party/bootstrap-glyphicons/css/bootstrap.icon-large.css
@@ -0,0 +1,411 @@
+.icon-large {
+ background-image: url("../img/glyphicons.png");
+ background-position: 24px 24px;
+ background-repeat: no-repeat;
+ display: inline-block;
+ height: 28px;
+ line-height: 28px;
+ vertical-align: text-bottom;
+ width: 28px;
+}
+.icon-large.icon-glass{ background-position: 0 0; }
+.icon-large.icon-leaf{ background-position: 0 -34px; }
+.icon-large.icon-dog{ background-position: 0 -69px; }
+.icon-large.icon-user{ background-position: 0 -104px; }
+.icon-large.icon-girl{ background-position: 0 -136px; }
+.icon-large.icon-car{ background-position: 0 -168px; }
+.icon-large.icon-user-add{ background-position: 0 -200px; }
+.icon-large.icon-user-remove{ background-position: 0 -232px; }
+.icon-large.icon-film{ background-position: 0 -264px; }
+.icon-large.icon-magic{ background-position: 0 -300px; }
+.icon-large.icon-envelope{ background-position: 0 -330px; }
+.icon-large.icon-camera{ background-position: 0 -360px; }
+.icon-large.icon-heart{ background-position: 0 -390px; }
+.icon-large.icon-beach-umbrella{ background-position: 0 -422px; }
+.icon-large.icon-train{ background-position: 0 -457px; }
+.icon-large.icon-print{ background-position: 0 -494px; }
+.icon-large.icon-bin{ background-position: 0 -528px; }
+.icon-large.icon-trash{ background-position: 0 -528px; }
+.icon-large.icon-music{ background-position: 0 -566px; }
+.icon-large.icon-note{ background-position: 0 -601px; }
+.icon-large.icon-cogwheel{ background-position: 0 -636px; }
+.icon-large.icon-cog{ background-position: 0 -636px; }
+.icon-large.icon-home{ background-position: 0 -670px; }
+.icon-large.icon-snowflake{ background-position: 0 -706px; }
+.icon-large.icon-fire{ background-position: 0 -744px; }
+.icon-large.icon-cogwheels{ background-position: 0 -780px; }
+.icon-large.icon-parents{ background-position: 0 -816px; }
+.icon-large.icon-binoculars{ background-position: 0 -848px; }
+.icon-large.icon-road{ background-position: 0 -882px; }
+.icon-large.icon-search{ background-position: 0 -916px; }
+.icon-large.icon-cars{ background-position: 0 -950px; }
+.icon-large.icon-pencil{ background-position: 0 -985px; }
+.icon-large.icon-bus{ background-position: 0 -1020px; }
+.icon-large.icon-wifi-alt{ background-position: 0 -1055px; }
+.icon-large.icon-luggage{ background-position: 0 -1091px; }
+.icon-large.icon-old-man{ background-position: 0 -1128px; }
+.icon-large.icon-woman{ background-position: 0 -1162px; }
+.icon-large.icon-file{ background-position: 0 -1194px; }
+.icon-large.icon-credit{ background-position: 0 -1228px; }
+.icon-large.icon-airplane, .icon-large.icon-plane{ background-position: 0 -1262px; }
+.icon-large.icon-notes{ background-position: 0 -1297px; }
+.icon-large.icon-stats{ background-position: 0 -1332px; }
+.icon-large.icon-charts{ background-position: 0 -1367px; }
+.icon-large.icon-pie-chart{ background-position: 0 -1401px; }
+.icon-large.icon-group{ background-position: 0 -1436px; }
+.icon-large.icon-keys{ background-position: 0 -1468px; }
+.icon-large.icon-calendar{ background-position: 0 -1504px; }
+.icon-large.icon-router{ background-position: 0 -1539px; }
+.icon-large.icon-camera-small{ background-position: 0 -1575px; }
+.icon-large.icon-dislikes{ background-position: 0 -1609px; }
+.icon-large.icon-star-empty{ background-position: 0 -1609px; }
+.icon-large.icon-star{ background-position: 0 -1643px; }
+.icon-large.icon-link{ background-position: 0 -1677px; }
+.icon-large.icon-eye-open{ background-position: -1px -1704px; }
+.icon-large.icon-eye-close{ background-position: -1px -1737px; }
+.icon-large.icon-alarm{ background-position: 0 -1771px; }
+.icon-large.icon-clock{ background-position: 0 -1807px; }
+.icon-large.icon-time{ background-position: 0 -1807px; }
+.icon-large.icon-stopwatch{ background-position: 0 -1841px; }
+.icon-large.icon-projector{ background-position: 0 -1878px; }
+.icon-large.icon-history{ background-position: 0 -1913px; }
+.icon-large.icon-truck{ background-position: 0 -1949px; }
+.icon-large.icon-cargo{ background-position: 0 -1986px; }
+.icon-large.icon-compass{ background-position: -46px 0; }
+.icon-large.icon-keynote{ background-position: -46px -34px; }
+.icon-large.icon-attach{ background-position: -46px -74px; }
+.icon-large.icon-power{ background-position: -46px -108px; }
+.icon-large.icon-off{ background-position: -46px -108px; }
+.icon-large.icon-lightbulb{ background-position: -46px -142px; }
+.icon-large.icon-tag{ background-position: -46px -178px; }
+.icon-large.icon-tags{ background-position: -46px -212px; }
+.icon-large.icon-cleaning{ background-position: -46px -246px; }
+.icon-large.icon-ruller{ background-position: -46px -281px; }
+.icon-large.icon-gift{ background-position: -46px -305px; }
+.icon-large.icon-umbrella{ background-position: -46px -340px; }
+.icon-large.icon-book{ background-position: -46px -378px; }
+.icon-large.icon-bookmark{ background-position: -44px -412px; }
+.icon-large.icon-signal{ background-position: -46px -446px; }
+.icon-large.icon-cup{ background-position: -46px -479px; }
+.icon-large.icon-stroller{ background-position: -46px -513px; }
+.icon-large.icon-headphones{ background-position: -46px -549px; }
+.icon-large.icon-headset{ background-position: -46px -583px; }
+.icon-large.icon-warning-sign{ background-position: -46px -621px; }
+.icon-large.icon-signal{ background-position: -46px -655px; }
+.icon-large.icon-retweet{ background-position: -47px -680px }
+.icon-large.icon-refresh{ background-position: -46px -714px; }
+.icon-large.icon-roundabout{ background-position: -46px -750px; }
+.icon-large.icon-random{ background-position: -46px -787px; }
+.icon-large.icon-heat{ background-position: -46px -817px; }
+.icon-large.icon-repeat{ background-position: -46px -852px; }
+.icon-large.icon-display{ background-position: -46px -888px; }
+.icon-large.icon-log-book{ background-position: -46px -922px; }
+.icon-large.icon-adress-book{ background-position: -46px -956px; }
+.icon-large.icon-magnet{ background-position: -46px -990px; }
+.icon-large.icon-table{ background-position: -46px -1023px; }
+.icon-large.icon-adjust{ background-position: -46px -1057px; }
+.icon-large.icon-tint{ background-position: -46px -1093px; }
+.icon-large.icon-crop{ background-position: -46px -1129px; }
+.icon-large.icon-vector-path-square{ background-position: -46px -1165px; }
+.icon-large.icon-vector-path-circle{ background-position: -46px -1199px; }
+.icon-large.icon-vector-path-polygon{ background-position: -46px -1233px; }
+.icon-large.icon-vector-path-line{ background-position: -46px -1268px; }
+.icon-large.icon-vector-path-curve{ background-position: -46px -1302px; }
+.icon-large.icon-vector-path-all{ background-position: -46px -1336px; }
+.icon-large.icon-font{ background-position: -46px -1370px; }
+.icon-large.icon-italic{ background-position: -46px -1403px; }
+.icon-large.icon-bold{ background-position: -46px -1437px; }
+.icon-large.icon-text-underline{ background-position: -46px -1471px; }
+.icon-large.icon-text-strike{ background-position: -46px -1505px; }
+.icon-large.icon-text-height{ background-position: -46px -1537px; }
+.icon-large.icon-text-width{ background-position: -46px -1571px; }
+.icon-large.icon-text-resize{ background-position: -46px -1605px; }
+.icon-large.icon-left-indent, .icon-large.icon-indent-left{ background-position: -46px -1641px; }
+.icon-large.icon-right-indent, .icon-large.icon-indent-right{ background-position: -46px -1673px; }
+.icon-large.icon-align-left{ background-position: -46px -1705px; }
+.icon-large.icon-align-center{ background-position: -46px -1736px; }
+.icon-large.icon-align-right{ background-position: -46px -1767px; }
+.icon-large.icon-justify{ background-position: -46px -1798px; }
+.icon-large.icon-align-justify{ background-position: -46px -1798px; }
+.icon-large.icon-list{ background-position: -46px -1829px; }
+.icon-large.icon-text-smaller{ background-position: -46px -1860px; }
+.icon-large.icon-text-bigger{ background-position: -46px -1886px; }
+.icon-large.icon-embed{ background-position: -47px -1910px; }
+.icon-large.icon-embed-close{ background-position: -47px -1940px; }
+.icon-large.icon-adjust{ background-position: -46px -1976px; }
+.icon-large.icon-message-full{ background-position: -92px 0; }
+.icon-large.icon-message-empty{ background-position: -92px -38px; }
+.icon-large.icon-message-in{ background-position: -92px -76px; }
+.icon-large.icon-message-out{ background-position: -92px -114px; }
+.icon-large.icon-message-plus{ background-position: -92px -152px; }
+.icon-large.icon-message-minus{ background-position: -92px -185px; }
+.icon-large.icon-message-ban{ background-position: -92px -218px; }
+.icon-large.icon-message-flag{ background-position: -92px -251px; }
+.icon-large.icon-message-lock{ background-position: -92px -284px; }
+.icon-large.icon-message-new{ background-position: -92px -318px; }
+.icon-large.icon-inbox{ background-position: -92px -350px; }
+.icon-large.icon-inbox-plus{ background-position: -92px -383px; }
+.icon-large.icon-inbox-minus{ background-position: -92px -420px; }
+.icon-large.icon-inbox-lock{ background-position: -92px -457px; }
+.icon-large.icon-inbox-in{ background-position: -92px -495px; }
+.icon-large.icon-inbox-out{ background-position: -92px -531px; }
+.icon-large.icon-computer-locked{ background-position: -92px -567px; }
+.icon-large.icon-computer-service{ background-position: -92px -601px; }
+.icon-large.icon-computer-proces{ background-position: -92px -635px; }
+.icon-large.icon-phone{ background-position: -92px -669px; }
+.icon-large.icon-database-lock{ background-position: -92px -704px; }
+.icon-large.icon-database-plus{ background-position: -92px -742px; }
+.icon-large.icon-database-minus{ background-position: -92px -779px; }
+.icon-large.icon-database-ban{ background-position: -92px -816px; }
+.icon-large.icon-folder-open{ background-position: -92px -853px; }
+.icon-large.icon-folder-plus{ background-position: -92px -885px; }
+.icon-large.icon-folder-minus{ background-position: -92px -920px; }
+.icon-large.icon-folder-lock{ background-position: -92px -955px; }
+.icon-large.icon-folder-flag{ background-position: -92px -991px; }
+.icon-large.icon-folder-new{ background-position: -92px -1026px; }
+.icon-large.icon-check{ background-position: -92px -1060px; }
+.icon-large.icon-edit{ background-position: -92px -1088px; }
+.icon-large.icon-new-window{ background-position: -92px -1119px; }
+.icon-large.icon-more-windows{ background-position: -92px -1151px; }
+.icon-large.icon-show-big-thumbnails{ background-position: -92px -1184px; }
+.icon-large.icon-th-large{ background-position: -92px -1184px; }
+.icon-large.icon-show-thumbnails{ background-position: -92px -1216px; }
+.icon-large.icon-th{ background-position: -92px -1216px; }
+.icon-large.icon-show-thumbnails-with-lines{ background-position: -92px -1248px; }
+.icon-large.icon-th-list{ background-position: -92px -1248px; }
+.icon-large.icon-show-lines{ background-position: -92px -1273px; }
+.icon-large.icon-playlist{ background-position: -92px -1298px; }
+.icon-large.icon-picture{ background-position: -92px -1332px; }
+.icon-large.icon-imac{ background-position: -92px -1362px; }
+.icon-large.icon-macbook{ background-position: -92px -1394px; }
+.icon-large.icon-ipad{ background-position: -92px -1419px; }
+.icon-large.icon-iphone{ background-position: -92px -1456px; }
+.icon-large.icon-iphone-transfer{ background-position: -92px -1490px; }
+.icon-large.icon-iphone-exchange{ background-position: -92px -1524px; }
+.icon-large.icon-ipod{ background-position: -92px -1558px; }
+.icon-large.icon-ipod-shuffle{ background-position: -92px -1590px; }
+.icon-large.icon-ear-plugs{ background-position: -92px -1613px; }
+.icon-large.icon-albums{ background-position: -92px -1647px; }
+.icon-large.icon-step-backward{ background-position: -92px -1675px; }
+.icon-large.icon-fast-backward{ background-position: -92px -1703px; }
+.icon-large.icon-rewind, .icon-large.icon-backwards{ background-position: -92px -1731px; }
+.icon-large.icon-play{ background-position: -92px -1759px; }
+.icon-large.icon-pause{ background-position: -92px -1787px; }
+.icon-large.icon-stop{ background-position: -92px -1813px; }
+.icon-large.icon-forward{ background-position: -92px -1837px; }
+.icon-large.icon-fast-forward{ background-position: -92px -1865px; }
+.icon-large.icon-step-forward{ background-position: -92px -1893px; }
+.icon-large.icon-eject{ background-position: -92px -1921px; }
+.icon-large.icon-facetime-video{ background-position: -92px -1948px; }
+.icon-large.icon-download-alt{ background-position: -92px -1974px; }
+.icon-large.icon-mute, .icon-large.icon-volume-off{ background-position: -138px 4px; }
+.icon-large.icon-volume-down{ background-position: -134px -22px; }
+.icon-large.icon-volume-up{ background-position: -138px -52px; }
+.icon-large.icon-screenshot{ background-position: -138px -88px; }
+.icon-large.icon-move{ background-position: -138px -125px; }
+.icon-large.icon-more{ background-position: -138px -159px; }
+.icon-large.icon-brightness-reduce{ background-position: -138px -176px; }
+.icon-large.icon-brightness-increase{ background-position: -138px -206px; }
+.icon-large.icon-circle-plus, .icon-large.icon-plus-sign{ background-position: -138px -240px; }
+.icon-large.icon-circle-minus, .icon-large.icon-minus-sign{ background-position: -138px -276px; }
+.icon-large.icon-circle-remove, .icon-large.icon-remove-sign{ background-position: -138px -312px; }
+.icon-large.icon-circle-ok, .icon-large.icon-ok-sign{ background-position: -138px -348px; }
+.icon-large.icon-circle-question-mark, .icon-large.icon-question-sign{ background-position: -138px -384px; }
+.icon-large.icon-circle-info, .icon-large.icon-info-sign{ background-position: -138px -420px; }
+.icon-large.icon-circle-exclamation-mark, .icon-large.icon-exclamation-sign{ background-position: -138px -456px; }
+.icon-large.icon-remove{ background-position: -138px -492px; }
+.icon-large.icon-ok{ background-position: -138px -528px; }
+.icon-large.icon-ban{ background-position: -138px -564px; }
+.icon-large.icon-download{ background-position: -138px -600px; }
+.icon-large.icon-upload{ background-position: -138px -636px; }
+.icon-large.icon-shopping-cart{ background-position: -138px -672px; }
+.icon-large.icon-lock{ background-position: -138px -705px; }
+.icon-large.icon-unlock{ background-position: -138px -741px; }
+.icon-large.icon-electricity{ background-position: -138px -777px; }
+.icon-large.icon-cart-out{ background-position: -138px -811px; }
+.icon-large.icon-cart-in{ background-position: -138px -846px; }
+.icon-large.icon-left-arrow{ background-position: -138px -880px; }
+.icon-large.icon-right-arrow{ background-position: -138px -908px; }
+.icon-large.icon-down-arrow{ background-position: -138px -936px; }
+.icon-large.icon-up-arrow{ background-position: -138px -966px; }
+.icon-large.icon-resize-small{ background-position: -138px -996px; }
+.icon-large.icon-resize-full{ background-position: -138px -1030px; }
+.icon-large.icon-circle-arrow-left{ background-position: -138px -1064px; }
+.icon-large.icon-circle-arrow-right{ background-position: -138px -1100px; }
+.icon-large.icon-circle-arrow-top, .icon-large.icon-circle-arrow-up{ background-position: -138px -1136px; }
+.icon-large.icon-circle-arrow-down{ background-position: -138px -1172px; }
+.icon-large.icon-play-button{ background-position: -138px -1208px; }
+.icon-large.icon-play-circle{ background-position: -138px -1208px; }
+.icon-large.icon-unshare{ background-position: -138px -1244px; }
+.icon-large.icon-share{ background-position: -138px -1272px; }
+.icon-large.icon-thin-right-arrow, .icon-large.icon-chevron-right{ background-position: -138px -1300px; }
+.icon-large.icon-thin-arrow-left, .icon-large.icon-chevron-left{ background-position: -138px -1332px; }
+.icon-large.icon-bluetooth{ background-position: -138px -1364px; }
+.icon-large.icon-euro{ background-position: -138px -1398px; }
+.icon-large.icon-usd{ background-position: -138px -1431px; }
+.icon-large.icon-bp{ background-position: -138px -1467px; }
+.icon-large.icon-moon{ background-position: -138px -1501px; }
+.icon-large.icon-sun{ background-position: -138px -1536px; }
+.icon-large.icon-cloud{ background-position: -138px -1570px; }
+.icon-large.icon-direction{ background-position: -138px -1597px; }
+.icon-large.icon-brush{ background-position: -138px -1633px; }
+.icon-large.icon-pen{ background-position: -138px -1666px; }
+.icon-large.icon-zoom-in{ background-position: -138px -1700px; }
+.icon-large.icon-zoom-out{ background-position: -138px -1735px; }
+.icon-large.icon-pin{ background-position: -138px -1770px; }
+.icon-large.icon-riflescope{ background-position: -138px -1805px; }
+.icon-large.icon-rotation-lock{ background-position: -138px -1840px; }
+.icon-large.icon-flash{ background-position: -138px -1874px; }
+.icon-large.icon-google-maps, .icon-large.icon-map-marker{ background-position: -138px -1909px; }
+.icon-large.icon-anchor{ background-position: -138px -1943px; }
+.icon-large.icon-conversation{ background-position: -138px -1978px; }
+.icon-large.icon-chat{ background-position: -184px 0; }
+.icon-large.icon-male{ background-position: -184px -29px; }
+.icon-large.icon-female{ background-position: -184px -61px; }
+.icon-large.icon-asterisk{ background-position: -184px -98px; }
+.icon-large.icon-divide{ background-position: -184px -128px; }
+.icon-large.icon-snorkel-diving{ background-position: -184px -154px; }
+.icon-large.icon-scuba-diving{ background-position: -184px -189px; }
+.icon-large.icon-oxygen-bottle{ background-position: -184px -223px; }
+.icon-large.icon-fins{ background-position: -184px -260px; }
+.icon-large.icon-fishes{ background-position: -184px -297px; }
+.icon-large.icon-boat{ background-position: -184px -337px; }
+.icon-large.icon-delete-point{ background-position: -184px -371px; }
+.icon-large.icon-qrcode{ background-position: -184px -398px; }
+.icon-large.icon-barcode{ background-position: -184px -432px; }
+.icon-large.icon-pool{ background-position: -184px -466px; }
+.icon-large.icon-buoy{ background-position: -184px -500px; }
+.icon-large.icon-spade{ background-position: -184px -534px; }
+.icon-large.icon-bank{ background-position: -184px -568px; }
+.icon-large.icon-vcard{ background-position: -184px -602px; }
+.icon-large.icon-electrical-plug{ background-position: -184px -636px; }
+.icon-large.icon-flag{ background-position: -184px -671px; }
+.icon-large.icon-credit-card{ background-position: -184px -707px; }
+.icon-large.icon-keyboard-wireless{ background-position: -184px -736px; }
+.icon-large.icon-keyboard-wired{ background-position: -184px -765px; }
+.icon-large.icon-shield{ background-position: -184px -800px; }
+.icon-large.icon-ring{ background-position: -184px -834px; }
+.icon-large.icon-cake{ background-position: -184px -868px; }
+.icon-large.icon-drink{ background-position: -184px -902px; }
+.icon-large.icon-beer{ background-position: -184px -936px; }
+.icon-large.icon-fast-food{ background-position: -184px -970px; }
+.icon-large.icon-cutlery{ background-position: -184px -1004px; }
+.icon-large.icon-pizza{ background-position: -184px -1038px; }
+.icon-large.icon-birthday-cake{ background-position: -184px -1077px; }
+.icon-large.icon-tablet{ background-position: -184px -1116px; }
+.icon-large.icon-settings{ background-position: -184px -1151px; }
+.icon-large.icon-bullets{ background-position: -184px -1185px; }
+.icon-large.icon-cardio{ background-position: -184px -1218px; }
+.icon-large.icon-pants{ background-position: -184px -1254px; }
+.icon-large.icon-sweater{ background-position: -184px -1288px; }
+.icon-large.icon-fabric{ background-position: -184px -1322px; }
+.icon-large.icon-leather{ background-position: -184px -1354px; }
+.icon-large.icon-scissors{ background-position: -184px -1388px; }
+.icon-large.icon-podium{ background-position: -184px -1425px; }
+.icon-large.icon-skull{ background-position: -184px -1456px; }
+.icon-large.icon-celebration{ background-position: -184px -1490px; }
+.icon-large.icon-tea-kettle{ background-position: -184px -1525px; }
+.icon-large.icon-french-press{ background-position: -184px -1558px; }
+.icon-large.icon-coffe-cup{ background-position: -184px -1593px; }
+.icon-large.icon-pot{ background-position: -184px -1622px; }
+.icon-large.icon-grater{ background-position: -184px -1654px; }
+.icon-large.icon-kettle{ background-position: -184px -1688px; }
+.icon-large.icon-hospital{ background-position: -184px -1722px; }
+.icon-large.icon-hospital-h{ background-position: -184px -1756px; }
+.icon-large.icon-microphone{ background-position: -184px -1790px; }
+.icon-large.icon-webcam{ background-position: -184px -1824px; }
+.icon-large.icon-temple-christianity-church{ background-position: -184px -1858px; }
+.icon-large.icon-temple-islam{ background-position: -184px -1893px; }
+.icon-large.icon-temple-hindu{ background-position: -184px -1927px; }
+.icon-large.icon-temple-buddhist{ background-position: -184px -1961px; }
+.icon-large.icon-electrical-socket-eu{ background-position: -230px 0; }
+.icon-large.icon-electrical-socket-us{ background-position: -230px -33px; }
+.icon-large.icon-bomb{ background-position: -230px -66px; }
+.icon-large.icon-comments, .icon-large.icon-comment{ background-position: -230px -102px; }
+.icon-large.icon-flower{ background-position: -230px -135px; }
+.icon-large.icon-baseball{ background-position: -230px -170px; }
+.icon-large.icon-rugby{ background-position: -230px -206px; }
+.icon-large.icon-ax{ background-position: -230px -240px; }
+.icon-large.icon-table-tennis{ background-position: -230px -275px; }
+.icon-large.icon-bowling{ background-position: -230px -309px; }
+.icon-large.icon-tree-conifer{ background-position: -230px -343px; }
+.icon-large.icon-tree-deciduous{ background-position: -230px -377px; }
+.icon-large.icon-sort{ background-position: -230px -412px; }
+.icon-large.icon-filter{ background-position: -230px -447px; }
+.icon-large.icon-gamepad{ background-position: -230px -481px; }
+.icon-large.icon-playing-dices{ background-position: -230px -510px; }
+.icon-large.icon-calculator{ background-position: -230px -543px; }
+.icon-large.icon-tie{ background-position: -230px -577px; }
+.icon-large.icon-wallet{ background-position: -230px -613px; }
+.icon-large.icon-share{ background-position: -230px -643px; }
+.icon-large.icon-sampler{ background-position: -230px -675px; }
+.icon-large.icon-piano{ background-position: -230px -707px; }
+.icon-large.icon-web-browser{ background-position: -230px -741px; }
+.icon-large.icon-blog{ background-position: -230px -773px; }
+.icon-large.icon-dashboard{ background-position: -230px -806px; }
+.icon-large.icon-certificate{ background-position: -230px -840px; }
+.icon-large.icon-bell{ background-position: -230px -875px; }
+.icon-large.icon-candle{ background-position: -230px -909px; }
+.icon-large.icon-pin-classic{ background-position: -230px -944px; }
+.icon-large.icon-iphone-shake{ background-position: -230px -978px; }
+.icon-large.icon-pin-flag{ background-position: -230px -1012px; }
+.icon-large.icon-turtle{ background-position: -230px -1044px; }
+.icon-large.icon-rabbit{ background-position: -230px -1070px; }
+.icon-large.icon-globe{ background-position: -230px -1102px; }
+.icon-large.icon-briefcase{ background-position: -230px -1136px; }
+.icon-large.icon-hdd{ background-position: -230px -1167px; }
+.icon-large.icon-thumbs-up{ background-position: -230px -1198px; }
+.icon-large.icon-thumbs-down{ background-position: -230px -1229px; }
+.icon-large.icon-hand-right{ background-position: -230px -1260px; }
+.icon-large.icon-hand-left{ background-position: -230px -1289px; }
+.icon-large.icon-hand-up{ background-position: -230px -1318px; }
+.icon-large.icon-hand-down{ background-position: -230px -1354px; }
+.icon-large.icon-fullscreen{ background-position: -230px -1391px; }
+.icon-large.icon-shopping-bag{ background-position: -230px -1425px; }
+.icon-large.icon-book-open{ background-position: -230px -1461px; }
+.icon-large.icon-nameplate{ background-position: -230px -1494px; }
+.icon-large.icon-nameplate-alt{ background-position: -230px -1525px; }
+.icon-large.icon-vases{ background-position: -230px -1557px; }
+.icon-large.icon-announcement, .icon-large.icon-bullhorn{ background-position: -230px -1591px; }
+.icon-large.icon-dumbbell{ background-position: -230px -1621px; }
+.icon-large.icon-suitcase{ background-position: -230px -1647px; }
+.icon-large.icon-file-import{ background-position: -230px -1679px; }
+.icon-large.icon-file-export{ background-position: -230px -1713px; }
+.icon-large.icon-pinterest{ background-position: -230px -1747px; }
+.icon-large.icon-dropbox{ background-position: -230px -1781px; }
+.icon-large.icon-jolicloud{ background-position: -230px -1815px; }
+.icon-large.icon-yahoo{ background-position: -230px -1849px; }
+.icon-large.icon-blogger{ background-position: -230px -1883px; }
+.icon-large.icon-picasa{ background-position: -230px -1917px; }
+.icon-large.icon-amazon{ background-position: -230px -1951px; }
+.icon-large.icon-tumblr{ background-position: -230px -1985px; }
+.icon-large.icon-wordpress{ background-position: -276px 0; }
+.icon-large.icon-instapaper{ background-position: -276px -34px; }
+.icon-large.icon-evernote{ background-position: -276px -68px; }
+.icon-large.icon-xing{ background-position: -276px -102px; }
+.icon-large.icon-zootool{ background-position: -276px -136px; }
+.icon-large.icon-dribbble{ background-position: -276px -170px; }
+.icon-large.icon-deviantart{ background-position: -276px -204px; }
+.icon-large.icon-read-it-later{ background-position: -276px -238px; }
+.icon-large.icon-linked-in{ background-position: -276px -272px; }
+.icon-large.icon-forrst{ background-position: -276px -306px; }
+.icon-large.icon-pinboard{ background-position: -276px -340px; }
+.icon-large.icon-behance{ background-position: -276px -374px; }
+.icon-large.icon-github{ background-position: -276px -408px; }
+.icon-large.icon-youtube{ background-position: -276px -442px; }
+.icon-large.icon-skitch{ background-position: -276px -476px; }
+.icon-large.icon-quora{ background-position: -276px -510px; }
+.icon-large.icon-google-plus{ background-position: -276px -544px; }
+.icon-large.icon-spootify{ background-position: -276px -578px; }
+.icon-large.icon-stumbleupon{ background-position: -276px -612px; }
+.icon-large.icon-readability{ background-position: -276px -646px; }
+.icon-large.icon-facebook{ background-position: -276px -680px; }
+.icon-large.icon-twitter-t{ background-position: -276px -714px; }
+.icon-large.icon-twitter{ background-position: -276px -748px; }
+.icon-large.icon-buzz{ background-position: -276px -782px; }
+.icon-large.icon-vimeo{ background-position: -276px -816px; }
+.icon-large.icon-flickr{ background-position: -276px -850px; }
+.icon-large.icon-last-fm{ background-position: -276px -884px; }
+.icon-large.icon-rss{ background-position: -276px -918px; }
+.icon-large.icon-skype{ background-position: -276px -952px; }
+
diff --git a/static/third-party/bootstrap-glyphicons/css/bootstrap.icon-large.min.css b/static/third-party/bootstrap-glyphicons/css/bootstrap.icon-large.min.css
new file mode 100644
index 0000000..6d54222
--- /dev/null
+++ b/static/third-party/bootstrap-glyphicons/css/bootstrap.icon-large.min.css
@@ -0,0 +1 @@
+.icon-large{background-image:url("../img/glyphicons.png");background-position:24px 24px;background-repeat:no-repeat;display:inline-block;height:28px;line-height:28px;vertical-align:text-bottom;width:28px}.icon-large.icon-glass{background-position:0 0}.icon-large.icon-leaf{background-position:0 -34px}.icon-large.icon-dog{background-position:0 -69px}.icon-large.icon-user{background-position:0 -104px}.icon-large.icon-girl{background-position:0 -136px}.icon-large.icon-car{background-position:0 -168px}.icon-large.icon-user-add{background-position:0 -200px}.icon-large.icon-user-remove{background-position:0 -232px}.icon-large.icon-film{background-position:0 -264px}.icon-large.icon-magic{background-position:0 -300px}.icon-large.icon-envelope{background-position:0 -330px}.icon-large.icon-camera{background-position:0 -360px}.icon-large.icon-heart{background-position:0 -390px}.icon-large.icon-beach-umbrella{background-position:0 -422px}.icon-large.icon-train{background-position:0 -457px}.icon-large.icon-print{background-position:0 -494px}.icon-large.icon-bin{background-position:0 -528px}.icon-large.icon-trash{background-position:0 -528px}.icon-large.icon-music{background-position:0 -566px}.icon-large.icon-note{background-position:0 -601px}.icon-large.icon-cogwheel{background-position:0 -636px}.icon-large.icon-cog{background-position:0 -636px}.icon-large.icon-home{background-position:0 -670px}.icon-large.icon-snowflake{background-position:0 -706px}.icon-large.icon-fire{background-position:0 -744px}.icon-large.icon-cogwheels{background-position:0 -780px}.icon-large.icon-parents{background-position:0 -816px}.icon-large.icon-binoculars{background-position:0 -848px}.icon-large.icon-road{background-position:0 -882px}.icon-large.icon-search{background-position:0 -916px}.icon-large.icon-cars{background-position:0 -950px}.icon-large.icon-pencil{background-position:0 -985px}.icon-large.icon-bus{background-position:0 -1020px}.icon-large.icon-wifi-alt{background-position:0 -1055px}.icon-large.icon-luggage{background-position:0 -1091px}.icon-large.icon-old-man{background-position:0 -1128px}.icon-large.icon-woman{background-position:0 -1162px}.icon-large.icon-file{background-position:0 -1194px}.icon-large.icon-credit{background-position:0 -1228px}.icon-large.icon-airplane,.icon-large.icon-plane{background-position:0 -1262px}.icon-large.icon-notes{background-position:0 -1297px}.icon-large.icon-stats{background-position:0 -1332px}.icon-large.icon-charts{background-position:0 -1367px}.icon-large.icon-pie-chart{background-position:0 -1401px}.icon-large.icon-group{background-position:0 -1436px}.icon-large.icon-keys{background-position:0 -1468px}.icon-large.icon-calendar{background-position:0 -1504px}.icon-large.icon-router{background-position:0 -1539px}.icon-large.icon-camera-small{background-position:0 -1575px}.icon-large.icon-dislikes{background-position:0 -1609px}.icon-large.icon-star-empty{background-position:0 -1609px}.icon-large.icon-star{background-position:0 -1643px}.icon-large.icon-link{background-position:0 -1677px}.icon-large.icon-eye-open{background-position:-1px -1704px}.icon-large.icon-eye-close{background-position:-1px -1737px}.icon-large.icon-alarm{background-position:0 -1771px}.icon-large.icon-clock{background-position:0 -1807px}.icon-large.icon-time{background-position:0 -1807px}.icon-large.icon-stopwatch{background-position:0 -1841px}.icon-large.icon-projector{background-position:0 -1878px}.icon-large.icon-history{background-position:0 -1913px}.icon-large.icon-truck{background-position:0 -1949px}.icon-large.icon-cargo{background-position:0 -1986px}.icon-large.icon-compass{background-position:-46px 0}.icon-large.icon-keynote{background-position:-46px -34px}.icon-large.icon-attach{background-position:-46px -74px}.icon-large.icon-power{background-position:-46px -108px}.icon-large.icon-off{background-position:-46px -108px}.icon-large.icon-lightbulb{background-position:-46px -142px}.icon-large.icon-tag{background-position:-46px -178px}.icon-large.icon-tags{background-position:-46px -212px}.icon-large.icon-cleaning{background-position:-46px -246px}.icon-large.icon-ruller{background-position:-46px -281px}.icon-large.icon-gift{background-position:-46px -305px}.icon-large.icon-umbrella{background-position:-46px -340px}.icon-large.icon-book{background-position:-46px -378px}.icon-large.icon-bookmark{background-position:-44px -412px}.icon-large.icon-signal{background-position:-46px -446px}.icon-large.icon-cup{background-position:-46px -479px}.icon-large.icon-stroller{background-position:-46px -513px}.icon-large.icon-headphones{background-position:-46px -549px}.icon-large.icon-headset{background-position:-46px -583px}.icon-large.icon-warning-sign{background-position:-46px -621px}.icon-large.icon-signal{background-position:-46px -655px}.icon-large.icon-retweet{background-position:-47px -680px}.icon-large.icon-refresh{background-position:-46px -714px}.icon-large.icon-roundabout{background-position:-46px -750px}.icon-large.icon-random{background-position:-46px -787px}.icon-large.icon-heat{background-position:-46px -817px}.icon-large.icon-repeat{background-position:-46px -852px}.icon-large.icon-display{background-position:-46px -888px}.icon-large.icon-log-book{background-position:-46px -922px}.icon-large.icon-adress-book{background-position:-46px -956px}.icon-large.icon-magnet{background-position:-46px -990px}.icon-large.icon-table{background-position:-46px -1023px}.icon-large.icon-adjust{background-position:-46px -1057px}.icon-large.icon-tint{background-position:-46px -1093px}.icon-large.icon-crop{background-position:-46px -1129px}.icon-large.icon-vector-path-square{background-position:-46px -1165px}.icon-large.icon-vector-path-circle{background-position:-46px -1199px}.icon-large.icon-vector-path-polygon{background-position:-46px -1233px}.icon-large.icon-vector-path-line{background-position:-46px -1268px}.icon-large.icon-vector-path-curve{background-position:-46px -1302px}.icon-large.icon-vector-path-all{background-position:-46px -1336px}.icon-large.icon-font{background-position:-46px -1370px}.icon-large.icon-italic{background-position:-46px -1403px}.icon-large.icon-bold{background-position:-46px -1437px}.icon-large.icon-text-underline{background-position:-46px -1471px}.icon-large.icon-text-strike{background-position:-46px -1505px}.icon-large.icon-text-height{background-position:-46px -1537px}.icon-large.icon-text-width{background-position:-46px -1571px}.icon-large.icon-text-resize{background-position:-46px -1605px}.icon-large.icon-left-indent,.icon-large.icon-indent-left{background-position:-46px -1641px}.icon-large.icon-right-indent,.icon-large.icon-indent-right{background-position:-46px -1673px}.icon-large.icon-align-left{background-position:-46px -1705px}.icon-large.icon-align-center{background-position:-46px -1736px}.icon-large.icon-align-right{background-position:-46px -1767px}.icon-large.icon-justify{background-position:-46px -1798px}.icon-large.icon-align-justify{background-position:-46px -1798px}.icon-large.icon-list{background-position:-46px -1829px}.icon-large.icon-text-smaller{background-position:-46px -1860px}.icon-large.icon-text-bigger{background-position:-46px -1886px}.icon-large.icon-embed{background-position:-47px -1910px}.icon-large.icon-embed-close{background-position:-47px -1940px}.icon-large.icon-adjust{background-position:-46px -1976px}.icon-large.icon-message-full{background-position:-92px 0}.icon-large.icon-message-empty{background-position:-92px -38px}.icon-large.icon-message-in{background-position:-92px -76px}.icon-large.icon-message-out{background-position:-92px -114px}.icon-large.icon-message-plus{background-position:-92px -152px}.icon-large.icon-message-minus{background-position:-92px -185px}.icon-large.icon-message-ban{background-position:-92px -218px}.icon-large.icon-message-flag{background-position:-92px -251px}.icon-large.icon-message-lock{background-position:-92px -284px}.icon-large.icon-message-new{background-position:-92px -318px}.icon-large.icon-inbox{background-position:-92px -350px}.icon-large.icon-inbox-plus{background-position:-92px -383px}.icon-large.icon-inbox-minus{background-position:-92px -420px}.icon-large.icon-inbox-lock{background-position:-92px -457px}.icon-large.icon-inbox-in{background-position:-92px -495px}.icon-large.icon-inbox-out{background-position:-92px -531px}.icon-large.icon-computer-locked{background-position:-92px -567px}.icon-large.icon-computer-service{background-position:-92px -601px}.icon-large.icon-computer-proces{background-position:-92px -635px}.icon-large.icon-phone{background-position:-92px -669px}.icon-large.icon-database-lock{background-position:-92px -704px}.icon-large.icon-database-plus{background-position:-92px -742px}.icon-large.icon-database-minus{background-position:-92px -779px}.icon-large.icon-database-ban{background-position:-92px -816px}.icon-large.icon-folder-open{background-position:-92px -853px}.icon-large.icon-folder-plus{background-position:-92px -885px}.icon-large.icon-folder-minus{background-position:-92px -920px}.icon-large.icon-folder-lock{background-position:-92px -955px}.icon-large.icon-folder-flag{background-position:-92px -991px}.icon-large.icon-folder-new{background-position:-92px -1026px}.icon-large.icon-check{background-position:-92px -1060px}.icon-large.icon-edit{background-position:-92px -1088px}.icon-large.icon-new-window{background-position:-92px -1119px}.icon-large.icon-more-windows{background-position:-92px -1151px}.icon-large.icon-show-big-thumbnails{background-position:-92px -1184px}.icon-large.icon-th-large{background-position:-92px -1184px}.icon-large.icon-show-thumbnails{background-position:-92px -1216px}.icon-large.icon-th{background-position:-92px -1216px}.icon-large.icon-show-thumbnails-with-lines{background-position:-92px -1248px}.icon-large.icon-th-list{background-position:-92px -1248px}.icon-large.icon-show-lines{background-position:-92px -1273px}.icon-large.icon-playlist{background-position:-92px -1298px}.icon-large.icon-picture{background-position:-92px -1332px}.icon-large.icon-imac{background-position:-92px -1362px}.icon-large.icon-macbook{background-position:-92px -1394px}.icon-large.icon-ipad{background-position:-92px -1419px}.icon-large.icon-iphone{background-position:-92px -1456px}.icon-large.icon-iphone-transfer{background-position:-92px -1490px}.icon-large.icon-iphone-exchange{background-position:-92px -1524px}.icon-large.icon-ipod{background-position:-92px -1558px}.icon-large.icon-ipod-shuffle{background-position:-92px -1590px}.icon-large.icon-ear-plugs{background-position:-92px -1613px}.icon-large.icon-albums{background-position:-92px -1647px}.icon-large.icon-step-backward{background-position:-92px -1675px}.icon-large.icon-fast-backward{background-position:-92px -1703px}.icon-large.icon-rewind,.icon-large.icon-backwards{background-position:-92px -1731px}.icon-large.icon-play{background-position:-92px -1759px}.icon-large.icon-pause{background-position:-92px -1787px}.icon-large.icon-stop{background-position:-92px -1813px}.icon-large.icon-forward{background-position:-92px -1837px}.icon-large.icon-fast-forward{background-position:-92px -1865px}.icon-large.icon-step-forward{background-position:-92px -1893px}.icon-large.icon-eject{background-position:-92px -1921px}.icon-large.icon-facetime-video{background-position:-92px -1948px}.icon-large.icon-download-alt{background-position:-92px -1974px}.icon-large.icon-mute,.icon-large.icon-volume-off{background-position:-138px 4px}.icon-large.icon-volume-down{background-position:-134px -22px}.icon-large.icon-volume-up{background-position:-138px -52px}.icon-large.icon-screenshot{background-position:-138px -88px}.icon-large.icon-move{background-position:-138px -125px}.icon-large.icon-more{background-position:-138px -159px}.icon-large.icon-brightness-reduce{background-position:-138px -176px}.icon-large.icon-brightness-increase{background-position:-138px -206px}.icon-large.icon-circle-plus,.icon-large.icon-plus-sign{background-position:-138px -240px}.icon-large.icon-circle-minus,.icon-large.icon-minus-sign{background-position:-138px -276px}.icon-large.icon-circle-remove,.icon-large.icon-remove-sign{background-position:-138px -312px}.icon-large.icon-circle-ok,.icon-large.icon-ok-sign{background-position:-138px -348px}.icon-large.icon-circle-question-mark,.icon-large.icon-question-sign{background-position:-138px -384px}.icon-large.icon-circle-info,.icon-large.icon-info-sign{background-position:-138px -420px}.icon-large.icon-circle-exclamation-mark,.icon-large.icon-exclamation-sign{background-position:-138px -456px}.icon-large.icon-remove{background-position:-138px -492px}.icon-large.icon-ok{background-position:-138px -528px}.icon-large.icon-ban{background-position:-138px -564px}.icon-large.icon-download{background-position:-138px -600px}.icon-large.icon-upload{background-position:-138px -636px}.icon-large.icon-shopping-cart{background-position:-138px -672px}.icon-large.icon-lock{background-position:-138px -705px}.icon-large.icon-unlock{background-position:-138px -741px}.icon-large.icon-electricity{background-position:-138px -777px}.icon-large.icon-cart-out{background-position:-138px -811px}.icon-large.icon-cart-in{background-position:-138px -846px}.icon-large.icon-left-arrow{background-position:-138px -880px}.icon-large.icon-right-arrow{background-position:-138px -908px}.icon-large.icon-down-arrow{background-position:-138px -936px}.icon-large.icon-up-arrow{background-position:-138px -966px}.icon-large.icon-resize-small{background-position:-138px -996px}.icon-large.icon-resize-full{background-position:-138px -1030px}.icon-large.icon-circle-arrow-left{background-position:-138px -1064px}.icon-large.icon-circle-arrow-right{background-position:-138px -1100px}.icon-large.icon-circle-arrow-top,.icon-large.icon-circle-arrow-up{background-position:-138px -1136px}.icon-large.icon-circle-arrow-down{background-position:-138px -1172px}.icon-large.icon-play-button{background-position:-138px -1208px}.icon-large.icon-play-circle{background-position:-138px -1208px}.icon-large.icon-unshare{background-position:-138px -1244px}.icon-large.icon-share{background-position:-138px -1272px}.icon-large.icon-thin-right-arrow,.icon-large.icon-chevron-right{background-position:-138px -1300px}.icon-large.icon-thin-arrow-left,.icon-large.icon-chevron-left{background-position:-138px -1332px}.icon-large.icon-bluetooth{background-position:-138px -1364px}.icon-large.icon-euro{background-position:-138px -1398px}.icon-large.icon-usd{background-position:-138px -1431px}.icon-large.icon-bp{background-position:-138px -1467px}.icon-large.icon-moon{background-position:-138px -1501px}.icon-large.icon-sun{background-position:-138px -1536px}.icon-large.icon-cloud{background-position:-138px -1570px}.icon-large.icon-direction{background-position:-138px -1597px}.icon-large.icon-brush{background-position:-138px -1633px}.icon-large.icon-pen{background-position:-138px -1666px}.icon-large.icon-zoom-in{background-position:-138px -1700px}.icon-large.icon-zoom-out{background-position:-138px -1735px}.icon-large.icon-pin{background-position:-138px -1770px}.icon-large.icon-riflescope{background-position:-138px -1805px}.icon-large.icon-rotation-lock{background-position:-138px -1840px}.icon-large.icon-flash{background-position:-138px -1874px}.icon-large.icon-google-maps,.icon-large.icon-map-marker{background-position:-138px -1909px}.icon-large.icon-anchor{background-position:-138px -1943px}.icon-large.icon-conversation{background-position:-138px -1978px}.icon-large.icon-chat{background-position:-184px 0}.icon-large.icon-male{background-position:-184px -29px}.icon-large.icon-female{background-position:-184px -61px}.icon-large.icon-asterisk{background-position:-184px -98px}.icon-large.icon-divide{background-position:-184px -128px}.icon-large.icon-snorkel-diving{background-position:-184px -154px}.icon-large.icon-scuba-diving{background-position:-184px -189px}.icon-large.icon-oxygen-bottle{background-position:-184px -223px}.icon-large.icon-fins{background-position:-184px -260px}.icon-large.icon-fishes{background-position:-184px -297px}.icon-large.icon-boat{background-position:-184px -337px}.icon-large.icon-delete-point{background-position:-184px -371px}.icon-large.icon-qrcode{background-position:-184px -398px}.icon-large.icon-barcode{background-position:-184px -432px}.icon-large.icon-pool{background-position:-184px -466px}.icon-large.icon-buoy{background-position:-184px -500px}.icon-large.icon-spade{background-position:-184px -534px}.icon-large.icon-bank{background-position:-184px -568px}.icon-large.icon-vcard{background-position:-184px -602px}.icon-large.icon-electrical-plug{background-position:-184px -636px}.icon-large.icon-flag{background-position:-184px -671px}.icon-large.icon-credit-card{background-position:-184px -707px}.icon-large.icon-keyboard-wireless{background-position:-184px -736px}.icon-large.icon-keyboard-wired{background-position:-184px -765px}.icon-large.icon-shield{background-position:-184px -800px}.icon-large.icon-ring{background-position:-184px -834px}.icon-large.icon-cake{background-position:-184px -868px}.icon-large.icon-drink{background-position:-184px -902px}.icon-large.icon-beer{background-position:-184px -936px}.icon-large.icon-fast-food{background-position:-184px -970px}.icon-large.icon-cutlery{background-position:-184px -1004px}.icon-large.icon-pizza{background-position:-184px -1038px}.icon-large.icon-birthday-cake{background-position:-184px -1077px}.icon-large.icon-tablet{background-position:-184px -1116px}.icon-large.icon-settings{background-position:-184px -1151px}.icon-large.icon-bullets{background-position:-184px -1185px}.icon-large.icon-cardio{background-position:-184px -1218px}.icon-large.icon-pants{background-position:-184px -1254px}.icon-large.icon-sweater{background-position:-184px -1288px}.icon-large.icon-fabric{background-position:-184px -1322px}.icon-large.icon-leather{background-position:-184px -1354px}.icon-large.icon-scissors{background-position:-184px -1388px}.icon-large.icon-podium{background-position:-184px -1425px}.icon-large.icon-skull{background-position:-184px -1456px}.icon-large.icon-celebration{background-position:-184px -1490px}.icon-large.icon-tea-kettle{background-position:-184px -1525px}.icon-large.icon-french-press{background-position:-184px -1558px}.icon-large.icon-coffe-cup{background-position:-184px -1593px}.icon-large.icon-pot{background-position:-184px -1622px}.icon-large.icon-grater{background-position:-184px -1654px}.icon-large.icon-kettle{background-position:-184px -1688px}.icon-large.icon-hospital{background-position:-184px -1722px}.icon-large.icon-hospital-h{background-position:-184px -1756px}.icon-large.icon-microphone{background-position:-184px -1790px}.icon-large.icon-webcam{background-position:-184px -1824px}.icon-large.icon-temple-christianity-church{background-position:-184px -1858px}.icon-large.icon-temple-islam{background-position:-184px -1893px}.icon-large.icon-temple-hindu{background-position:-184px -1927px}.icon-large.icon-temple-buddhist{background-position:-184px -1961px}.icon-large.icon-electrical-socket-eu{background-position:-230px 0}.icon-large.icon-electrical-socket-us{background-position:-230px -33px}.icon-large.icon-bomb{background-position:-230px -66px}.icon-large.icon-comments,.icon-large.icon-comment{background-position:-230px -102px}.icon-large.icon-flower{background-position:-230px -135px}.icon-large.icon-baseball{background-position:-230px -170px}.icon-large.icon-rugby{background-position:-230px -206px}.icon-large.icon-ax{background-position:-230px -240px}.icon-large.icon-table-tennis{background-position:-230px -275px}.icon-large.icon-bowling{background-position:-230px -309px}.icon-large.icon-tree-conifer{background-position:-230px -343px}.icon-large.icon-tree-deciduous{background-position:-230px -377px}.icon-large.icon-sort{background-position:-230px -412px}.icon-large.icon-filter{background-position:-230px -447px}.icon-large.icon-gamepad{background-position:-230px -481px}.icon-large.icon-playing-dices{background-position:-230px -510px}.icon-large.icon-calculator{background-position:-230px -543px}.icon-large.icon-tie{background-position:-230px -577px}.icon-large.icon-wallet{background-position:-230px -613px}.icon-large.icon-share{background-position:-230px -643px}.icon-large.icon-sampler{background-position:-230px -675px}.icon-large.icon-piano{background-position:-230px -707px}.icon-large.icon-web-browser{background-position:-230px -741px}.icon-large.icon-blog{background-position:-230px -773px}.icon-large.icon-dashboard{background-position:-230px -806px}.icon-large.icon-certificate{background-position:-230px -840px}.icon-large.icon-bell{background-position:-230px -875px}.icon-large.icon-candle{background-position:-230px -909px}.icon-large.icon-pin-classic{background-position:-230px -944px}.icon-large.icon-iphone-shake{background-position:-230px -978px}.icon-large.icon-pin-flag{background-position:-230px -1012px}.icon-large.icon-turtle{background-position:-230px -1044px}.icon-large.icon-rabbit{background-position:-230px -1070px}.icon-large.icon-globe{background-position:-230px -1102px}.icon-large.icon-briefcase{background-position:-230px -1136px}.icon-large.icon-hdd{background-position:-230px -1167px}.icon-large.icon-thumbs-up{background-position:-230px -1198px}.icon-large.icon-thumbs-down{background-position:-230px -1229px}.icon-large.icon-hand-right{background-position:-230px -1260px}.icon-large.icon-hand-left{background-position:-230px -1289px}.icon-large.icon-hand-up{background-position:-230px -1318px}.icon-large.icon-hand-down{background-position:-230px -1354px}.icon-large.icon-fullscreen{background-position:-230px -1391px}.icon-large.icon-shopping-bag{background-position:-230px -1425px}.icon-large.icon-book-open{background-position:-230px -1461px}.icon-large.icon-nameplate{background-position:-230px -1494px}.icon-large.icon-nameplate-alt{background-position:-230px -1525px}.icon-large.icon-vases{background-position:-230px -1557px}.icon-large.icon-announcement,.icon-large.icon-bullhorn{background-position:-230px -1591px}.icon-large.icon-dumbbell{background-position:-230px -1621px}.icon-large.icon-suitcase{background-position:-230px -1647px}.icon-large.icon-file-import{background-position:-230px -1679px}.icon-large.icon-file-export{background-position:-230px -1713px}.icon-large.icon-pinterest{background-position:-230px -1747px}.icon-large.icon-dropbox{background-position:-230px -1781px}.icon-large.icon-jolicloud{background-position:-230px -1815px}.icon-large.icon-yahoo{background-position:-230px -1849px}.icon-large.icon-blogger{background-position:-230px -1883px}.icon-large.icon-picasa{background-position:-230px -1917px}.icon-large.icon-amazon{background-position:-230px -1951px}.icon-large.icon-tumblr{background-position:-230px -1985px}.icon-large.icon-wordpress{background-position:-276px 0}.icon-large.icon-instapaper{background-position:-276px -34px}.icon-large.icon-evernote{background-position:-276px -68px}.icon-large.icon-xing{background-position:-276px -102px}.icon-large.icon-zootool{background-position:-276px -136px}.icon-large.icon-dribbble{background-position:-276px -170px}.icon-large.icon-deviantart{background-position:-276px -204px}.icon-large.icon-read-it-later{background-position:-276px -238px}.icon-large.icon-linked-in{background-position:-276px -272px}.icon-large.icon-forrst{background-position:-276px -306px}.icon-large.icon-pinboard{background-position:-276px -340px}.icon-large.icon-behance{background-position:-276px -374px}.icon-large.icon-github{background-position:-276px -408px}.icon-large.icon-youtube{background-position:-276px -442px}.icon-large.icon-skitch{background-position:-276px -476px}.icon-large.icon-quora{background-position:-276px -510px}.icon-large.icon-google-plus{background-position:-276px -544px}.icon-large.icon-spootify{background-position:-276px -578px}.icon-large.icon-stumbleupon{background-position:-276px -612px}.icon-large.icon-readability{background-position:-276px -646px}.icon-large.icon-facebook{background-position:-276px -680px}.icon-large.icon-twitter-t{background-position:-276px -714px}.icon-large.icon-twitter{background-position:-276px -748px}.icon-large.icon-buzz{background-position:-276px -782px}.icon-large.icon-vimeo{background-position:-276px -816px}.icon-large.icon-flickr{background-position:-276px -850px}.icon-large.icon-last-fm{background-position:-276px -884px}.icon-large.icon-rss{background-position:-276px -918px}.icon-large.icon-skype{background-position:-276px -952px} \ No newline at end of file
diff --git a/static/third-party/bootstrap-glyphicons/glyphicons.png b/static/third-party/bootstrap-glyphicons/glyphicons.png
new file mode 100644
index 0000000..0b85819
--- /dev/null
+++ b/static/third-party/bootstrap-glyphicons/glyphicons.png
Binary files differ
diff --git a/static/third-party/bootstrap-glyphicons/img/glyphicons.png b/static/third-party/bootstrap-glyphicons/img/glyphicons.png
new file mode 120000
index 0000000..cfd4f06
--- /dev/null
+++ b/static/third-party/bootstrap-glyphicons/img/glyphicons.png
@@ -0,0 +1 @@
+../glyphicons.png \ No newline at end of file
diff --git a/templates/base.html b/templates/base.html
new file mode 100644
index 0000000..81766a4
--- /dev/null
+++ b/templates/base.html
@@ -0,0 +1,76 @@
+{% extends 'bootstrap3/bootstrap3.html' %}
+
+{% comment %}
+'base.html' for skaschool
+based on 'django-bootstrap3'
+
+Weitian LI <liweitianux@gmail.com>
+2014/04/19
+{% endcomment %}
+
+{% load bootstrap3 %}
+{% load url from future %}
+{% load staticfiles %}
+
+{# title #}
+{% block bootstrap3_title %}
+ {% block title %}(title){% endblock %}
+{% endblock %}
+
+{# bootstrap3_extra_head #}
+{% block bootstrap3_extra_head %}
+ {# custom css #}
+ {% block custom_css %}
+ <link href="{% static 'css/base.css' %}" rel="stylesheet">
+ {# css_extra #}
+ {% block css_extra %}{% endblock %}
+ {% endblock %} {# custom_css #}
+ {# add favicon #}
+ {% block favicon %}
+ {% include 'favicon.html' %}
+ {% endblock %}
+{% endblock %}
+
+{# body #}
+{% block bootstrap3_content %}
+ {# add block page #}
+ {% block page %}
+ {# message #}
+ {% block message %}
+ {# show 'django.contrib.messages' in Bootstrap alert containers #}
+ {% bootstrap_messages %}
+ {% endblock %} {# message #}
+ {# header #}
+ {% block header %}
+ <header role="banner">
+ {# navigation bar #}
+ {% block navbar %}
+ {% include 'navbar.html' %}
+ {% endblock %} {# navbar #}
+ {# header_extra #}
+ {% block header_extra %}{% endblock %}
+ </header>
+ {% endblock %} {# header #}
+ {# main #}
+ {% block main %}
+ <main role="main">
+ {# sidebar #}
+ {% block sidebar %}{% endblock %}
+ {# content #}
+ {% block content %}{% endblock %}
+ </main>
+ {% endblock %} {# main #}
+ {# footer #}
+ {% block footer %}{% endblock %}
+ {% endblock page %} {# page #}
+{% endblock %} {# bootstrap3_content #}
+
+{# bootstrap3_extra_scripts #}
+{% block bootstrap3_extra_script %}
+ {# extra javascript files #}
+ {% block js_extra %}{% endblock %}
+ {# custom script (e.g. built-in js code) #}
+ {% block custom_script %}{% endblock %}
+{% endblock %} {# bootstrap3_extra_script #}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/favicon.html b/templates/favicon.html
new file mode 100644
index 0000000..e6a0255
--- /dev/null
+++ b/templates/favicon.html
@@ -0,0 +1,5 @@
+{# Favicons: to be included in 'base.html' #}
+{% load staticfiles %}
+<link rel="apple-touch-icon-precomposed" sizes="144x144" href="{% static 'images/apple-touch-icon-144-precomposed.png' %}">
+<link rel="shortcut icon" href="{% static 'images/favicon.png' %}">
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..6b57b80
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,50 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+
+{# index page for skaschool #}
+
+{% block title %}
+首页 | 2014 SKA Summer School
+{% endblock %}
+
+{% block css_extra %}
+ <link href="{% static 'css/index.css' %}" rel="stylesheet">
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h1>第二届 中国SKA暑期学校</h1>
+ <h1>暨 中国-新西兰联合SKA暑期学校</h1>
+ <h2>China-New Zealand Joint SKA Summer School</h2>
+
+ <br>
+ <p class="lead">
+ 上海,2014,6月28日-7月5日 <br>
+ June 28 - July 05, 2014, Shanghai
+ </p>
+
+ <br>
+ <p>
+ <a href="#" class="btn btn-outline-inverse btn-lg">了解更多</a>
+ <a href="{% url 'registration_register' %}" class="btn btn-outline-inverse btn-lg">注册参加</a>
+ </p>
+ </div>
+{% endblock %} {# content #}
+
+{% block footer %}
+ <footer class="container" role="contentinfo">
+ <p>Brought to you by: <strong>Weitian LI</strong>.</p>
+ <ul class="masthead-links">
+ <li>Powered by:</li>
+ <li><a href="https://www.djangoproject.com/">Django</a></li>
+ <li><a href="http://getbootstrap.com/">Bootstrap</a></li>
+ </ul>
+ </footer>
+{% endblock %}
+
+{% block js_extra %}
+ <script src="{% static 'js/index.js' %}" type="text/javascript"></script>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/navbar.html b/templates/navbar.html
new file mode 100644
index 0000000..6296c6c
--- /dev/null
+++ b/templates/navbar.html
@@ -0,0 +1,49 @@
+{# navbar: to be included in 'base.html' #}
+{% load url from future %}
+{% load staticfiles %}
+<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
+ <div class="container">
+ <!-- Brand and toggle get grouped for better mobile display -->
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#ska-navbar-collapse">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="navbar-brand" href="{% url 'index' %}">SKA暑期学校</a>
+ </div> <!-- navbar-header -->
+ <!-- Collect the nav links, forms, and other content for toggling -->
+ <div class="collapse navbar-collapse" id="ska-navbar-collapse">
+ <ul class="nav navbar-nav">
+ <li><a href="#">介绍</a></li>
+ <li><a href="#">通知</a></li>
+ <li><a href="#">日程</a></li>
+ <li><a href="#">组委会</a></li>
+ <li><a href="#">交通/食宿</a></li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">更多 <b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li><a href="#">下载</a></li>
+ <li><a href="#">赞助方</a></li>
+ <li><a href="#">联系方式</a></li>
+ <li class="divider"></li>
+ <li><a href="#">关于</a></li>
+ </ul>
+ </li>
+ </ul>
+ <ul class="nav navbar-nav navbar-right">
+ <!-- <li><a href="#">English</a></li> -->
+ {% if user.is_authenticated %}
+ <li><a href="{% url 'profile' %}" class="navbar-link">{{ user.username }}</a></li>
+ <li><div><a href="{% url 'logout' %}" class="btn btn-default navbar-btn">退出</a></div></li>
+ {% else %}
+ <!-- wrap 'navbar-btn' within 'div' -->
+ <li><div><a href="{% url 'registration_register' %}" class="btn btn-default navbar-btn">注册</a></div></li>
+ <li><div><a href="{% url 'login' %}" class="btn btn-primary navbar-btn">登录</a></div></li>
+ {% endif %}
+ </ul>
+ </div> <!-- /.navbar-collapse -->
+ </div> <!-- /.container-->
+</nav>
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/registration/activate.html b/templates/registration/activate.html
new file mode 100644
index 0000000..113d1b3
--- /dev/null
+++ b/templates/registration/activate.html
@@ -0,0 +1,24 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# step 3. activating ... #}
+{% comment %}
+Note: This page is showed when activation failed.
+ Otherwise, it will be redirect to 'registration_activation_complete'
+{% endcomment %}
+
+{% block title %}
+激活失败 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>激活失败</h2>
+ <p class="lead">Oops, 激活您的账户时遇到一点小问题,请检查激活链接是否正确并且没有过期……</p>
+ <p>如果您还是不能激活账户,请直接与我们联系:<a href="mailto:skaschool2014@163.com"><code>skaschool2014@163.com</code></a></p>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/registration/activation_complete.html b/templates/registration/activation_complete.html
new file mode 100644
index 0000000..d27622a
--- /dev/null
+++ b/templates/registration/activation_complete.html
@@ -0,0 +1,22 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# step 4. activation complete #}
+
+{% block title %}
+成功激活 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>成功激活</h2>
+ <p class="lead">您已成功激活账户。</p>
+
+ <br>
+ <p><a href="{% url 'login' %}" class="btn btn-primary">登录</a></p>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/registration/activation_email.txt b/templates/registration/activation_email.txt
new file mode 100644
index 0000000..0667fa0
--- /dev/null
+++ b/templates/registration/activation_email.txt
@@ -0,0 +1,14 @@
+Hello,
+
+Please follow the link below to activate your account at
+"2014 SKA Summer School"({{ site }}).
+
+http://{{ site }}/accounts/activate/{{ activation_key }}
+
+Note: this link will expire in {{ expiration_days }} days.
+
+
+Best regards.
+
+2014 SKA Summer School Team
+
diff --git a/templates/registration/activation_email_subject.txt b/templates/registration/activation_email_subject.txt
new file mode 100644
index 0000000..215f006
--- /dev/null
+++ b/templates/registration/activation_email_subject.txt
@@ -0,0 +1 @@
+激活您的账户
diff --git a/templates/registration/registration_closed.html b/templates/registration/registration_closed.html
new file mode 100644
index 0000000..7368c71
--- /dev/null
+++ b/templates/registration/registration_closed.html
@@ -0,0 +1,19 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+
+{# registration closed #}
+
+{% block title %}
+注册已关闭 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>注册已关闭</h2>
+ <p class="lead">很抱歉,暑期学校注册已经关闭。</p>
+ <p>如果您有需要,请与我们联系:<a href="mailto:skaschool2014@163.com"><code>skaschool2014@163.com</code></a></p>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/registration/registration_complete.html b/templates/registration/registration_complete.html
new file mode 100644
index 0000000..553a154
--- /dev/null
+++ b/templates/registration/registration_complete.html
@@ -0,0 +1,27 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# step 2. registration complete #}
+
+{% block title %}
+注册完成 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>注册完成</h2>
+ <p class="lead">
+ 您已顺利完成注册。我们已向您注册使用的邮箱发送了激活邮件,请留意查收,并使用其中的链接激活账户。
+ </p>
+
+ <br>
+ <p>
+ 还未收到激活邮件?
+ <a href="#" class="btn btn-default">重新发送激活邮件</a>
+ </p>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/registration/registration_form.html b/templates/registration/registration_form.html
new file mode 100644
index 0000000..31316fe
--- /dev/null
+++ b/templates/registration/registration_form.html
@@ -0,0 +1,25 @@
+{% extends 'base.html' %}
+{% load staticfiles %}
+{% load url from future %}
+{% load bootstrap3 %}
+
+{# step 1. registration #}
+
+{% block title %}
+注册 | 2014 SKA Summer School
+{% endblock %}
+
+{% block content %}
+ <div class="container">
+ <h2>注册账户</h2>
+ <br>
+
+ <form role="form" class="form-horizontal" method="post">
+ {% csrf_token %}
+ {% bootstrap_form form layout='horizontal' %}
+ {% buttons submit='提交' reset='重置' layout='horizontal' %}{% endbuttons %}
+ </form>
+ </div>
+{% endblock %}
+
+{# vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=htmldjango.html: #}
diff --git a/templates/test.html b/templates/test.html
new file mode 100644
index 0000000..85ec3e6
--- /dev/null
+++ b/templates/test.html
@@ -0,0 +1,3 @@
+{% extends 'base.html' %}
+
+{# vim: set ts=8 sw=4 tw=0 fenc=utf-8 ft=htmldjango.html: #}