From 739fde442c1570d11348314b135b86b134c63fe9 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 8 Mar 2012 01:57:51 +0800 Subject: [PATCH 01/56] =?UTF-8?q?=E5=BC=80=E5=A7=8B=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api.py | 19 - backstage.py | 184 --- config.example.py | 29 - contest.py | 36 - forum.py | 146 --- home.py | 24 - i18n/base.po | 499 -------- i18n/en_US/LC_MESSAGES/onlinejudge.mo | Bin 378 -> 0 bytes i18n/zh_CN.po | 495 -------- i18n/zh_CN/LC_MESSAGES/onlinejudge.mo | Bin 6466 -> 0 bytes i18n/zh_TW.po | 495 -------- i18n/zh_TW/LC_MESSAGES/onlinejudge.mo | Bin 6496 -> 0 bytes judge/__init__.py | 664 ----------- judge/base/__init__.py | 161 +-- judge/filters/__init__.py | 178 +-- judge/utils/__init__.py | 21 - lang.py | 17 - main.py | 107 +- member.py | 380 ------ note.py | 124 -- problem.py | 85 -- scheme.sql | 328 ----- static/css/bootstrap-responsive.min.css | 3 - static/css/bootstrap.min.css | 610 ---------- static/css/ie.css | 4 - static/css/style.css | 894 -------------- static/css/timepicker.css | 566 --------- static/img/404.png | Bin 88597 -> 0 bytes static/img/500.png | Bin 117959 -> 0 bytes static/img/avatar.png | Bin 1323 -> 0 bytes static/img/background-dark.png | Bin 23656 -> 0 bytes static/img/bg-black.gif | Bin 14700 -> 0 bytes static/img/bg-noise.jpg | Bin 3438 -> 0 bytes static/img/error.jpg | Bin 110832 -> 0 bytes static/img/glyphicons-halflings-white.png | Bin 4352 -> 0 bytes static/img/glyphicons-halflings.png | Bin 4352 -> 0 bytes static/img/lines.jpg | Bin 19856 -> 0 bytes static/js/base.js | 5 - static/js/bootstrap.min.js | 1 - static/js/jquery-ui-timepicker-addon.js | 1326 --------------------- static/js/jquery-ui.min.js | 414 ------- static/js/note.js | 48 - static/js/problem.js | 9 - static/js/timepicker.js | 38 - tpl/404.html | 35 - tpl/500.html | 38 - tpl/backstage/contest_create.html | 73 -- tpl/backstage/index.html | 5 - tpl/backstage/node_create.html | 41 - tpl/backstage/problem_add.html | 136 --- tpl/contest.html | 95 -- tpl/contest_list.html | 31 - tpl/count.html | 15 - tpl/error.html | 44 - tpl/footer.html | 3 - tpl/forget.html | 15 - tpl/forum.html | 47 - tpl/header.html | 165 --- tpl/home.html | 79 -- tpl/index.html | 1 - tpl/member.html | 45 - tpl/member_note.html | 24 - tpl/node.html | 62 - tpl/note.html | 19 - tpl/note_create.html | 57 - tpl/problem.html | 95 -- tpl/problem_list.html | 23 - tpl/reset.html | 21 - tpl/settings.html | 91 -- tpl/settings_changepass.html | 32 - tpl/signin.html | 50 - tpl/signup.html | 54 - tpl/submit.html | 32 - tpl/test.html | 1 - tpl/topic.html | 87 -- tpl/topic_create.html | 35 - 76 files changed, 47 insertions(+), 9414 deletions(-) delete mode 100644 api.py delete mode 100644 backstage.py delete mode 100644 config.example.py delete mode 100644 contest.py delete mode 100644 forum.py delete mode 100644 home.py delete mode 100644 i18n/base.po delete mode 100644 i18n/en_US/LC_MESSAGES/onlinejudge.mo delete mode 100644 i18n/zh_CN.po delete mode 100644 i18n/zh_CN/LC_MESSAGES/onlinejudge.mo delete mode 100644 i18n/zh_TW.po delete mode 100644 i18n/zh_TW/LC_MESSAGES/onlinejudge.mo delete mode 100644 judge/utils/__init__.py delete mode 100644 lang.py delete mode 100644 member.py delete mode 100644 note.py delete mode 100644 problem.py delete mode 100644 scheme.sql delete mode 100644 static/css/bootstrap-responsive.min.css delete mode 100644 static/css/bootstrap.min.css delete mode 100644 static/css/ie.css delete mode 100644 static/css/style.css delete mode 100644 static/css/timepicker.css delete mode 100644 static/img/404.png delete mode 100644 static/img/500.png delete mode 100644 static/img/avatar.png delete mode 100644 static/img/background-dark.png delete mode 100644 static/img/bg-black.gif delete mode 100644 static/img/bg-noise.jpg delete mode 100644 static/img/error.jpg delete mode 100644 static/img/glyphicons-halflings-white.png delete mode 100644 static/img/glyphicons-halflings.png delete mode 100644 static/img/lines.jpg delete mode 100644 static/js/base.js delete mode 100644 static/js/bootstrap.min.js delete mode 100644 static/js/jquery-ui-timepicker-addon.js delete mode 100644 static/js/jquery-ui.min.js delete mode 100644 static/js/note.js delete mode 100644 static/js/problem.js delete mode 100644 static/js/timepicker.js delete mode 100644 tpl/404.html delete mode 100644 tpl/500.html delete mode 100644 tpl/backstage/contest_create.html delete mode 100644 tpl/backstage/index.html delete mode 100644 tpl/backstage/node_create.html delete mode 100644 tpl/backstage/problem_add.html delete mode 100644 tpl/contest.html delete mode 100644 tpl/contest_list.html delete mode 100644 tpl/count.html delete mode 100644 tpl/error.html delete mode 100644 tpl/footer.html delete mode 100644 tpl/forget.html delete mode 100644 tpl/forum.html delete mode 100644 tpl/header.html delete mode 100644 tpl/home.html delete mode 100644 tpl/index.html delete mode 100644 tpl/member.html delete mode 100644 tpl/member_note.html delete mode 100644 tpl/node.html delete mode 100644 tpl/note.html delete mode 100644 tpl/note_create.html delete mode 100644 tpl/problem.html delete mode 100644 tpl/problem_list.html delete mode 100644 tpl/reset.html delete mode 100644 tpl/settings.html delete mode 100644 tpl/settings_changepass.html delete mode 100644 tpl/signin.html delete mode 100644 tpl/signup.html delete mode 100644 tpl/submit.html delete mode 100644 tpl/test.html delete mode 100644 tpl/topic.html delete mode 100644 tpl/topic_create.html diff --git a/api.py b/api.py deleted file mode 100644 index b64c51f..0000000 --- a/api.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- - -from tornado.web import HTTPError - -from judge import ProblemDBMixin -from judge.base import BaseHandler - -class ProblemGetAPIHandler(BaseHandler, ProblemDBMixin): - def get(self, pid): - try: - pid = int(pid) - except ValueError: - raise HTTPError(404) - return - problem = self.select_problem_by_id(pid) - if problem: - self.write(problem.title) - return - raise HTTPError(404) diff --git a/backstage.py b/backstage.py deleted file mode 100644 index 97c6be6..0000000 --- a/backstage.py +++ /dev/null @@ -1,184 +0,0 @@ -# -*- coding: utf-8 -*- - -import datetime -import functools -from tornado.web import HTTPError -from tornado.web import authenticated - -from judge import Node -from judge import Contest -from judge import Problem -from judge import NodeDBMixin -from judge import ProblemDBMixin -from judge import ContestDBMixin -from judge.base import BaseHandler -from judge.utils import escape - -def backstage(method): - """Decorate methods with this to require that user be NOT logged in""" - @functools.wraps(method) - def wrapper(self, *args, **kwargs): - if self.current_user: - if self.current_user['admin']: - return method(self, *args, **kwargs) - raise HTTPError(404) - return wrapper - - -class BackstageHandler(BaseHandler): - @backstage - def get(self): - title = self._("Backstage") - self.render("backstage/index.html", locals()) - -class AddProblemHandler(BaseHandler, ProblemDBMixin): - @backstage - def get(self): - title = self._("Add Problem") - pid = self.get_argument("pid", default = 0) - problem = None - if pid: - problem = self.select_problem_by_id(pid) - problem.content = self.xhtml_escape(problem.content) - tags = self.select_problem_tag_by_pid(problem.id) - self.render("backstage/problem_add.html", locals()) - @backstage - def post(self): - probtitle = self.get_argument('probtitle', default = None) - shortname = self.get_argument('shortname', default = None) - timelimit = self.get_argument('timelimit', default = 1000) - memlimit = self.get_argument('memlimit', default = 1000) - testpoint = self.get_argument('testpoint', default = None) - invisible = self.get_argument('invisible', default = 0) - content = self.get_argument('content', default = None) - pid = self.get_argument('pid', default = 0) - tags = self.get_arguments('tags[]') - tags = map(self.xhtml_escape, tags) - problem = Problem() - error = [] - error.extend(self._check_text_value(probtitle, self._("Title"), True)) - error.extend(self._check_text_value(shortname, self._("Short Name"), True)) - error.extend(self._check_text_value(content, self._("Content"), True)) - error.extend(self._check_text_value(testpoint, self._("Test Point"), True)) - problem.id = int(pid) - problem.title = self.xhtml_escape(probtitle) - problem.shortname = self.xhtml_escape(shortname) - problem.timelimit = self.xhtml_escape(timelimit) - problem.memlimit = self.xhtml_escape(memlimit) - problem.testpoint = self.xhtml_escape(testpoint) - problem.invisible = self.xhtml_escape(invisible) - if invisible not in ['1', '0', 0]: - error.append(self._("Invisible is Invalid!")) - if error: - problem.content = self.xhtml_escape(content) - title = self._("Add Problem") - self.render("backstage/problem_add.html", locals()) - return - problem.content = content - if problem.id: - self.update_problem(problem) - self.delete_problem_tag_by_problem_id(problem.id) - else: - self.insert_problem(problem) - for tag in tags: - self.insert_problem_tag(tag, problem.id) - self.redirect('/problem/%d' % problem.id) - -class CreateNodeHandler(BaseHandler, NodeDBMixin): - @backstage - def get(self): - title = self._("Add Node") - nid = self.get_argument('nid', default = 0) - node = None - if nid: - node = self.select_node_by_id(nid) - title = self._("Edit Node") - self.render("backstage/node_create.html", locals()) - @backstage - def post(self): - nid = self.get_argument("nid", default = 0) - name = self.get_argument("name", default = None) - description = self.get_argument("description", default = None) - link = self.get_argument("link", default = None) - node = Node() - error = [] - error.extend(self._check_text_value(name, self._("Node Name"), True, max = 50)) - error.extend(self._check_text_value(description, self._("Node Description"), True, max = 2000)) - error.extend(self._check_text_value(link, self._("Node Link"), True, max = 30)) - node.id = int(nid) - node.name = self.xhtml_escape(name) - node.description = self.xhtml_escape(description) - node.link = self.xhtml_escape(link) - if error: - title = self._("Add Node") - if node.id: - title = self._("Edit Node") - self.render("backstage/node_create.html", locals()) - return - if node.id: - self.update_node(node) - else: - self.insert_node(node) - self.redirect("/forum/go/%s" % node.link) - -class CreateContestHandler(BaseHandler, ProblemDBMixin, ContestDBMixin): - @backstage - def get(self): - title = self._("Add Contest") - cid = self.get_argument("cid", default = 0) - contest = None - related_js = True - timepicker_js = True - if cid: - contest = self.select_contest_by_id(cid) - title = self._("Edit Contest") - related_problem = self.select_contest_problem_by_cid(contest.id) - self.render("backstage/contest_create.html", locals()) - @backstage - def post(self): - title = self.get_argument("title", default = "") - description = self.get_argument("description", default = "") - start_time = self.get_argument("start_time", default = "") - end_time = self.get_argument("end_time", default = "") - invisible = self.get_argument("invisible", default = 0) - cid = self.get_argument("cid", default = None) - related_problem = self.get_arguments("link_problem[]") - contest = Contest() - contest.id = cid - error = [] - error.extend(self._check_text_value(title, self._("Title"), required = True, max = 100)) - error.extend(self._check_text_value(description, self._("Description"), max = 2000)) - try: - start_datetime = datetime.datetime.strptime(start_time, "%m/%d/%Y %H:%M") - end_datetime = datetime.datetime.strptime(end_time, "%m/%d/%Y %H:%M") - except ValueError: - error.append(self._("Start/End Time Format is Invalid.")) - else: - if start_datetime > end_datetime: - error.append(self._("Start/End Time is invalid.")) - contest.title = self.xhtml_escape(title) - contest.description = self.xhtml_escape(description) - contest.start_time = self.xhtml_escape(start_time) - contest.end_time = self.xhtml_escape(end_time) - contest.invisible = self.xhtml_escape(invisible) - contest.related_problem = related_problem - if error: - title = self._("Add Contest") - related_js = True - timepicker_js = True - related_problem = [] - for pid in contest.related_problem: - related_problem.append(self.select_problem_by_id(pid)) - self.render("backstage/contest_create.html", locals()) - return - contest.start_time = start_datetime - contest.end_time = end_datetime - if contest.id: - self.update_contest(contest) - self.delete_contest_problem_by_cid(contest.id) - else: - self.insert_contest(contest) - print contest.related_problem - for pid in contest.related_problem: - self.insert_contest_problem(cid = contest.id, pid = pid) - self.redirect("/contest/%d" % int(contest.id)) diff --git a/config.example.py b/config.example.py deleted file mode 100644 index 6a309cb..0000000 --- a/config.example.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -import os - -mysql_config = { - 'mysql_host' : '', - 'mysql_user' : '', - 'mysql_password' : '', - 'mysql_database' : '' -} - -accept_lang = { - 'zh_cn' : 'zh_CN', - 'en' : 'en_US', -} - -site_config = { - 'site_title' : u'Online Judge', - 'base_domain' : '', - 'login_url' : '/signin', - 'template_path' : os.path.join(os.path.dirname(__file__), 'tpl'), - 'static_path' : os.path.join(os.path.dirname(__file__), "static"), - 'i18n_path' : os.path.join(os.path.dirname(__file__), 'i18n'), - 'xsrf_cookies' : True, - 'cookie_secret' : '', # - 'bcrypt_salt' : '', # import bcrypt; bcrypt.gensalt(log_rounds=4) - 'default_mail' : 'no-reply@fanhe.org', - 'mail_server' : '127.0.0.1', -} diff --git a/contest.py b/contest.py deleted file mode 100644 index 38e7b91..0000000 --- a/contest.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- - -import datetime - -from tornado.web import HTTPError -from tornado.web import authenticated - -from judge import ContestDBMixin -from judge.base import BaseHandler - -class ContestHandler(BaseHandler, ContestDBMixin): - @authenticated - def get(self, cid): - try: - cid = int(cid) - except ValueError: - raise HTTPError(404) - return - contest = self.select_contest_by_id(cid) - if not contest: - raise HTTPError(404) - return - related_problem = self.select_contest_submit_by_cid_and_uid(contest.id, self.current_user.id) - now = datetime.datetime.now() - self.render("contest.html", locals()) - - -class ContestListHandler(BaseHandler, ContestDBMixin): - def get(self): - start = self.get_argument("start", default = 0) - title = self._("Contest List") - if self.current_user and self.current_user.admin: - contests = self.select_contest(start = int(start)) - else: - contests = self.select_contest_visible(start = int(start)) - self.render("contest_list.html", locals()) diff --git a/forum.py b/forum.py deleted file mode 100644 index 4a9634a..0000000 --- a/forum.py +++ /dev/null @@ -1,146 +0,0 @@ -# -*- coding: utf-8 -*- - -from tornado.web import HTTPError -from tornado.web import authenticated - -from judge import Reply -from judge import Topic -from judge import NodeDBMixin -from judge import ReplyDBMixin -from judge import TopicDBMixin -from judge.base import BaseHandler - -class ForumIndexHandler(BaseHandler, TopicDBMixin, NodeDBMixin): - def get(self): - topics = self.select_topic_by_last_reply() - nodes = self.select_nodes() - title = self._("Forum") - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Forum'), '/forum')) - self.render("forum.html", locals()) - -class ForumNodeHandler(BaseHandler, NodeDBMixin, TopicDBMixin): - def get(self, link): - node = self.select_node_by_link(link) - if node: - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Forum'), '/forum')) - breadcrumb.append((node.name, '/forum/go/%s' % node.link)) - topics = self.select_topic_by_node(node.id) - title = node.name - self.render("node.html", locals()) - else: - raise HTTPError(404) - -class TopicCreateHandler(BaseHandler, NodeDBMixin, TopicDBMixin): - @authenticated - def get(self, link): - node = self.select_node_by_link(link) - tid = self.get_argument("tid", default = 0) - if node: - topic = None - if tid: - topic = self.select_topic_by_id(tid) - if not topic: - raise HTTPError(404) - if topic and not self.current_user.admin: - raise HTTPError(404) - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Forum'), '/forum')) - breadcrumb.append((node.name, '/forum/go/%s' % node.link)) - breadcrumb.append((self._('Create Topic'), '/forum/new/%s' % node.link)) - title = self._("Create Topic") - if topic: - title = self._("Edit Topic") - self.render("topic_create.html", locals()) - else: - raise HTTPError(404) - @authenticated - def post(self, link): - node = self.select_node_by_link(link) - tid = self.get_argument("tid", default = 0) - if node: - if tid: - topic = self.select_topic_by_id(tid) - if not topic: - raise HTTPError(404) - if topic and not self.current_user.admin: - raise HTTPError(404) - title = self.get_argument("title", default = None) - content = self.get_argument("content", default = None) - topic = Topic() - error = [] - error.extend(self._check_text_value(title, self._("Title"), True, max = 200)) - error.extend(self._check_text_value(content, self._("Content"), True, max = 4000)) - topic.title = self.xhtml_escape(title) - topic.content = self.xhtml_escape(content) - topic.id = tid - if error: - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Forum'), '/forum')) - breadcrumb.append((node.name, '/forum/go/%s' % node.link)) - breadcrumb.append((self._('Create Topic'), '/forum/new/%s' % node.link)) - title = self._("Create Topic") - if topic: - title = self._("Edit Topic") - self.render("topic_create.html", locals()) - return - topic.node_id = node.id - topic.member_id = self.current_user.id - if topic.id: - self.update_topic(topic) - else: - self.insert_topic(topic) - self.redirect("/forum/t/%d" % topic.id) - else: - raise HTTPError(404) - -class TopicHandler(BaseHandler, TopicDBMixin, NodeDBMixin, ReplyDBMixin): - def get(self, tid): - try: - tid = int(tid) - except ValueError: - raise HTTPError(404) - topic = self.select_topic_by_id(tid) - node = self.select_node_by_id(topic.node_id) - replies = self.select_reply_by_topic_id(tid) - reply_count = len(replies) - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Forum'), '/forum')) - breadcrumb.append((node.name, '/forum/go/%s' % node.link)) - breadcrumb.append((topic.title, '/forum/t/%s' % topic.id)) - title = topic.title - self.render("topic.html", locals()) - @authenticated - def post(self, tid): - try: - tid = int(tid) - except ValueError: - raise HTTPError(404) - content = self.get_argument('content', default = None) - error = [] - reply = Reply() - error.extend(self._check_text_value(content, self._('Reply'), True, max = 3000)) - reply.content = self.xhtml_escape(content) - if error: - topic = self.select_topic_by_id(tid) - node = self.select_node_by_id(topic.node_id) - replies = self.select_reply_by_topic_id(tid) - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Forum'), '/forum')) - breadcrumb.append((node.name, '/forum/go/%s' % node.link)) - breadcrumb.append((topic.title, '/forum/t/%s' % topic.id)) - title = topic.title - self.render("topic.html", locals()) - return - reply.member_id = self.current_user.id - reply.topic_id = tid - self.insert_reply(reply) - self.update_topic_last_reply(tid) - self.redirect('/forum/t/%d' % tid) diff --git a/home.py b/home.py deleted file mode 100644 index 47fca2b..0000000 --- a/home.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -from tornado.web import HTTPError - -from judge import Problem -from judge import NodeDBMixin -from judge import TopicDBMixin -from judge import ProblemDBMixin -from judge.base import BaseHandler - -class HomeHandler(BaseHandler, ProblemDBMixin, TopicDBMixin, NodeDBMixin): - def get(self): - if True or self.current_user: - title = self._("Home") - breadcrumb = [] - breadcrumb.append((self._("Home"), '/')) - newest_problem = self.select_problem_by_create(5) - topics = self.select_topic_by_last_reply(num = 5) - problem_count = self.count_problem() - node_count = self.count_node() - topic_count = self.count_topic() - self.render('home.html', locals()) - else: - self.render('index.html', locals()) diff --git a/i18n/base.po b/i18n/base.po deleted file mode 100644 index ed9e197..0000000 --- a/i18n/base.po +++ /dev/null @@ -1,499 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-02-17 01:04+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#: backstage.py:28 tpl/header.html:98 -msgid "Backstage" -msgstr "" - -#: backstage.py:34 backstage.py:73 tpl/header.html:103 -#: tpl/backstage/index.html:3 tpl/backstage/problem_add.html:13 -msgid "Add Problem" -msgstr "" - -#: backstage.py:55 forum.py:75 tpl/node.html:45 tpl/note_create.html:18 -#: tpl/topic_create.html:18 tpl/home.html:35 tpl/problem_list.html:6 -#: tpl/backstage/problem_add.html:18 tpl/backstage/node_create.html:18 -msgid "Title" -msgstr "" - -#: backstage.py:56 tpl/home.html:36 tpl/problem_list.html:7 -#: tpl/backstage/problem_add.html:24 -msgid "Short Name" -msgstr "" - -#: backstage.py:57 note.py:64 forum.py:76 tpl/node.html:51 -#: tpl/note_create.html:24 tpl/topic_create.html:24 -#: tpl/backstage/problem_add.html:48 tpl/problem.html:47 -msgid "Content" -msgstr "" - -#: backstage.py:58 tpl/backstage/problem_add.html:54 tpl/problem.html:53 -msgid "Input Format" -msgstr "" - -#: backstage.py:59 tpl/backstage/problem_add.html:66 tpl/problem.html:59 -msgid "Output Format" -msgstr "" - -#: backstage.py:60 tpl/problem.html:65 -msgid "Sample Input" -msgstr "" - -#: backstage.py:61 tpl/problem.html:71 -msgid "Sample Output" -msgstr "" - -#: backstage.py:86 backstage.py:109 tpl/header.html:109 -#: tpl/backstage/node_create.html:13 -msgid "Add Node" -msgstr "" - -#: backstage.py:91 backstage.py:111 -msgid "Edit Node" -msgstr "" - -#: backstage.py:101 -msgid "Node Name" -msgstr "" - -#: backstage.py:102 -msgid "Node Description" -msgstr "" - -#: backstage.py:103 -msgid "Node Link" -msgstr "" - -#: note.py:26 note.py:42 note.py:71 note.py:116 problem.py:21 problem.py:35 -#: problem.py:45 member.py:151 member.py:214 member.py:276 home.py:14 -#: home.py:16 forum.py:18 forum.py:27 forum.py:50 forum.py:82 forum.py:111 -#: forum.py:133 tpl/header.html:44 -msgid "Home" -msgstr "" - -#: note.py:28 note.py:44 note.py:73 note.py:118 -msgid "Note" -msgstr "" - -#: note.py:49 note.py:76 note.py:77 tpl/note_create.html:14 -msgid "Edit Note" -msgstr "" - -#: note.py:52 note.py:53 note.py:79 note.py:80 tpl/note_create.html:14 -#: tpl/member_note.html:4 -msgid "Write Note" -msgstr "" - -#: note.py:63 -msgid "Note Title" -msgstr "" - -#: note.py:121 -msgid "'s Note" -msgstr "" - -#: judge/base/__init__.py:42 -#, python-format -msgid "%s is too long." -msgstr "" - -#: judge/base/__init__.py:45 -#, python-format -msgid "%s is Required!" -msgstr "" - -#: problem.py:22 problem.py:24 problem.py:36 tpl/header.html:50 -#: tpl/submit.html:8 -msgid "Problem" -msgstr "" - -#: problem.py:37 -msgid "Problems" -msgstr "" - -#: problem.py:46 problem.py:47 tpl/node.html:57 tpl/note_create.html:48 -#: tpl/topic_create.html:31 tpl/header.html:62 -#: tpl/backstage/problem_add.html:78 tpl/backstage/node_create.html:38 -#: tpl/topic.html:80 tpl/problem.html:98 -msgid "Submit" -msgstr "" - -#: member.py:30 member.py:54 tpl/signup.html:47 tpl/header.html:117 -#: tpl/signin.html:40 -msgid "Sign In" -msgstr "" - -#: member.py:41 member.py:50 -msgid "Wrong Username and password combination." -msgstr "" - -#: member.py:52 member.py:299 -msgid "A username can only contain letters and digits." -msgstr "" - -#: member.py:73 member.py:119 tpl/signup.html:44 tpl/header.html:123 -#: tpl/signin.html:43 -msgid "Sign Up" -msgstr "" - -#: member.py:84 -msgid "A username should be between 3 and 15 characters long." -msgstr "" - -#: member.py:91 -msgid "That username is taken. Please choose another." -msgstr "" - -#: member.py:95 member.py:301 -msgid "A username is required!" -msgstr "" - -#: member.py:98 member.py:238 member.py:249 member.py:366 -msgid "A password should be between 6 and 32 characters long." -msgstr "" - -#: member.py:102 -msgid "A password is required!" -msgstr "" - -#: member.py:105 member.py:166 -msgid "Email address cannot be longer than 100 characters long." -msgstr "" - -#: member.py:115 member.py:176 member.py:309 -msgid "Your Email address is invalid." -msgstr "" - -#: member.py:117 member.py:178 member.py:311 -msgid "Email Address is required!" -msgstr "" - -#: member.py:145 member.py:153 member.py:212 member.py:216 tpl/header.html:87 -msgid "Settings" -msgstr "" - -#: member.py:181 -msgid "Tagline cannot be longer than 70 characters long." -msgstr "" - -#: member.py:186 -msgid "Website address cannot be longer than 200 characters long." -msgstr "" - -#: member.py:191 -msgid "Website address is invalid." -msgstr "" - -#: member.py:201 member.py:203 -msgid "Wrong Language select." -msgstr "" - -#: member.py:206 -msgid "Bio cannot be longer than 2000 characters long." -msgstr "" - -#: member.py:244 -msgid "Wrong password." -msgstr "" - -#: member.py:246 -msgid "Current password is required." -msgstr "" - -#: member.py:253 -msgid "New password is required." -msgstr "" - -#: member.py:255 tpl/settings_changepass.html:13 -#: tpl/settings_changepass.html:29 tpl/settings.html:71 -msgid "Change Password" -msgstr "" - -#: member.py:284 member.py:319 -msgid "Forget Password" -msgstr "" - -#: member.py:297 -msgid "Sorry, We couldn't find you." -msgstr "" - -#: member.py:307 -msgid "Wrong Username and Email combination." -msgstr "" - -#: member.py:317 -msgid "You can only request one reset mail in a day." -msgstr "" - -#: member.py:345 member.py:370 tpl/reset.html:14 -msgid "Reset Password" -msgstr "" - -#: member.py:363 -msgid "Two passwords do not match." -msgstr "" - -#: forum.py:16 forum.py:19 forum.py:28 forum.py:51 forum.py:83 forum.py:112 -#: forum.py:134 tpl/header.html:68 -msgid "Forum" -msgstr "" - -#: forum.py:53 forum.py:54 forum.py:85 forum.py:86 tpl/topic_create.html:14 -msgid "Create Topic" -msgstr "" - -#: forum.py:56 forum.py:88 tpl/topic_create.html:14 -msgid "Edit Topic" -msgstr "" - -#: forum.py:126 -msgid "Reply" -msgstr "" - -#: tpl/node.html:5 tpl/node.html:41 -msgid "Create New Topic" -msgstr "" - -#: tpl/node.html:33 tpl/forum.html:28 -msgid "oooops. There have no more topic." -msgstr "" - -#: tpl/node.html:33 -msgid "Create" -msgstr "" - -#: tpl/member.html:14 -msgid "ID:" -msgstr "" - -#: tpl/member.html:14 -msgid "Joined at" -msgstr "" - -#: tpl/member.html:26 -msgid "User Notes" -msgstr "" - -#: tpl/note_create.html:30 tpl/note.html:5 -msgid "Related Problem" -msgstr "" - -#: tpl/note_create.html:33 -msgid "Add" -msgstr "" - -#: tpl/forum.html:35 -msgid "Nodes" -msgstr "" - -#: tpl/home.html:4 -msgid "Notice" -msgstr "" - -#: tpl/home.html:11 -msgid "Site Count" -msgstr "" - -#: tpl/home.html:14 -msgid "Total Problems" -msgstr "" - -#: tpl/home.html:18 -msgid "Total Nodes" -msgstr "" - -#: tpl/home.html:22 -msgid "Total Topics" -msgstr "" - -#: tpl/home.html:30 -msgid "Latest Problem" -msgstr "" - -#: tpl/home.html:53 -msgid "Latest Discuss" -msgstr "" - -#: tpl/settings_changepass.html:17 tpl/settings.html:75 -msgid "Current Password" -msgstr "" - -#: tpl/settings_changepass.html:23 tpl/settings.html:81 tpl/reset.html:16 -msgid "New Password" -msgstr "" - -#: tpl/header.html:56 -msgid "Contest" -msgstr "" - -#: tpl/header.html:74 -msgid "List" -msgstr "" - -#: tpl/header.html:81 -msgid "Notes" -msgstr "" - -#: tpl/header.html:93 -msgid "Sign Out" -msgstr "" - -#: tpl/header.html:130 -msgid "Help" -msgstr "" - -#: tpl/submit.html:6 -msgid "Status" -msgstr "" - -#: tpl/submit.html:7 -msgid "Test Point" -msgstr "" - -#: tpl/submit.html:9 -msgid "User" -msgstr "" - -#: tpl/submit.html:10 -msgid "Score" -msgstr "" - -#: tpl/submit.html:11 -msgid "Time" -msgstr "" - -#: tpl/submit.html:12 -msgid "Memory" -msgstr "" - -#: tpl/backstage/problem_add.html:30 -msgid "Time Limit" -msgstr "" - -#: tpl/backstage/problem_add.html:39 -msgid "Memory Limit" -msgstr "" - -#: tpl/backstage/problem_add.html:60 -msgid "Input Sample" -msgstr "" - -#: tpl/backstage/problem_add.html:72 -msgid "Output Sample" -msgstr "" - -#: tpl/backstage/node_create.html:24 -msgid "Link" -msgstr "" - -#: tpl/backstage/node_create.html:30 -msgid "Description" -msgstr "" - -#: tpl/forget.html:11 -msgid "Username" -msgstr "" - -#: tpl/forget.html:12 tpl/settings.html:23 -msgid "Email" -msgstr "" - -#: tpl/settings.html:19 -msgid "Basic Settings" -msgstr "" - -#: tpl/settings.html:29 -msgid "Website" -msgstr "" - -#: tpl/settings.html:35 -msgid "Tagline" -msgstr "" - -#: tpl/settings.html:41 -msgid "Code Language" -msgstr "" - -#: tpl/settings.html:59 -msgid "Bio" -msgstr "" - -#: tpl/settings.html:65 -msgid "Save Changes" -msgstr "" - -#: tpl/settings.html:87 -msgid "Change Passowrd" -msgstr "" - -#: tpl/note.html:14 tpl/problem.html:31 -msgid "Edit" -msgstr "" - -#: tpl/note.html:14 -msgid "Delete" -msgstr "" - -#: tpl/member_note.html:9 -msgid "There are empty now. Add something here." -msgstr "" - -#: tpl/member_note.html:20 -msgid "More.." -msgstr "" - -#: tpl/topic.html:53 -msgid "No Reply Yet" -msgstr "" - -#: tpl/topic.html:71 -msgid "Add Reply" -msgstr "" - -#: tpl/reset.html:3 -msgid "You have reseted your password successfully." -msgstr "" - -#: tpl/reset.html:4 -msgid "Sign in Now" -msgstr "" - -#: tpl/reset.html:17 -msgid "Repeat Password" -msgstr "" - -#: tpl/problem.html:5 -msgid "Meta" -msgstr "" - -#: tpl/problem.html:38 -msgid "Related Notes" -msgstr "" - -#: tpl/problem.html:80 -msgid "Submit Problem" -msgstr "" - -#: tpl/problem.html:83 -msgid "Code File" -msgstr "" - -#: tpl/problem.html:89 -msgid "Language" -msgstr "" diff --git a/i18n/en_US/LC_MESSAGES/onlinejudge.mo b/i18n/en_US/LC_MESSAGES/onlinejudge.mo deleted file mode 100644 index 031e3e845e53c28e6ab503ba994b5ea80e8dd267..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 378 zcmYL^u};G<6h%QWWn^aXz*b&yI-p<*s%cD#u#+lHE5T-3Hv|>Ca$E!-!te1dyhw;% z>Bxi6v+w&kIsQJt93rR48FGZ2BV7_?gqK%%cFupM-o2S+fNTW|J}=;NHi@f7<;1w4neAeVPrt#0nh=&l*9?6mpz(LiXxQe zqv;<1^PU7RK^2g4@=!39^`47dL{hf_Dz9z3(ZP8}?&ngHoGU?wLh($Fc$$`CHoHaD z);nDrsEmGRMDlzx?m@Bzv!`wKg7vUAk3cYetfnCPW9nVk>5% diff --git a/i18n/zh_CN.po b/i18n/zh_CN.po deleted file mode 100644 index 497cb61..0000000 --- a/i18n/zh_CN.po +++ /dev/null @@ -1,495 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: 0.0.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-02-17 01:04+0800\n" -"PO-Revision-Date: 2012-02-17 01:04+0800\n" -"Last-Translator: Zeray Rice \n" -"Language-Team: Zeray Rice \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: backstage.py:28 tpl/header.html:98 -msgid "Backstage" -msgstr "后台" - -#: backstage.py:34 backstage.py:73 tpl/header.html:103 -#: tpl/backstage/index.html:3 tpl/backstage/problem_add.html:13 -msgid "Add Problem" -msgstr "添加题目" - -#: backstage.py:55 forum.py:75 tpl/node.html:45 tpl/note_create.html:18 -#: tpl/topic_create.html:18 tpl/home.html:35 tpl/problem_list.html:6 -#: tpl/backstage/problem_add.html:18 tpl/backstage/node_create.html:18 -msgid "Title" -msgstr "标题" - -#: backstage.py:56 tpl/home.html:36 tpl/problem_list.html:7 -#: tpl/backstage/problem_add.html:24 -msgid "Short Name" -msgstr "英文名" - -#: backstage.py:57 note.py:64 forum.py:76 tpl/node.html:51 -#: tpl/note_create.html:24 tpl/topic_create.html:24 -#: tpl/backstage/problem_add.html:48 tpl/problem.html:47 -msgid "Content" -msgstr "内容" - -#: backstage.py:58 tpl/backstage/problem_add.html:54 tpl/problem.html:53 -msgid "Input Format" -msgstr "输入格式" - -#: backstage.py:59 tpl/backstage/problem_add.html:66 tpl/problem.html:59 -msgid "Output Format" -msgstr "输出格式" - -#: backstage.py:60 tpl/problem.html:65 -msgid "Sample Input" -msgstr "样例输入" - -#: backstage.py:61 tpl/problem.html:71 -msgid "Sample Output" -msgstr "样例输出" - -#: backstage.py:86 backstage.py:109 tpl/header.html:109 -#: tpl/backstage/node_create.html:13 -msgid "Add Node" -msgstr "添加节点" - -#: backstage.py:91 backstage.py:111 -msgid "Edit Node" -msgstr "编辑节点" - -#: backstage.py:101 -msgid "Node Name" -msgstr "节点名称" - -#: backstage.py:102 -msgid "Node Description" -msgstr "节点描述" - -#: backstage.py:103 -msgid "Node Link" -msgstr "节点链接" - -#: note.py:26 note.py:42 note.py:71 note.py:116 problem.py:21 problem.py:35 -#: problem.py:45 member.py:151 member.py:214 member.py:276 home.py:14 -#: home.py:16 forum.py:18 forum.py:27 forum.py:50 forum.py:82 forum.py:111 -#: forum.py:133 tpl/header.html:44 -msgid "Home" -msgstr "首页" - -#: note.py:28 note.py:44 note.py:73 note.py:118 -msgid "Note" -msgstr "笔记" - -#: note.py:49 note.py:76 note.py:77 tpl/note_create.html:14 -msgid "Edit Note" -msgstr "编辑笔记" - -#: note.py:52 note.py:53 note.py:79 note.py:80 tpl/note_create.html:14 -#: tpl/member_note.html:4 -msgid "Write Note" -msgstr "写新笔记" - -#: note.py:63 -msgid "Note Title" -msgstr "笔记标题" - -#: note.py:121 -msgid "'s Note" -msgstr "的笔记" - -#: judge/base/__init__.py:42 -#, python-format -msgid "%s is too long." -msgstr "%s 太长了。" - -#: judge/base/__init__.py:45 -#, python-format -msgid "%s is Required!" -msgstr "请填写 %s" - -#: problem.py:22 problem.py:24 problem.py:36 tpl/header.html:50 -#: tpl/submit.html:8 -msgid "Problem" -msgstr "题目" - -#: problem.py:46 problem.py:47 tpl/node.html:57 tpl/note_create.html:48 -#: tpl/topic_create.html:31 tpl/header.html:62 -#: tpl/backstage/problem_add.html:78 tpl/backstage/node_create.html:38 -#: tpl/topic.html:80 tpl/problem.html:98 -msgid "Submit" -msgstr "提交" - -#: member.py:30 member.py:54 tpl/signup.html:47 tpl/header.html:117 -#: tpl/signin.html:40 -msgid "Sign In" -msgstr "登录" - -#: member.py:41 member.py:50 -msgid "Wrong Username and password combination." -msgstr "用户名密码错误。" - -#: member.py:52 member.py:299 -msgid "A username can only contain letters and digits." -msgstr "用户名只能由数字和字母组成。" - -#: member.py:73 member.py:119 tpl/signup.html:44 tpl/header.html:123 -#: tpl/signin.html:43 -msgid "Sign Up" -msgstr "注册" - -#: member.py:84 -msgid "A username should be between 3 and 15 characters long." -msgstr "用户名长度只能在3和15之间。" - -#: member.py:91 -msgid "That username is taken. Please choose another." -msgstr "用户名已被占用,请选择其他的。" - -#: member.py:95 member.py:301 -msgid "A username is required!" -msgstr "请填写用户名。" - -#: member.py:98 member.py:238 member.py:249 member.py:366 -msgid "A password should be between 6 and 32 characters long." -msgstr "密码长度只能在6和32之间。" - -#: member.py:102 -msgid "A password is required!" -msgstr "请填写密码。" - -#: member.py:105 member.py:166 -msgid "Email address cannot be longer than 100 characters long." -msgstr "Email地址不能超过100个字符。" - -#: member.py:115 member.py:176 member.py:309 -msgid "Your Email address is invalid." -msgstr "Email地址不合法。" - -#: member.py:117 member.py:178 member.py:311 -msgid "Email Address is required!" -msgstr "请填写Email地址。" - -#: member.py:145 member.py:153 member.py:212 member.py:216 tpl/header.html:87 -msgid "Settings" -msgstr "设置" - -#: member.py:181 -msgid "Tagline cannot be longer than 70 characters long." -msgstr "签名长度不能超过70个字符。" - -#: member.py:186 -msgid "Website address cannot be longer than 200 characters long." -msgstr "网站地址不能超过200个字符。" - -#: member.py:191 -msgid "Website address is invalid." -msgstr "网站地址不合法。" - -#: member.py:201 member.py:203 -msgid "Wrong Language select." -msgstr "错误的语言选择。" - -#: member.py:206 -msgid "Bio cannot be longer than 2000 characters long." -msgstr "自我介绍不能超过200个字符。" - -#: member.py:244 -msgid "Wrong password." -msgstr "错误的密码。" - -#: member.py:246 -msgid "Current password is required." -msgstr "请输入旧密码。" - -#: member.py:253 -msgid "New password is required." -msgstr "请输入更改的新密码。" - -#: member.py:255 tpl/settings_changepass.html:13 -#: tpl/settings_changepass.html:29 tpl/settings.html:71 -msgid "Change Password" -msgstr "修改密码" - -#: member.py:284 member.py:319 -msgid "Forget Password" -msgstr "忘记密码" - -#: member.py:297 -msgid "Sorry, We couldn't find you." -msgstr "对不起,这个用户名不存在。" - -#: member.py:307 -msgid "Wrong Username and Email combination." -msgstr "用户名或Email错误" - -#: member.py:317 -msgid "You can only request one reset mail in a day." -msgstr "你一天只能请求一封密码恢复邮件。" - -#: member.py:345 member.py:370 tpl/reset.html:14 -msgid "Reset Password" -msgstr "重设密码" - -#: member.py:363 -msgid "Two passwords do not match." -msgstr "两项密码不相同。" - -#: forum.py:16 forum.py:19 forum.py:28 forum.py:51 forum.py:83 forum.py:112 -#: forum.py:134 tpl/header.html:68 -msgid "Forum" -msgstr "讨论" - -#: forum.py:53 forum.py:54 forum.py:85 forum.py:86 tpl/topic_create.html:14 -msgid "Create Topic" -msgstr "创建新主题" - -#: forum.py:56 forum.py:88 tpl/topic_create.html:14 -msgid "Edit Topic" -msgstr "编辑主题" - -#: forum.py:126 -msgid "Reply" -msgstr "回复" - -#: tpl/node.html:5 tpl/node.html:41 -msgid "Create New Topic" -msgstr "创建新主题" - -#: tpl/node.html:33 tpl/forum.html:28 -msgid "oooops. There have no more topic." -msgstr "杯具了,这里没有更多的主题显示了。" - -#: tpl/node.html:33 -msgid "Create" -msgstr "创建" - -#: tpl/member.html:14 -msgid "ID:" -msgstr "ID:" - -#: tpl/member.html:14 -msgid "Joined at" -msgstr "加入于" - -#: tpl/member.html:26 -msgid "User Notes" -msgstr "笔记" - -#: tpl/note_create.html:30 tpl/note.html:5 -msgid "Related Problem" -msgstr "相关题目" - -#: tpl/note_create.html:33 -msgid "Add" -msgstr "增加" - -#: tpl/forum.html:35 -msgid "Nodes" -msgstr "节点" - -#: tpl/home.html:4 -msgid "Notice" -msgstr "公告" - -#: tpl/home.html:11 -msgid "Site Count" -msgstr "运行状态" - -#: tpl/home.html:14 -msgid "Total Problems" -msgstr "题目总数" - -#: tpl/home.html:18 -msgid "Total Nodes" -msgstr "节点总数" - -#: tpl/home.html:22 -msgid "Total Topics" -msgstr "主题总数" - -#: tpl/home.html:30 -msgid "Latest Problem" -msgstr "最新题目" - -#: tpl/home.html:53 -msgid "Latest Discuss" -msgstr "最新讨论" - -#: tpl/settings_changepass.html:17 tpl/settings.html:75 -msgid "Current Password" -msgstr "当前密码" - -#: tpl/settings_changepass.html:23 tpl/settings.html:81 tpl/reset.html:16 -msgid "New Password" -msgstr "新密码" - -#: tpl/header.html:56 -msgid "Contest" -msgstr "比赛" - -#: tpl/header.html:74 -msgid "List" -msgstr "列表" - -#: tpl/header.html:81 -msgid "Notes" -msgstr "笔记" - -#: tpl/header.html:93 -msgid "Sign Out" -msgstr "登出" - -#: tpl/header.html:130 -msgid "Help" -msgstr "帮助" - -#: tpl/submit.html:6 -msgid "Status" -msgstr "状态" - -#: tpl/submit.html:7 -msgid "Test Point" -msgstr "测试点" - -#: tpl/submit.html:9 -msgid "User" -msgstr "用户" - -#: tpl/submit.html:10 -msgid "Score" -msgstr "成绩" - -#: tpl/submit.html:11 -msgid "Time" -msgstr "耗时" - -#: tpl/submit.html:12 -msgid "Memory" -msgstr "内存" - -#: tpl/backstage/problem_add.html:30 -msgid "Time Limit" -msgstr "时间限制" - -#: tpl/backstage/problem_add.html:39 -msgid "Memory Limit" -msgstr "内存限制" - -#: tpl/backstage/problem_add.html:60 -msgid "Input Sample" -msgstr "样例输入" - -#: tpl/backstage/problem_add.html:72 -msgid "Output Sample" -msgstr "样例输出" - -#: tpl/backstage/node_create.html:24 -msgid "Link" -msgstr "链接" - -#: tpl/backstage/node_create.html:30 -msgid "Description" -msgstr "描述" - -#: tpl/forget.html:11 -msgid "Username" -msgstr "用户名" - -#: tpl/forget.html:12 tpl/settings.html:23 -msgid "Email" -msgstr "" - -#: tpl/settings.html:19 -msgid "Basic Settings" -msgstr "基本设置" - -#: tpl/settings.html:29 -msgid "Website" -msgstr "网站" - -#: tpl/settings.html:35 -msgid "Tagline" -msgstr "签名" - -#: tpl/settings.html:41 -msgid "Code Language" -msgstr "编程语言" - -#: tpl/settings.html:59 -msgid "Bio" -msgstr "自我介绍" - -#: tpl/settings.html:65 -msgid "Save Changes" -msgstr "保存设置" - -#: tpl/settings.html:87 -msgid "Change Passowrd" -msgstr "更改密码" - -#: tpl/note.html:14 tpl/problem.html:31 -msgid "Edit" -msgstr "编辑" - -#: tpl/note.html:14 -msgid "Delete" -msgstr "删除" - -#: tpl/member_note.html:9 -msgid "There are empty now. Add something here." -msgstr "这里什么还没有。 添加点什么吧。" - -#: tpl/member_note.html:20 -msgid "More.." -msgstr "更多.." - -#: tpl/topic.html:53 -msgid "No Reply Yet" -msgstr "还没有回复" - -#: tpl/topic.html:71 -msgid "Add Reply" -msgstr "回复" - -#: tpl/reset.html:3 -msgid "You have reseted your password successfully." -msgstr "修改密码成功。" - -#: tpl/reset.html:4 -msgid "Sign in Now" -msgstr "现在就登入。" - -#: tpl/reset.html:17 -msgid "Repeat Password" -msgstr "重复密码" - -#: tpl/problem.html:5 -msgid "Meta" -msgstr "信息" - -#: tpl/problem.html:38 -msgid "Related Notes" -msgstr "相关笔记" - -#: tpl/problem.html:80 -msgid "Submit Problem" -msgstr "提交题目" - -#: tpl/problem.html:83 -msgid "Code File" -msgstr "代码文件" - -#: tpl/problem.html:89 -msgid "Language" -msgstr "编程语言" diff --git a/i18n/zh_CN/LC_MESSAGES/onlinejudge.mo b/i18n/zh_CN/LC_MESSAGES/onlinejudge.mo deleted file mode 100644 index e984ca2dc07c71276219a4d9a90e2ae045ab0ff6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6466 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, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: 0.0.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-02-17 01:04+0800\n" -"PO-Revision-Date: 2012-02-17 01:04+0800\n" -"Last-Translator: Zeray Rice \n" -"Language-Team: Zeray Rice \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: backstage.py:28 tpl/header.html:98 -msgid "Backstage" -msgstr "後臺" - -#: backstage.py:34 backstage.py:73 tpl/header.html:103 -#: tpl/backstage/index.html:3 tpl/backstage/problem_add.html:13 -msgid "Add Problem" -msgstr "添加題目" - -#: backstage.py:55 forum.py:75 tpl/node.html:45 tpl/note_create.html:18 -#: tpl/topic_create.html:18 tpl/home.html:35 tpl/problem_list.html:6 -#: tpl/backstage/problem_add.html:18 tpl/backstage/node_create.html:18 -msgid "Title" -msgstr "標題" - -#: backstage.py:56 tpl/home.html:36 tpl/problem_list.html:7 -#: tpl/backstage/problem_add.html:24 -msgid "Short Name" -msgstr "英文名" - -#: backstage.py:57 note.py:64 forum.py:76 tpl/node.html:51 -#: tpl/note_create.html:24 tpl/topic_create.html:24 -#: tpl/backstage/problem_add.html:48 tpl/problem.html:47 -msgid "Content" -msgstr "內容" - -#: backstage.py:58 tpl/backstage/problem_add.html:54 tpl/problem.html:53 -msgid "Input Format" -msgstr "輸入格式" - -#: backstage.py:59 tpl/backstage/problem_add.html:66 tpl/problem.html:59 -msgid "Output Format" -msgstr "輸出格式" - -#: backstage.py:60 tpl/problem.html:65 -msgid "Sample Input" -msgstr "樣例輸入" - -#: backstage.py:61 tpl/problem.html:71 -msgid "Sample Output" -msgstr "樣例輸出" - -#: backstage.py:86 backstage.py:109 tpl/header.html:109 -#: tpl/backstage/node_create.html:13 -msgid "Add Node" -msgstr "添加節點" - -#: backstage.py:91 backstage.py:111 -msgid "Edit Node" -msgstr "編輯節點" - -#: backstage.py:101 -msgid "Node Name" -msgstr "節點名稱" - -#: backstage.py:102 -msgid "Node Description" -msgstr "節點描述" - -#: backstage.py:103 -msgid "Node Link" -msgstr "節點連結" - -#: note.py:26 note.py:42 note.py:71 note.py:116 problem.py:21 problem.py:35 -#: problem.py:45 member.py:151 member.py:214 member.py:276 home.py:14 -#: home.py:16 forum.py:18 forum.py:27 forum.py:50 forum.py:82 forum.py:111 -#: forum.py:133 tpl/header.html:44 -msgid "Home" -msgstr "首頁" - -#: note.py:28 note.py:44 note.py:73 note.py:118 -msgid "Note" -msgstr "筆記" - -#: note.py:49 note.py:76 note.py:77 tpl/note_create.html:14 -msgid "Edit Note" -msgstr "編輯筆記" - -#: note.py:52 note.py:53 note.py:79 note.py:80 tpl/note_create.html:14 -#: tpl/member_note.html:4 -msgid "Write Note" -msgstr "寫新筆記" - -#: note.py:63 -msgid "Note Title" -msgstr "筆記標題" - -#: note.py:121 -msgid "'s Note" -msgstr "的筆記" - -#: judge/base/__init__.py:42 -#, python-format -msgid "%s is too long." -msgstr "%s 太長了。" - -#: judge/base/__init__.py:45 -#, python-format -msgid "%s is Required!" -msgstr "請填寫 %s" - -#: problem.py:22 problem.py:24 problem.py:36 tpl/header.html:50 -#: tpl/submit.html:8 -msgid "Problem" -msgstr "題目" - -#: problem.py:46 problem.py:47 tpl/node.html:57 tpl/note_create.html:48 -#: tpl/topic_create.html:31 tpl/header.html:62 -#: tpl/backstage/problem_add.html:78 tpl/backstage/node_create.html:38 -#: tpl/topic.html:80 tpl/problem.html:98 -msgid "Submit" -msgstr "提交" - -#: member.py:30 member.py:54 tpl/signup.html:47 tpl/header.html:117 -#: tpl/signin.html:40 -msgid "Sign In" -msgstr "登入" - -#: member.py:41 member.py:50 -msgid "Wrong Username and password combination." -msgstr "使用者名密碼錯誤。" - -#: member.py:52 member.py:299 -msgid "A username can only contain letters and digits." -msgstr "使用者名只能由數字和字母組成。" - -#: member.py:73 member.py:119 tpl/signup.html:44 tpl/header.html:123 -#: tpl/signin.html:43 -msgid "Sign Up" -msgstr "註冊" - -#: member.py:84 -msgid "A username should be between 3 and 15 characters long." -msgstr "使用者名長度只能在3和15之間。" - -#: member.py:91 -msgid "That username is taken. Please choose another." -msgstr "使用者名已被佔用,請選擇其他的。" - -#: member.py:95 member.py:301 -msgid "A username is required!" -msgstr "請填寫使用者名。" - -#: member.py:98 member.py:238 member.py:249 member.py:366 -msgid "A password should be between 6 and 32 characters long." -msgstr "密碼長度只能在6和32之間。" - -#: member.py:102 -msgid "A password is required!" -msgstr "請填寫密碼。" - -#: member.py:105 member.py:166 -msgid "Email address cannot be longer than 100 characters long." -msgstr "Email地址不能超過100個字元。" - -#: member.py:115 member.py:176 member.py:309 -msgid "Your Email address is invalid." -msgstr "Email地址不合法。" - -#: member.py:117 member.py:178 member.py:311 -msgid "Email Address is required!" -msgstr "請填寫Email地址。" - -#: member.py:145 member.py:153 member.py:212 member.py:216 tpl/header.html:87 -msgid "Settings" -msgstr "設定" - -#: member.py:181 -msgid "Tagline cannot be longer than 70 characters long." -msgstr "簽名長度不能超過70個字元。" - -#: member.py:186 -msgid "Website address cannot be longer than 200 characters long." -msgstr "網站地址不能超過200個字元。" - -#: member.py:191 -msgid "Website address is invalid." -msgstr "網站地址不合法。" - -#: member.py:201 member.py:203 -msgid "Wrong Language select." -msgstr "錯誤的語言選擇。" - -#: member.py:206 -msgid "Bio cannot be longer than 2000 characters long." -msgstr "自我介紹不能超過200個字元。" - -#: member.py:244 -msgid "Wrong password." -msgstr "錯誤的密碼。" - -#: member.py:246 -msgid "Current password is required." -msgstr "請輸入舊密碼。" - -#: member.py:253 -msgid "New password is required." -msgstr "請輸入更改的新密碼。" - -#: member.py:255 tpl/settings_changepass.html:13 -#: tpl/settings_changepass.html:29 tpl/settings.html:71 -msgid "Change Password" -msgstr "修改密碼" - -#: member.py:284 member.py:319 -msgid "Forget Password" -msgstr "忘記密碼" - -#: member.py:297 -msgid "Sorry, We couldn't find you." -msgstr "對不起,這個使用者名不存在。" - -#: member.py:307 -msgid "Wrong Username and Email combination." -msgstr "使用者名或Email錯誤" - -#: member.py:317 -msgid "You can only request one reset mail in a day." -msgstr "你一天只能請求一封密碼恢復郵件。" - -#: member.py:345 member.py:370 tpl/reset.html:14 -msgid "Reset Password" -msgstr "重設密碼" - -#: member.py:363 -msgid "Two passwords do not match." -msgstr "兩項密碼不相同。" - -#: forum.py:16 forum.py:19 forum.py:28 forum.py:51 forum.py:83 forum.py:112 -#: forum.py:134 tpl/header.html:68 -msgid "Forum" -msgstr "討論" - -#: forum.py:53 forum.py:54 forum.py:85 forum.py:86 tpl/topic_create.html:14 -msgid "Create Topic" -msgstr "創建新主題" - -#: forum.py:56 forum.py:88 tpl/topic_create.html:14 -msgid "Edit Topic" -msgstr "編輯主題" - -#: forum.py:126 -msgid "Reply" -msgstr "回覆" - -#: tpl/node.html:5 tpl/node.html:41 -msgid "Create New Topic" -msgstr "創建新主題" - -#: tpl/node.html:33 tpl/forum.html:28 -msgid "oooops. There have no more topic." -msgstr "杯具了,這裏沒有更多的主題顯示了。" - -#: tpl/node.html:33 -msgid "Create" -msgstr "創建" - -#: tpl/member.html:14 -msgid "ID:" -msgstr "ID:" - -#: tpl/member.html:14 -msgid "Joined at" -msgstr "加入於" - -#: tpl/member.html:26 -msgid "User Notes" -msgstr "筆記" - -#: tpl/note_create.html:30 tpl/note.html:5 -msgid "Related Problem" -msgstr "相關題目" - -#: tpl/note_create.html:33 -msgid "Add" -msgstr "增加" - -#: tpl/forum.html:35 -msgid "Nodes" -msgstr "節點" - -#: tpl/home.html:4 -msgid "Notice" -msgstr "公告" - -#: tpl/home.html:11 -msgid "Site Count" -msgstr "運行狀態" - -#: tpl/home.html:14 -msgid "Total Problems" -msgstr "題目總數" - -#: tpl/home.html:18 -msgid "Total Nodes" -msgstr "節點總數" - -#: tpl/home.html:22 -msgid "Total Topics" -msgstr "主題總數" - -#: tpl/home.html:30 -msgid "Latest Problem" -msgstr "最新題目" - -#: tpl/home.html:53 -msgid "Latest Discuss" -msgstr "最新討論" - -#: tpl/settings_changepass.html:17 tpl/settings.html:75 -msgid "Current Password" -msgstr "當前密碼" - -#: tpl/settings_changepass.html:23 tpl/settings.html:81 tpl/reset.html:16 -msgid "New Password" -msgstr "新密碼" - -#: tpl/header.html:56 -msgid "Contest" -msgstr "比賽" - -#: tpl/header.html:74 -msgid "List" -msgstr "列表" - -#: tpl/header.html:81 -msgid "Notes" -msgstr "筆記" - -#: tpl/header.html:93 -msgid "Sign Out" -msgstr "登出" - -#: tpl/header.html:130 -msgid "Help" -msgstr "幫助" - -#: tpl/submit.html:6 -msgid "Status" -msgstr "狀態" - -#: tpl/submit.html:7 -msgid "Test Point" -msgstr "測試點" - -#: tpl/submit.html:9 -msgid "User" -msgstr "使用者" - -#: tpl/submit.html:10 -msgid "Score" -msgstr "成績" - -#: tpl/submit.html:11 -msgid "Time" -msgstr "耗時" - -#: tpl/submit.html:12 -msgid "Memory" -msgstr "內存" - -#: tpl/backstage/problem_add.html:30 -msgid "Time Limit" -msgstr "時間限制" - -#: tpl/backstage/problem_add.html:39 -msgid "Memory Limit" -msgstr "內存限制" - -#: tpl/backstage/problem_add.html:60 -msgid "Input Sample" -msgstr "樣例輸入" - -#: tpl/backstage/problem_add.html:72 -msgid "Output Sample" -msgstr "樣例輸出" - -#: tpl/backstage/node_create.html:24 -msgid "Link" -msgstr "連結" - -#: tpl/backstage/node_create.html:30 -msgid "Description" -msgstr "描述" - -#: tpl/forget.html:11 -msgid "Username" -msgstr "使用者名" - -#: tpl/forget.html:12 tpl/settings.html:23 -msgid "Email" -msgstr "" - -#: tpl/settings.html:19 -msgid "Basic Settings" -msgstr "基本設定" - -#: tpl/settings.html:29 -msgid "Website" -msgstr "網站" - -#: tpl/settings.html:35 -msgid "Tagline" -msgstr "簽名" - -#: tpl/settings.html:41 -msgid "Code Language" -msgstr "程式語言" - -#: tpl/settings.html:59 -msgid "Bio" -msgstr "自我介紹" - -#: tpl/settings.html:65 -msgid "Save Changes" -msgstr "儲存設定" - -#: tpl/settings.html:87 -msgid "Change Passowrd" -msgstr "更改密碼" - -#: tpl/note.html:14 tpl/problem.html:31 -msgid "Edit" -msgstr "編輯" - -#: tpl/note.html:14 -msgid "Delete" -msgstr "刪除" - -#: tpl/member_note.html:9 -msgid "There are empty now. Add something here." -msgstr "這裏什麼還沒有。 添加點什麼吧。" - -#: tpl/member_note.html:20 -msgid "More.." -msgstr "更多.." - -#: tpl/topic.html:53 -msgid "No Reply Yet" -msgstr "還沒有回覆" - -#: tpl/topic.html:71 -msgid "Add Reply" -msgstr "回覆" - -#: tpl/reset.html:3 -msgid "You have reseted your password successfully." -msgstr "修改密碼成功。" - -#: tpl/reset.html:4 -msgid "Sign in Now" -msgstr "現在就登入。" - -#: tpl/reset.html:17 -msgid "Repeat Password" -msgstr "重複密碼" - -#: tpl/problem.html:5 -msgid "Meta" -msgstr "資訊" - -#: tpl/problem.html:38 -msgid "Related Notes" -msgstr "相關筆記" - -#: tpl/problem.html:80 -msgid "Submit Problem" -msgstr "提交題目" - -#: tpl/problem.html:83 -msgid "Code File" -msgstr "程式碼檔案" - -#: tpl/problem.html:89 -msgid "Language" -msgstr "程式語言" diff --git a/i18n/zh_TW/LC_MESSAGES/onlinejudge.mo b/i18n/zh_TW/LC_MESSAGES/onlinejudge.mo deleted file mode 100644 index 3b58ff5d2300062164a3bf039707358fd4267e5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6496 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 E15pYzT>t<8 diff --git a/judge/__init__.py b/judge/__init__.py index 3266976..e69de29 100644 --- a/judge/__init__.py +++ b/judge/__init__.py @@ -1,664 +0,0 @@ -# -*- coding: utf-8 -*- - -import uuid -import binascii -from judge.utils import escape - -class BaseDBObject(object): - def __repr__(self): - result = ", \n".join(["'%s': '%s'" % (attr, getattr(self, attr)) for attr in dir(self) if attr[0] != '_' and not callable(getattr(self, attr)) ]) - return "<{%s}>" % result - def __getitem__(self, name): - return getattr(self, name) - def _init_row(self, row): - if row: - keys = row.keys() - for key in keys: - setattr(self, key, row[key]) - def e(self, name): - if self[name]: - return escape(self[name]) - return "" - -class Member(BaseDBObject): - id = 0 - username = "" - username_lower = "" - password = "" - email = "" - website = "" - tagline = "" - bio = "" - gravatar_link = "" - create = None - admin = 0 - lang = 1 - -class MemberDBMixin(object): - def _new_member_by_row(self, row): - member = Member() - member._init_row(row) - return member - def select_member_by_id(self, mid): - result = self.db.get("""SELECT * FROM `member` WHERE `id` = %s""", int(mid)) - if result: - return self._new_member_by_row(result) - return None - def select_member_by_username(self, username): - result = self.db.get("""SELECT * FROM `member` WHERE `username_lower` = %s LIMIT 1""", username.lower()) - if result: - return self._new_member_by_row(result) - return None - def select_member_by_usr_pwd(self, usr, pwd): - result = self.db.get("""SELECT * FROM `member` WHERE `username_lower` = %s AND `password` = %s LIMIT 1""", usr.lower(), pwd) - if result: - return self._new_member_by_row(result) - return None - def select_member_by_email(self, email): - result = self.db.get("""SELECT * FROM `member` WHERE `email` = %s LIMIT 1""", email.lower()) - if result: - return self._new_member_by_row(result) - return None - def insert_member(self, member): - member.username_lower = member.username.lower() - member.id = self.db.execute("""INSERT INTO `member` (`username`, `username_lower`, `password`, `email`, `gravatar_link`, `create`, `website`, `tagline`, `bio`, `admin`, `lang`) - VALUES (%s, %s, %s, %s, %s, UTC_TIMESTAMP(), %s, %s, %s, %s, %s)""", \ - member.username, member.username_lower, member.password, member.email, \ - member.gravatar_link, member.website, member.tagline, member.bio, \ - member.admin, member.lang) - def update_member(self, member): - self.db.execute("""UPDATE `member` - SET `password` = %s, - `email` = %s, - `gravatar_link` = %s, - `website` = %s, - `tagline` = %s, - `bio` = %s, - `admin` = %s, - `lang` = %s - WHERE `id` = %s""", member.password, member.email, member.gravatar_link, \ - member.website, member.tagline, member.bio, \ - member.admin, member.lang, member.id) - -class Auth(BaseDBObject): - member_id = 0 - secret = "" - create = None - -class AuthDBMixin(object): - def _new_auth_by_row(self, row): - if row: - auth = Auth() - auth._init_row(row) - return [auth] - return [] - def select_auth_by_uid(self, uid): - rows = self.db.query("""SELECT * FROM `auth` WHERE `member_id` = %s""", int(uid)) - result = [] - for row in rows: - result.extend(self._new_auth_by_row(row)) - return result - def select_auth_by_secret(self, secret): - result = self.db.get("""SELECT * FROM `auth` WHERE `secret` = %s LIMIT 1""", secret) - if result: - auth = Auth() - auth._init_row(result) - return auth - return None - def create_auth(self, uid): - random = binascii.b2a_hex(uuid.uuid4().bytes) - self.db.execute("""INSERT INTO `auth` (`member_id`, `secret`, `create`) VALUES (%s, %s, UTC_TIMESTAMP())""" \ - , int(uid), random) - auth = Auth() - auth.uid = uid - auth.secret = random - return auth - def delete_auth_by_uid(self, uid): - self.db.execute("""DELETE FROM `auth` WHERE `member_id` = %s""", int(uid)) - def delete_auth_by_secret(self, secret): - self.db.execute("""DELETE FROM `auth` WHERE `secret` = %s""", secret) - -class ResetMail(BaseDBObject): - member_id = 0 - secret = "" - create = None - -class ResetMailDBMixin(object): - def _new_reset_mail_by_row(self, row): - if row: - auth = Auth() - auth._init_row(row) - return [auth] - return [] - def select_reset_mail_by_uid(self, uid): - result = [] - rows = self.db.query("""SELECT * FROM `reset_mail` WHERE `member_id` = %s""", int(uid)) - for row in rows: - result.extend(self._new_reset_mail_by_row(row)) - return result - def select_reset_mail_last_by_uid(self, uid): - result = self.db.get("""SELECT * FROM `reset_mail` WHERE `member_id` = %s ORDER BY `create` DESC LIMIT 1""", int(uid)) - if result: - reset_mail = ResetMail() - reset_mail._init_row(result) - return reset_mail - return None - def select_reset_mail_by_secret(self, secret): - result = self.db.get("""SELECT * FROM `reset_mail` WHERE `secret` = %s LIMIT 1""", secret) - if result: - reset_mail = ResetMail() - reset_mail._init_row(result) - return reset_mail - return None - def create_reset_mail(self, uid): - random = binascii.b2a_hex(uuid.uuid4().bytes) - self.db.execute("""INSERT INTO `reset_mail` (`member_id`, `secret`, `create`) VALUES (%s, %s, UTC_TIMESTAMP())""" \ - , int(uid), random) - reset_mail = ResetMail() - reset_mail.member_id = uid - reset_mail.secret = random - return reset_mail - def delete_reset_mail_by_secret(self, secret): - self.db.execute("""DELETE FROM `reset_mail` WHERE `secret` = %s""", secret) - -class Problem(BaseDBObject): - id = 0 - title = "" - shortname = "" - content = "" - timelimit = 1000 - memlimit = 128 - testpoint = 0 - invisible = 0 - tags = "" - create = None - -class ProblemTag(BaseDBObject): - problem_id = 0 - tagname = "" - -class ProblemDBMixin(object): - def _new_problem_by_row(self, row): - if row: - problem = Problem() - problem._init_row(row) - return [problem] - return [] - def insert_problem_tag(self, tagname, problem_id): - self.db.execute("""INSERT INTO `problem_tag` (`tagname`, `problem_id`) VAlUES (%s, %s)""", tagname, int(problem_id)) - def insert_problem(self, problem): - problem.id = self.db.execute("""INSERT INTO `problem` (`title`, `shortname`, `content`, \ - `timelimit`, `memlimit`, `testpoint`, `invisible`, `create`) \ - VALUES (%s, %s, %s, %s, %s, %s, %s, UTC_TIMESTAMP())""" \ - , problem.title, problem.shortname, problem.content, \ - int(problem.timelimit), int(problem.memlimit), int(problem.testpoint), int(problem.invisible)) - def delete_problem_tag_by_problem_id(self, problem_id): - self.db.execute("""DELETE FROM `problem_tag` WHERE `problem_id` = %s""", int(problem_id)) - def update_problem(self, problem): - self.db.execute("""UPDATE `problem` SET `title` = %s, - `shortname` = %s, - `content` = %s, - `timelimit` = %s, - `memlimit` = %s, - `testpoint` = %s, - `invisible` = %s - WHERE `id` = %s""", \ - problem.title, problem.shortname, problem.content, \ - int(problem.timelimit), int(problem.memlimit), int(problem.testpoint), int(problem.invisible), \ - problem.id) - def count_problem(self): - count = self.db.get("""SELECT COUNT(*) FROM `problem`""") - return count["COUNT(*)"] - def count_visible_problem(self): - count = self.db.get("""SELECT COUNT(*) FROM `problem` WHERE `invisible` = 0""") - return count["COUNT(*)"] - def count_problem_by_tagname(self, tagname): - count = self.db.get("""SELECT COUNT(*) FROM `problem_tag` WHERE `tagname` = %s""", tagname) - return count["COUNT(*)"] - def count_visible_problem_by_tagname(self, tagname): - count = self.db.get("""SELECT COUNT(*), `problem`.* FROM `problem_tag` - LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` - WHERE `tagname` = %s AND `problem`.`invisible` = 0""", tagname) - return count["COUNT(*)"] - def select_problem_tag_by_pid(self, pid): - query = self.db.query("""SELECT * FROM `problem_tag` WHERE `problem_id` = %s""", pid) - result = [] - if query: - for row in query: - result.append(row['tagname']) - return result - def select_problem_by_id(self, pid): - query = self.db.get("""SELECT * FROM `problem` WHERE `id` = %s LIMIT 1""" , int(pid)) - if query: - problem = Problem() - problem._init_row(query) - return problem - return None - def select_problem_order_by_id(self, nums = 10, start = 0): - rows = self.db.query("""SELECT * FROM `problem` LIMIT %s, %s""", int(start), int(nums)) - result = [] - if rows: - for row in rows: - result.extend(self._new_problem_by_row(row)) - return result - def select_problem_order_by_id_visible(self, nums = 10, start = 0): - rows = self.db.query("""SELECT * FROM `problem` WHERE `invisible` = 0 LIMIT %s, %s""", int(start), int(nums)) - result = [] - if rows: - for row in rows: - result.extend(self._new_problem_by_row(row)) - return result - def select_problem_by_create(self, nums = 10): - rows = self.db.query("""SELECT * FROM `problem` ORDER BY `id` DESC LIMIT %s""", nums) - result = [] - if rows: - for row in rows: - result.extend(self._new_problem_by_row(row)) - return result - def select_problem_by_tagname(self, tagname, start = 0, nums = 10): - rows = self.db.query("""SELECT `problem_tag`.*, `problem`.* - FROM `problem_tag` - LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` - WHERE `tagname` = %s LIMIT %s, %s""", tagname, int(start), int(nums)) - result = [] - if rows: - for row in rows: - result.extend(self._new_problem_by_row(row)) - return result - def select_visible_problem_by_tagname(self, tagname, start = 0, nums = 10): - rows = self.db.query("""SELECT `problem_tag`.*, `problem`.* - FROM `problem_tag` - LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` - WHERE `tagname` = %s AND `problem`.`invisible` = 0 - LIMIT %s, %s""", tagname, int(start), int(nums)) - result = [] - if rows: - for row in rows: - result.extend(self._new_problem_by_row(row)) - return result - -class Note(BaseDBObject): - id = 0 - title = "" - content = "" - member_id = 0 - create = "" - -class NoteDBMixin(object): - def _new_problem_by_row(self, row): - if row: - note = Note() - note._init_row(row) - return [note] - return [] - def select_note_by_id(self, nid): - query = self.db.get("""SELECT * FROM `note` WHERE `id` = %s LIMIT 1""", int(nid)) - if query: - note = Note() - note._init_row(query) - return note - return None - def select_note_by_mid(self, mid, start = 0, count = 10): - query = self.db.query("""SELECT * FROM `note` WHERE `member_id` = %s ORDER BY `id` DESC LIMIT %s, %s""" \ - , int(mid), int(start), int(count)) - result = [] - if query: - for row in query: - result.extend(self._new_problem_by_row(row)) - return result - def insert_note(self, note): - note.id = self.db.execute("""INSERT INTO `note` (`title`, `content`, `member_id`, `create`) - VALUES (%s, %s, %s, UTC_TIMESTAMP())""" \ - , note.title, note.content, int(note.member_id)) - def update_note(self, note): - self.db.execute("""UPDATE `note` SET `title` = %s, - `content` = %s - WHERE `id` = %s""" \ - , note.title, note.content, note.id) - def delete_note_by_nid(self, nid): - self.db.execute("""DELETE FROM `note` WHERE `id` = %s""", int(nid)) - -class Node(BaseDBObject): - id = 0 - name = "" - description = "" - link = "" - -class NodeDBMixin(object): - def _new_topic_by_row(self, row): - if row: - node = Node() - node._init_row(row) - return [node] - return [] - def count_node(self): - count = self.db.get("""SELECT COUNT(*) FROM `node`""") - return count["COUNT(*)"] - def select_nodes(self, start = 0, num = 100): - rows = self.db.query("""SELECT * FROM `node` LIMIT %s, %s""", start, num) - result = [] - for row in rows: - result.extend(self._new_topic_by_row(row)) - return result - def select_node_by_link(self, link): - result = self.db.get("""SELECT * FROM `node` WHERE `link` = %s LIMIT 1""", link) - if result: - node = Node() - node._init_row(result) - return node - return None - def select_node_by_id(self, nid): - result = self.db.get("""SELECT * FROM `node` WHERE `id` = %s LIMIT 1""", nid) - node = None - if result: - node = Node() - node._init_row(result) - return node - return None - def update_node(self, node): - self.db.execute("""UPDATE `node` SET `name` = %s, \ - `description` = %s, \ - `link` = %s \ - WHERE `id` = %s""", \ - node.name, node.description, node.link, node.id) - def insert_node(self, node): - node.id = self.db.execute("""INSERT INTO `node` (`name`, `description`, `link`) \ - VALUES (%s, %s, %s)""", \ - node.name, node.description, node.link) - def delete_node(self, nid): - self.db.execute("""DELETE FROM `node` WHERE `id` = %s""", nid) - -class Topic(BaseDBObject): - id = 0 - title = "" - content = "" - node_id = 0 - member_id = 0 - create = None - last_reply = None - -class TopicDBMixin(object): - def _new_topic_by_row(self, row): - if row: - topic = Topic() - topic._init_row(row) - return [topic] - return [] - def count_topic(self): - count = self.db.get("""SELECT COUNT(*) FROM `topic`""") - return count["COUNT(*)"] - def select_topic_by_node(self, node, start = 0, num = 15): - rows = self.db.query("""SELECT `topic`. * , `member`.`username`, `member`.`gravatar_link` , `node`.`name` , `node`.`link` - FROM `topic` - LEFT JOIN `member` ON `topic`.`member_id` = `member`.`id` - LEFT JOIN `node` ON `topic`.`node_id` = `node`.`id` - WHERE `node_id` = %s - ORDER BY `create` DESC - LIMIT %s, %s""", node, start, num) - result = [] - for row in rows: - result.extend(self._new_topic_by_row(row)) - return result - def select_topic_by_id(self, topic_id): - result = self.db.get("""SELECT `topic`.*, `member`.`username`, `member`.`gravatar_link`, `member`.`tagline` - FROM `topic` - LEFT JOIN `member` ON `topic`.`member_id` = `member`.`id` - WHERE `topic`.`id` = %s - LIMIT 1""", topic_id) - topic = Topic() - if result: - topic._init_row(result) - return topic - return None - def select_topic_by_last_reply(self, start = 0, num = 20): - rows = self.db.query("""SELECT `topic`.*, `member`.`username`, `member`.`gravatar_link`, `node`.`name` - FROM `topic` - LEFT JOIN `member` ON `topic`.`member_id` = `member`.`id` - LEFT JOIN `node` ON `topic`.`node_id` = `node`.`id` - ORDER BY `topic`.`last_reply` DESC LIMIT %s, %s""", start, num) - result = [] - for row in rows: - result.extend(self._new_topic_by_row(row)) - return result - def update_topic(self, topic): - self.db.execute("""UPDATE `topic` SET `title` = %s, \ - `content` = %s, \ - WHERE `id` = %s""", \ - topic.title, topic.content, topic.id) - def update_topic_last_reply(self, tid): - self.db.execute("""UPDATE `topic` SET `last_reply` = UTC_TIMESTAMP() WHERE `id` = %s""", tid) - def insert_topic(self, topic): - topic.id = self.db.execute("""INSERT INTO `topic` (`title`, `content`, `node_id`, `member_id`, `create`, `last_reply`) \ - VALUES (%s, %s, %s, %s, UTC_TIMESTAMP(), UTC_TIMESTAMP())""", \ - topic.title, topic.content, topic.node_id, topic.member_id) - def delete_topic(self, tid): - self.db.execute("""DELETE FROM `topic` WHERE `id` = %s""", tid) - -class Reply(BaseDBObject): - id = "" - content = "" - member_id = "" - topic_id = "" - create = None - -class ReplyDBMixin(object): - def _new_reply_by_row(self, row): - if row: - reply = Reply() - reply._init_row(row) - return [reply] - return [] - def select_reply_by_topic_id(self, tid, start = 0, count = 100): - rows = self.db.query("""SELECT `reply`.*, `member`.`gravatar_link`, `member`.`username` - FROM `reply` - LEFT JOIN `member` ON `reply`.`member_id` = `member`.`id` - WHERE `reply`.`topic_id` = %s LIMIT %s,%s""", tid, start, count) - result = [] - for row in rows: - result.extend(self._new_reply_by_row(row)) - return result - def insert_reply(self, reply): - self.db.execute("""INSERT INTO `reply` (`content`, `member_id`, `topic_id`, `create`) - VALUES (%s, %s, %s, UTC_TIMESTAMP())""", reply.content, reply.member_id, reply.topic_id) - - -class RelatedProblem(BaseDBObject): - problem_id = 0 - note_id = 0 - -class RelatedProblemDBMixin(object): - def _new_related_problem_by_row(self, row): - if row: - related_problem = RelatedProblem() - related_problem._init_row(row) - return [related_problem] - return [] - def select_related_problem_by_pid(self, pid, start = 0, max = 5): - rows = self.db.query("""SELECT `related_problem`.*, `note`.`title`, `note`.`content`, `note`.`member_id`, `member`.`username` - FROM `related_problem` - LEFT JOIN `note` ON `related_problem`.`note_id` = `note`.`id` - LEFT JOIN `member` ON `note`.`member_id` = `member`.`id` - WHERE `problem_id` = %s LIMIT %s, %s""", pid, start, max) - result = [] - for row in rows: - result.extend(self._new_related_problem_by_row(row)) - return result - def select_related_problem_by_nid(self, nid, start = 0, max = 20): - rows = self.db.query("""SELECT `related_problem`.*, `problem`.`title` - FROM `related_problem` - LEFT JOIN `problem` ON `related_problem`.`problem_id` = `problem`.`id` - WHERE `note_id` = %s LIMIT %s, %s""", nid, start, max) - result = [] - for row in rows: - result.extend(self._new_related_problem_by_row(row)) - return result - def insert_related_problem(self, related_problem): - self.db.execute("""INSERT INTO `related_problem` (`problem_id`, `note_id`) VALUES (%s, %s)""", \ - related_problem.pid, related_problem.nid) - def delete_related_problem_by_nid(self, nid): - self.db.execute("""DELETE FROM `related_problem` WHERE `note_id` = %s""", nid) - def delete_related_problem_by_pid(self, pid): - self.db.execute("""DELETE FROM `related_problem` WHERE `problem_id` = %s""", pid) - -class Submit(BaseDBObject): - id = "" - problem_id = 0 - member_id = 0 - status = 0 # Pending = 0, Accepted = 1, Wrong Answer = 2, Time Limit Exceeded = 3, Memory Limit Exceeded = 4, Runtime Error = 5, Compile Error = 6 - testpoint = "" - score = 0 - costtime = 0 # ms - costmemory = 0 # kb - timestamp = None - lang = 0 # - user_agent = "" - ip = "" - create = None - -class SubmitDBMixin(object): - def _new_submit_by_row(self, row): - if row: - submit = Submit() - submit._init_row(row) - return [submit] - return [] - def select_submit_desc(self, start = 0, max = 20): - rows = self.db.query("""SELECT `submit`.*, `problem`.`title`, `member`.`username` - FROM `submit` - LEFT JOIN `member` ON `submit`.`member_id` = `member`.`id` - LEFT JOIN `problem` ON `submit`.`problem_id` = `problem`.`id` - ORDER BY `id` DESC LIMIT %s, %s""", start, max) - result = [] - if rows: - for row in rows: - result.extend(self._new_submit_by_row(row)) - return result - def select_submit_by_member_id_desc(self, mid, start = 0, max = 20): - rows = self.db.query("""SELECT * FROM `submit` WHERE `member_id` = %s ORDER BY `id` DESC LIMIT %s, %s""", mid, start, max) - result = [] - if rows: - for row in rows: - result.extend(self._new_submit_by_row(row)) - return result - def select_submit_by_problem_id_desc(self, pid, start = 0, max = 20): - rows = self.db.query("""SELECT * FROM `submit` WHERE `problem_id` = %s ORDER BY `id` DESC LIMIT %s, %s""", pid, start, max) - result = [] - if rows: - for row in rows: - result.extend(self._new_submit_by_row(row)) - return result - -class Contest(BaseDBObject): - id = "" - title = "" - description = "" - start_time = None - end_time = None - invisible = 0 # 0 - visible 1 - invisible - create = None - -class ContestProblem(BaseDBObject): - cid = 0 - pid = 0 - -class ContestSubmit(BaseDBObject): - id = "" - contest_id = 0 - problem_id = 0 - member_id = 0 - status = 0 # Pending = 0, Accepted = 1, Wrong Answer = 2, Time Limit Exceeded = 3, Memory Limit Exceeded = 4, Runtime Error = 5, Compile Error = 6 - testpoint = "" - score = 0 - costtime = 0 # ms - costmemory = 0 # kb - lang = 0 # - timestamp = None - msg = "" - user_agent = "" - ip = "" - create = None - -class ContestDBMixin(object): - def _new_contest_by_row(self, row): - if row: - contest = Contest() - contest._init_row(row) - return [contest] - return [] - def _new_contest_problem_by_row(self, row): - if row: - contest_problem = ContestProblem() - contest_problem._init_row(row) - return [contest_problem] - return [] - def _new_contest_submit_by_row(self, row): - if row: - contest_submit = ContestSubmit() - contest_submit._init_row(row) - return [contest_submit] - return [] - def insert_contest(self, contest): - contest.id = self.db.execute("""INSERT INTO `contest` (`title`, `description`, `start_time`, - `end_time`, `invisible`, `create`) - VALUES (%s, %s, %s, %s, %s, UTC_TIMESTAMP())""", \ - contest.title, contest.description, contest.start_time, contest.end_time, \ - contest.invisible) - def insert_contest_problem(self, cid, pid): - self.db.execute("""INSERT INTO `contest_problem` (`contest_id`, `problem_id`) VALUES (%s, %s)""", int(cid), int(pid)) - def update_contest(self, contest): - self.db.execute("""UPDATE `contest` SET `title` = %s, - `description` = %s, - `start_time` = %s, - `end_time` = %s, - `invisible` = %s - WHERE `id` = %s""" \ - , contest.title, contest.description, contest.start_time, contest.end_time, \ - contest.invisible, contest.id) - def delete_contest_problem_by_cid(self, cid): - self.db.execute("""DELETE FROM `contest_problem` WHERE `cid` = %s""", cid) - def select_contest(self, start = 0, max = 20): - rows = self.db.query("""SELECT * FROM `contest` LIMIT %s, %s""", start, max) - result = [] - if rows: - for row in rows: - result.extend(self._new_contest_by_row(row)) - return result - def select_contest_visible(self, start = 0, max = 20): - rows = self.db.query("""SELECT * FROM `contest` WHERE `invisible` = 0 LIMIT %s, %s""", start, max) - result = [] - if rows: - for row in rows: - result.extend(self._new_contest_by_row(row)) - return result - def select_contest_by_id(self, cid): - row = self.db.get("""SELECT * FROM `contest` WHERE `id` = %s""", cid) - if row: - contest = Contest() - contest._init_row(row) - return contest - return None - def select_contest_problem_by_cid(self, cid): - rows = self.db.query("""SELECT `contest_problem`.*, `problem`.`title` - FROM `contest_problem` - LEFT JOIN `problem` ON `contest_problem`.`problem_id` = `problem`.`id` - WHERE `contest_id` = %s""", cid) - result = [] - if rows: - for row in rows: - result.extend(self._new_contest_problem_by_row(row)) - return result - def select_contest_submit_by_cid_and_uid(self, cid, uid): - rows = self.db.query("""SELECT `contest_problem`.*, `problem`.`title`, `problem`.`shortname` - FROM `contest_problem` - LEFT JOIN `problem` ON `contest_problem`.`problem_id` = `problem`.`id` - WHERE `contest_id` = %s""", cid) - result = [] - if rows: - for row in rows: - contest_problem = self._new_contest_problem_by_row(row) - query = self.db.get("""SELECT * FROM `contest_submit` WHERE `member_id` = %s AND `problem_id` = %s ORDER BY `id` DESC LIMIT 1""", uid, contest_problem[0].pid) - contest_problem[0].submit = ContestSubmit() - contest_problem[0].submit._init_row(query) - result.extend(contest_problem) - return result - diff --git a/judge/base/__init__.py b/judge/base/__init__.py index cd6ac08..9d51e7f 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -1,143 +1,34 @@ -# -*- coding: utf-8 - -import smtplib -import hashlib -import httplib -import datetime -import traceback -import functools -from email.mime.text import MIMEText -from MySQLdb import escape_string -from werkzeug.contrib.securecookie import SecureCookie +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: judge/base/__init__.py +# CREATED: 01:49:33 08/03/2012 +# MODIFIED: 01:54:14 08/03/2012 +# DESCRIPTION: Base handler import tornado.web import tornado.escape -import tornado.locale -from tornado.web import HTTPError - -from judge import Member -from judge.utils import unicode_len - - -def unauthenticated(method): - """Decorate methods with this to require that user be NOT logged in""" - @functools.wraps(method) - def wrapper(self, *args, **kwargs): - if self.current_user: - if self.request.method in ("GET", "HEAD"): - self.redirect("/") - return - raise HTTPError(403) - return method(self, *args, **kwargs) - return wrapper class BaseHandler(tornado.web.RequestHandler): - _ = lambda self, text: self.locale.translate(text) - xhtml_escape = lambda self, text: tornado.escape.xhtml_escape(text) if text else text - def prepare(self): + _ = lambda self, text: self.locale.translate(text) # i18n func + xhtml_escape = lambda self, text: tornado.escape.xhtml_escape(text) if text else text # xhtml escape + def _check_text_value(self): + '''Check text value is vaild''' + pass + def get_page_num(self): + '''Return page num by input item num''' pass - def _check_text_value(self, text, title, required = False, max = 0): - error = [] - if text: - if max: - if unicode_len(text) > max: - error.append(self._('%s is too long.' % title)) - else: - if required: - error.append(self._('%s is Required!' % title)) - return error - def get_page_count(self, count): - return count / 10 + (1 if count % 10 else 0) def get_current_user(self): - auth = self.get_cookie('auth', default = None) - uid = self.get_cookie('uid', default = None) - user = None - if auth and uid: - auth = escape_string(auth) - uid = escape_string(uid) - sql = """SELECT * FROM `auth` WHERE `secret` = '%s' AND `member_id` = '%s' LIMIT 1""" \ - % (auth, uid) - auth = self.db.get(sql) - if auth: - sql = """SELECT * FROM `member` WHERE `id` = '%d' LIMIT 1""" \ - % (auth['member_id']) - user = Member() - query = self.db.get(sql) - if query: - user._init_row(query) - delta = auth['create'] - datetime.datetime.now() - if delta.days > 20: - """ Refresh Token """ - sql = """DELETE FROM `auth` WHERE `secret` = '%s' LIMIT 1""" \ - % auth - self.db.execute(sql) - random = binascii.b2a_hex(uuid.uuid4().bytes) - sql = """INSERT INTO `auth` (`uid`, `secret`, `create`) \ - VALUES ('%d', '%s', UTC_TIMESTAMP())""" \ - % (uid, random) - self.db.execute(sql) - self.set_cookie('auth', random) - self.set_cookie('uid', str(uid)) - else: - self.clear_cookie('auth') - self.clear_cookie('uid') - return user + '''Check user is logined''' + pass def get_user_locale(self): - result = self.get_cookie('OJ_LANG', default = None) - if result == None: - result = self.get_browser_locale() - else: - result = tornado.locale.get(result) - return result - def sendmail(self, to, subject, msg): - self.require_setting('default_mail', 'Send Mail') - self.require_setting('mail_server', 'Send Mail') - msg = MIMEText(msg) - msg['Subject'] = subject - msg['From'] = self.settings['default_mail'] - msg['To'] = to - s = smtplib.SMTP(self.settings['mail_server']) - s.sendmail(self.settings['default_mail'], [to], msg.as_string()) - s.quit() - @property - def db(self): - return self.application.db - @property - def jinja2(self): - return self.application.jinja2 - @property - def markdown(self): - return self.application.markdown - def get_gravatar_url(self, email): - gravatar_id = hashlib.md5(email.lower()).hexdigest() - return "http://www.gravatar.com/avatar/%s?d=mm" % (gravatar_id) - def render(self, tplname, args = {}): - if 'self' in args.keys(): - args.pop('self') - tpl = self.jinja2.get_template(tplname) - ren = tpl.render(page = self, _ = self.locale.translate, user = self.current_user, **args) - self.write(ren) - self.finish() - def set_secure_cookie_new(self, name, value, expires_days = 30, **kwargs): - self.require_setting('cookie_secret', 'secure cookie') - x = SecureCookie({name : value}, self.settings['cookie_secret']) - self.set_secure_cookie(name, x.serialize(), expires_days, **kwargs) - def get_secure_cookie_new(self, name, value = None, max_age_days = 31): - data = self.get_secure_cookie(name, value, max_age_days) - if not data: - return value - x = SecureCookie.unserialize(data, self.settings['cookie_secret']) - return x[name] - def write_error(self, status_code, **kwargs): - if status_code == 404: - self.render('404.html') - return - elif status_code == 500: - error = [] - for line in traceback.format_exception(*kwargs['exc_info']): - error.append(line) - error = "\n".join(error) - self.render('500.html', locals()) - return - msg = httplib.responses[status_code] - self.render('error.html', locals()) + '''Get user locale, first check cookie, then browser''' + pass + def sendmail(self): + '''Send mail func, send mail to someone''' + pass + def render(self): + '''Rewrite render func for use jinja2''' + pass + def write_error(self): + '''Rewrite write_error for custom error page''' + pass diff --git a/judge/filters/__init__.py b/judge/filters/__init__.py index 1364bd1..50811dd 100644 --- a/judge/filters/__init__.py +++ b/judge/filters/__init__.py @@ -1,170 +1,8 @@ -# -*- coding: utf-8 -*- - -import re -import string -import datetime -from jinja2 import evalcontextfilter, Markup, escape - -# Configuration for urlize() function -LEADING_PUNCTUATION = ['(', '<', '<'] -TRAILING_PUNCTUATION = ['.', ',', ')', '>', '\n', '>'] - -# list of possible strings used for bullets in bulleted lists -DOTS = ['·', '*', '\xe2\x80\xa2', '•', '•', '•'] - -unencoded_ampersands_re = re.compile(r'&(?!(\w+|#\d+);)') -word_split_re = re.compile(r'(\s+)') -punctuation_re = re.compile('^(?P(?:%s)*)(?P.*?)(?P(?:%s)*)$' % \ - ('|'.join([re.escape(x) for x in LEADING_PUNCTUATION]), - '|'.join([re.escape(x) for x in TRAILING_PUNCTUATION]))) -simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$') -link_target_attribute_re = re.compile(r'(]*?)target=[^\s>]+') -html_gunk_re = re.compile(r'(?:
|<\/i>|<\/b>|<\/em>|<\/strong>|<\/?smallcaps>|<\/?uppercase>)', re.IGNORECASE) -hard_coded_bullets_re = re.compile(r'((?:

(?:%s).*?[a-zA-Z].*?

\s*)+)' % '|'.join([re.escape(x) for x in DOTS]), re.DOTALL) -trailing_empty_content_re = re.compile(r'(?:

(?: |\s|
)*?

\s*)+\Z') -_paragraph_re = re.compile(r'(?:\r\n|\r|\n){1,}') -pre_re = re.compile(r"
(.*?)
", re.S) - -def submitstatus(value): - if value == 0: - cla = "pe" - status = "Pending" - elif value == 1: - cla = "ac" - status = "Accepted" - elif value == 2: - cla = "wa" - status = "Wrong Answer" - elif value == 3: - cla = "tle" - status = "Time Limit Exceeded" - elif value == 4: - cla = "mle" - status = "Memory Limit Exceeded" - elif value == 5: - cla = "re" - status = "Runtime Error" - elif value == 6: - cla = "ce" - status = "Compile Error" - else: - cla = "unknown" - status = "Unknown" - return "%s" % (cla, status) - -def autolink(text, trim_url_limit=None, nofollow=False): - """ - Converts any URLs in text into clickable links. Works on http://, https:// and - www. links. Links can have trailing punctuation (periods, commas, close-parens) - and leading punctuation (opening parens) and it'll still do the right thing. - - If trim_url_limit is not None, the URLs in link text will be limited to - trim_url_limit characters. - - If nofollow is True, the URLs in link text will get a rel="nofollow" attribute. - - Copy from https://github.com/livid/v2ex/blob/master/v2ex/templatetags/filters.py#L35 - """ - trim_url = lambda x, limit=trim_url_limit: limit is not None and (x[:limit] + (len(x) >=limit and '...' or '')) or x - words = word_split_re.split(text) - nofollow_attr = nofollow and ' rel="nofollow"' or '' - for i, word in enumerate(words): - match = punctuation_re.match(word) - if match: - lead, middle, trail = match.groups() - if middle.startswith('www.') or ('@' not in middle and not middle.startswith('http://') and \ - len(middle) > 0 and middle[0] in string.letters + string.digits and \ - (middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))): - middle = '
%s' % (middle, nofollow_attr, trim_url(middle)) - if middle.startswith('http://') or middle.startswith('https://'): - middle = '%s' % (middle, nofollow_attr, trim_url(middle)) - if '@' in middle and not middle.startswith('www.') and not ':' in middle \ - and simple_email_re.match(middle): - middle = '%s' % (middle, middle) - if lead + middle + trail != word: - words[i] = lead + middle + trail - return ''.join(words) - -def datetimeformat(value, format='%m/%d/%Y %H:%M'): - return value.strftime(format) - -def get_contest_status(contest): - if contest.invisible: - return "Invisible" - now = datetime.datetime.now() - if now >= contest.start_time and now <= contest.end_time: - return "Running" - if now <= contest.start_time: - return "Waiting" - if now >= contest.end_time: - return "Finished" - return "Unknown" - -def get_prev_page(start): - prev = get_now_page(start) - 10 - return prev if prev >= 0 else 0 - -def get_now_page(start): - start = int(start) - now = start / 10 * 10 - return now - -def get_next_page(start): - return get_now_page(start) + 10 - -def get_page_nav(pages, start): - now = start / 10 - dotdot = lambda a: "
  • ...
  • " - button = lambda page: "
  • %d
  • " % (page * 10, page + 1) - activebutton = lambda page: "
  • %d
  • " % (page * 10, page + 1) - result = [] - for i in range(pages if pages <= 4 else 4): - if i == now: - result.append(activebutton(i)) - else: - result.append(button(i)) - if now == 3 and pages > 4: - result.append(button(4)) - if now > 3: - if now > 4: - result.append(dotdot(1)) - result.append(button(now - 1)) - result.append(activebutton(now)) - if now + 1 < pages: - result.append(button(now + 1)) - if pages - 1 > 3 and now + 1 < pages - 1: - result.append(dotdot(1)) - result.append(button(pages - 1)) - return result - -def pre_to_code(text): - text = text.replace('<pre>', '
    ').replace('</pre>', '
    ') - handle_list = pre_re.findall(text) - result = [] - for p in handle_list: - text = text.replace(p, p.replace('
    ', '')) - return text - -def nl_to_br(text): - result = text.replace('\r\n', '
    \r\n') - return result - -@evalcontextfilter -def nl2br(eval_ctx, value): - result = u'\n\n'.join(u'

    %s

    ' % p.replace('\n', '
    \n') - for p in _paragraph_re.split(value)) - if eval_ctx.autoescape: - result = Markup(result) - return result - -filters = { - 'submitstatus' : submitstatus, - 'autolink' : autolink, - 'datetimeformat' : datetimeformat, - 'get_contest_status' : get_contest_status, - 'get_prev_page' : get_prev_page, - 'get_next_page' : get_next_page, - 'get_page_nav' : get_page_nav, - 'pre_to_code' : pre_to_code, - 'nl_to_br' : nl_to_br, -} +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: judge/filters/__init__.py +# CREATED: 01:48:10 08/03/2012 +# MODIFIED: 01:48:22 08/03/2012 +# DESCRIPTION: jinja2 filters + +filters = {} diff --git a/judge/utils/__init__.py b/judge/utils/__init__.py deleted file mode 100644 index 0f84ff3..0000000 --- a/judge/utils/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- - -from MySQLdb import escape_string - -def to_ascii(text): - if isinstance(text, unicode): - text = text.encode('utf-8') - return text - -def unicode_len(text): - if isinstance(text, str): - text = text.decode('utf-8') - return len(text) - -def escape(text): - if isinstance(text, unicode): - text = text.encode('utf-8') - if text: - return escape_string(text).decode('utf-8') - return None - diff --git a/lang.py b/lang.py deleted file mode 100644 index 61cac1a..0000000 --- a/lang.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- - -from tornado.web import HTTPError - -from config import accept_lang - -from judge.base import BaseHandler - -class SetLangeuageHandler(BaseHandler): - def get(self, lang): - if lang not in accept_lang.keys(): - raise HTTPError(404) - self.set_cookie('OJ_LANG', accept_lang[lang]) - if self.request.headers.has_key('Referer'): - self.redirect(self.request.headers['Referer']) - return - self.redirect('/') diff --git a/main.py b/main.py index d4f6d2e..5de66e9 100644 --- a/main.py +++ b/main.py @@ -1,16 +1,18 @@ -# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: main.py +# CREATED: 01:37:19 08/03/2012 +# MODIFIED: 01:47:54 08/03/2012 +# DESCRIPTION: Main Server File, run as `python2 main.py [port_num]` import re import sys import httplib -import markdown -import datetime from jinja2 import Environment, FileSystemLoader -httplib.responses[418] = "I'm a teapot" +httplib.responses[418] = "I'm a teapot" # hack for HTTP 418 :D import tornado.web -import tornado.locale import tornado.ioloop import tornado.options import tornado.database @@ -18,108 +20,25 @@ from tornado.options import define from tornado.options import options -from config import site_config -from config import mysql_config - -from judge import MemberDBMixin -from judge.base import BaseHandler -from judge.utils import escape from judge.filters import filters -from api import ProblemGetAPIHandler -from lang import SetLangeuageHandler -from home import HomeHandler -from note import NoteHandler -from note import CreateNoteHandler -from note import DeleteNoteHandler -from note import MemberNotesHandler -from forum import ForumIndexHandler -from forum import ForumNodeHandler -from forum import TopicCreateHandler -from forum import TopicHandler -from member import MemberHandler -from member import SigninHandler -from member import SignupHandler -from member import SignoutHandler -from member import SettingsHandler -from member import ResetPasswordHandler -from member import ChangePasswordHandler -from member import ForgetPasswordHandler -from problem import ProblemHandler -from problem import ProblemListHandler -from problem import SubmitListHandler -from problem import TagListHandler -from contest import ContestHandler -from contest import ContestListHandler -from backstage import BackstageHandler -from backstage import AddProblemHandler -from backstage import CreateNodeHandler -from backstage import CreateContestHandler +from config import site_config +from config import mysql_config +from handlers import handlers tornado.options.parse_command_line() +# Set MySQL define("mysql_host", default = mysql_config['mysql_host']) define("mysql_database", default = mysql_config['mysql_database']) define("mysql_user", default = mysql_config['mysql_user']) define("mysql_password", default = mysql_config['mysql_password']) -class TestHandler(BaseHandler, MemberDBMixin): - def get(self): - self.render('test.html', locals()) - -class NotFoundHandler(BaseHandler): - def get(self, url): - raise tornado.web.HTTPError(404) - -class ServerErrorHandler(BaseHandler): - def get(self): - raise tornado.web.HTTPError(500) - -class TeapotHandler(BaseHandler): - def get(self): - raise tornado.web.HTTPError(418) - class Application(tornado.web.Application): def __init__(self): - handlers = [ - (r'/', HomeHandler), - (r'/signin', SigninHandler), - (r'/signup', SignupHandler), - (r'/signout', SignoutHandler), - (r'/settings', SettingsHandler), - (r'/settings/changepass', ChangePasswordHandler), - (r'/forget', ForgetPasswordHandler), - (r'/reset/([\w\d]{32})', ResetPasswordHandler), - (r'/member/([\w\d]*)', MemberHandler), - (r'/member/([\w\d]*)/notes', MemberNotesHandler), - (r'/lang/(.*)', SetLangeuageHandler), - (r'/problem/([\d]*)', ProblemHandler), - (r'/problem', ProblemListHandler), - (r'/tag/(.*)', TagListHandler), - (r'/contest/([\d]*)', ContestHandler), - (r'/contest', ContestListHandler), - (r'/submit', SubmitListHandler), - (r'/note/create', CreateNoteHandler), - (r'/note/([\d]*)', NoteHandler), - (r'/note/([\d]*)/remove', DeleteNoteHandler), - (r'/forum', ForumIndexHandler), - (r'/forum/go/(.*)', ForumNodeHandler), - (r'/forum/new/(.*)', TopicCreateHandler), - (r'/forum/t/([\d]*)', TopicHandler), - (r'/api/problem/get/([\d]*)', ProblemGetAPIHandler), - (r'/backstage', BackstageHandler), - (r'/backstage/problem/add', AddProblemHandler), - (r'/backstage/node/create', CreateNodeHandler), - (r'/backstage/contest/create', CreateContestHandler), - (r'/test', TestHandler), - (r'/500', ServerErrorHandler), - (r'/418', TeapotHandler), - (r'/(.*)', NotFoundHandler), - ] tornado.web.Application.__init__(self, handlers, **site_config) - tornado.locale.set_default_locale('zh_CN') - tornado.locale.load_gettext_translations(self.settings['i18n_path'], "onlinejudge") - self.markdown = markdown.Markdown(['codehilite(force_linenos=True)', 'tables'], safe_mode=True) + tornado.locale.load_gettext_translations(self.settings['i18n_path'], "vulpix") + # Set Jinja2 jinja_env = Environment(loader = FileSystemLoader(self.settings['template_path'])) jinja_env.filters.update(filters) self.jinja2 = jinja_env diff --git a/member.py b/member.py deleted file mode 100644 index 6dfda2c..0000000 --- a/member.py +++ /dev/null @@ -1,380 +0,0 @@ -# -*- coding: utf-8 -*- - -import re -import uuid -import bcrypt -import binascii -import datetime -from MySQLdb import escape_string - -import tornado.web -import tornado.escape -import tornado.locale -from tornado.web import HTTPError -from tornado.web import authenticated - -from judge import Member -from judge import AuthDBMixin -from judge import NoteDBMixin -from judge import MemberDBMixin -from judge import ResetMailDBMixin -from judge.base import BaseHandler -from judge.base import unauthenticated -from judge.utils import escape -from judge.utils import to_ascii -from judge.utils import unicode_len - -class SigninHandler(BaseHandler, AuthDBMixin, MemberDBMixin): - @unauthenticated - def get(self): - title = self._("Sign In") - self.render("signin.html", locals()) - @unauthenticated - def post(self): - usr = self.get_argument("usr", default = None) - pwd = self.get_argument("pwd", default = None) - error = [] - if not usr and not pwd: - self.redirect("/signin") - return - if not usr or not pwd: - error.append(self._("Wrong Username and password combination.")) - else: - p = re.compile(r'^([\w\d]*)$') - if p.match(usr): - """ TODO: check username and password is valid. """ - pwd = to_ascii(pwd) - auth = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) - member = self.select_member_by_usr_pwd(usr, auth) - if not member: - error.append(self._("Wrong Username and password combination.")) - else: - error.append(self._("A username can only contain letters and digits.")) - if error: - title = self._("Sign In") - self.render("signin.html", locals()) - return - auth = self.create_auth(member.id) - if auth: - self.set_cookie('auth', auth.secret) - self.set_cookie('uid', str(auth.uid)) - go_next = self.get_argument('next', default = None) - if go_next: - self.redirect(go_next) - return - self.redirect('/') - else: - print "aa" - raise HTTPError(500) - -class SignupHandler(BaseHandler, MemberDBMixin, AuthDBMixin,): - @unauthenticated - def get(self): - title = self._("Sign Up") - self.render("signup.html", locals()) - @unauthenticated - def post(self): - self.require_setting('bcrypt_salt', 'bcrypt for Password') - usr = self.get_argument("usr", default = None) - pwd = self.get_argument("pwd", default = None) - email = self.get_argument("email", default = None) - error = [] - if usr: - if len(usr) < 3 or len(usr) > 20: - error.append(self._("A username should be between 3 and 15 characters long.")) - else: - p = re.compile(r'^([\w\d]*)$') - if p.match(usr): - """ TODO: check is username had been token. """ - member = self.select_member_by_username(usr) - if member: - error.append(self._("That username is taken. Please choose another.")) - else: - error.append("A username can only contain letters and digits.") - else: - error.append(self._("A username is required!")) - if pwd: - if unicode_len(pwd) < 6 or unicode_len(pwd) > 32: - error.append(self._("A password should be between 6 and 32 characters long.")) - else: - pwd = to_ascii(pwd) - else: - error.append(self._("A password is required!")) - if email: - if len(email) > 100: - error.append(self._("Email address cannot be longer than 100 characters long.")) - else: - p = re.compile(r"(?:^|\s)[-a-z0-9_.+]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}(?:\s|$)", re.IGNORECASE) - if p.match(email): - email = email.lower() - """ TODO: check is email had been token. """ - member = self.select_member_by_email(email) - if member: - error.append("That Email is taken. Please choose another.") - else: - error.append(self._("Your Email address is invalid.")) - else: - error.append(self._("Email Address is required!")) - if error: - title = self._("Sign Up") - self.render("signup.html", locals()) - return - member = Member() - member.password = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) - member.username = usr - member.email = email - member.gravatar_link = self.get_gravatar_url(email) - self.insert_member(member) - auth = self.create_auth(member.id) - self.set_cookie('auth', auth.secret) - self.set_cookie('uid', str(auth.uid)) - self.redirect('/') - -class SignoutHandler(BaseHandler, AuthDBMixin): - @authenticated - def get(self): - auth = self.get_cookie('auth') - self.delete_auth_by_secret(auth) - self.clear_cookie('auth') - self.clear_cookie('uid') - self.redirect('/') - -class SettingsHandler(BaseHandler, MemberDBMixin): - @authenticated - def get(self): - title = self._("Settings") - msg = self.get_secure_cookie("msg") - if msg: - msg = self._(msg) - self.clear_cookie("msg") - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self.current_user.username, '/member/%s' % self.current_user.username)) - breadcrumb.append((self._('Settings'), '/settings')) - self.render("settings.html", locals()) - @authenticated - def post(self): - email = self.get_argument("email", default = None) - website = self.get_argument("website", default = "") - tagline = self.get_argument("tagline", default = "") - lang = self.get_argument("lang", default = "") - bio = self.get_argument("bio", default = "") - error = [] - member = None - if email and email != self.current_user['email']: - if len(email) > 100: - error.append(self._("Email address cannot be longer than 100 characters long.")) - else: - p = re.compile(r"(?:^|\s)[-a-z0-9_.+]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}(?:\s|$)", re.IGNORECASE) - if p.match(email): - email = escape_string(email.lower()) - """ TODO: check is email had been token. """ - member = self.select_member_by_email(email) - if member: - error.append("That Email is taken. Please choose another.") - else: - error.append(self._("Your Email address is invalid.")) - elif email == None: - error.append(self._("Email Address is required!")) - if tagline: - if unicode_len(tagline) > 70: - error.append(self._("Tagline cannot be longer than 70 characters long.")) - else: - tagline = tornado.escape.xhtml_escape(tagline) - if website: - if unicode_len(website) > 200: - error.append(self._("Website address cannot be longer than 200 characters long.")); - p = re.compile('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+') - if (p.match(website)): - website = tornado.escape.xhtml_escape(website) - else: - error.append(self._("Website address is invalid.")) - if lang: - if lang in ['pas', 'c', 'cpp']: - if lang == 'pas': - lang = 1 - elif lang == 'c': - lang = 2 - elif lang == 'cpp': - lang = 3 - else: - error.append(self._("Wrong Language select.")) - else: - error.append(self._("Wrong Language select.")) - if bio: - if unicode_len(bio) > 2000: - error.append(self._("Bio cannot be longer than 2000 characters long.")) - else: - bio = tornado.escape.xhtml_escape(bio) - if error: - if member: - del member - title = self._("Settings") - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self.current_user.username, '/member/%s' % self.current_user.username)) - breadcrumb.append((self._('Settings'), '/settings')) - self.render("settings.html", locals()) - return - member = self.select_member_by_id(self.current_user['id']) - member.email = email - member.gravatar_link = self.get_gravatar_url(email) - member.website = website - member.tagline = tagline - member.bio = bio - member.lang = lang - self.update_member(member) - self.set_secure_cookie('msg', 'Settings Updated.') - self.redirect('/settings') - -class ChangePasswordHandler(BaseHandler, MemberDBMixin, AuthDBMixin): - @authenticated - def post(self): - oldpwd = self.get_argument('oldpwd', default = None) - newpwd = self.get_argument('newpwd', default = None) - error = [] - if oldpwd: - if unicode_len(oldpwd) < 6 or unicode_len(oldpwd) > 32: - error.append(self._("A password should be between 6 and 32 characters long.")) - else: - oldpwd = to_ascii(oldpwd) - auth = bcrypt.hashpw(oldpwd, self.settings['bcrypt_salt']) - users = self.select_member_by_usr_pwd(self.current_user['username_lower'], auth) - if not users: - error.append(self._("Wrong password.")) - else: - error.append(self._('Current password is required.')) - if newpwd: - if unicode_len(newpwd) < 6 or unicode_len(newpwd) > 32: - error.append(self._("A password should be between 6 and 32 characters long.")) - else: - newpwd = to_ascii(newpwd) - else: - error.append(self._("New password is required.")) - if error: - title = self._("Change Password") - self.render("settings_changepass.html", locals()) - return - member = self.select_member_by_id(self.current_user['id']) - member.password = bcrypt.hashpw(newpwd, self.settings['bcrypt_salt']) - self.update_member(member) - self.delete_auth_by_uid(member.id) - auth = self.create_auth(member.id) - self.set_cookie('auth', auth.secret) - self.set_cookie('uid', str(auth.uid)) - self.set_secure_cookie('msg', 'Password Updated.') - self.redirect('/settings') - -class MemberHandler(BaseHandler, MemberDBMixin, NoteDBMixin): - def get(self, username): - title = username - username = escape_string(username.lower()) - member = self.select_member_by_username(username) - if not member: - raise HTTPError(404) - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((member.username, '/member/%s' % member.username)) - notes = self.select_note_by_mid(member.id, count = 5) - self.render("member.html", locals()) - -class ForgetPasswordHandler(BaseHandler, MemberDBMixin, ResetMailDBMixin): - @unauthenticated - def get(self): - title = self._("Forget Password") - self.render("forget.html", locals()) - @unauthenticated - def post(self): - usr = self.get_argument('usr', default = None) - email = self.get_argument('email', default = None) - error = [] - users = "" - if usr: - p = re.compile(r'^([\w\d]*)$') - if p.match(usr): - users = self.select_member_by_username(usr) - if not users: - error.append(self._("Sorry, We couldn't find you.")) - else: - error.append(self._('A username can only contain letters and digits.')) - else: - error.append(self._('A username is required!')) - if email: - p = re.compile(r"(?:^|\s)[-a-z0-9_.+]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}(?:\s|$)", re.IGNORECASE) - if p.match(email): - email = escape_string(email.lower()) - if users and users['email'] != email: - error.append(self._("Wrong Username and Email combination.")) - else: - error.append(self._("Your Email address is invalid.")) - else: - error.append(self._('Email Address is required!')) - if users: - query = self.select_reset_mail_last_by_uid(users.id) - if query: - delta = datetime.datetime.now() - query['create'] - if delta.days < 1: - error.append(self._("You can only request one reset mail in a day.")) - if error: - title = self._("Forget Password") - self.render("forget.html", locals()) - return - reset = self.create_reset_mail(users.id) - msg = """Hello, %s - - Please use this link to change your password: - - http://%s/reset/%s - - Here are some information about the requester: - - UA: %s - IP: %s - -%s""" % (users['username'], self.settings['base_domain'], reset.secret, self.request.headers['User-Agent'], self.request.remote_ip, self.settings['site_title']) - self.sendmail(users['email'], "[%s] Reset Your Password" % (self.settings['site_title']), msg) - self.redirect('/') - -class ResetPasswordHandler(BaseHandler, MemberDBMixin, ResetMailDBMixin, AuthDBMixin): - @unauthenticated - def get(self, secret): - if len(secret) != 32: - raise HTTPError(404) - reset = self.select_reset_mail_by_secret(secret) - if reset: - title = self._('Reset Password') - reset_user = self.select_member_by_id(reset.uid) - self.render('reset.html', locals()) - else: - raise HTTPError(404) - @unauthenticated - def post(self, secret): - if len(secret) != 32: - raise HTTPError(404) - reset = self.select_reset_mail_by_secret(secret) - if reset: - newpwd = self.get_argument('newpwd', default = None) - repeatpwd = self.get_argument('repeatpwd', default = None) - error = [] - reset_user = self.select_member_by_id(reset.uid) - if not reset_user: - raise HTTPError(404) - if newpwd != repeatpwd: - error.append(_('Two passwords do not match.')) - else: - if unicode_len(newpwd) < 6 or unicode_len(newpwd) > 32: - error.append(self._("A password should be between 6 and 32 characters long.")) - else: - newpwd = to_ascii(newpwd) - if error: - title = self._("Reset Password") - self.render('reset.html', locals()) - return - reset_user.auth = bcrypt.hashpw(newpwd, self.settings['bcrypt_salt']) - self.update_member(reset_user) - self.delete_auth_by_uid(reset_user.id) - auth = self.create_auth(reset_user.id) - success = 1 - self.render('reset.html', locals()) - else: - raise HTTPError(404) diff --git a/note.py b/note.py deleted file mode 100644 index 20f73d5..0000000 --- a/note.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- - -from tornado.web import HTTPError -from tornado.web import authenticated - -from judge import Note -from judge import RelatedProblem -from judge import NoteDBMixin -from judge import MemberDBMixin -from judge import ProblemDBMixin -from judge import RelatedProblemDBMixin -from judge.base import BaseHandler -from judge.utils import escape - -class NoteHandler(BaseHandler, NoteDBMixin, MemberDBMixin, RelatedProblemDBMixin): - def get(self, nid): - try: - nid = int(nid) - except ValueError: - raise HTTPError(404) - note = self.select_note_by_id(nid) - if note: - title = note.title - member = self.select_member_by_id(note.member_id) - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((member.username, '/member/%s' % member.username)) - breadcrumb.append((self._('Note'), '/member/%s/notes' % member.username)) - breadcrumb.append((note.title, '/note/%d' % note.id)) - related_problem = self.select_related_problem_by_nid(note.id) - self.render("note.html", locals()) - else: - raise HTTPError(404) - -class CreateNoteHandler(BaseHandler, NoteDBMixin, ProblemDBMixin, RelatedProblemDBMixin): - @authenticated - def get(self): - nid = self.get_argument("nid", default = None) - note = None - related_js = True - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self.current_user.username, '/member/%s' % self.current_user.username)) - breadcrumb.append((self._('Note'), '/member/%s/notes' % self.current_user.username)) - if nid: - note = self.select_note_by_id(nid) - if note.member_id != self.current_user['id']: - raise HTTPError(403) - breadcrumb.append((self._('Edit Note'), '/note/create?nid=%s' % nid)) - related_problem = self.select_related_problem_by_nid(nid) - else: - breadcrumb.append((self._('Write Note'), '/note/create')) - title = self._("Write Note") - self.render("note_create.html", locals()) - @authenticated - def post(self): - notetitle = self.get_argument("notetitle", default = None) - content = self.get_argument("content", default = None) - nid = self.get_argument("nid", default = None) - link_problem = self.get_arguments("link_problem[]") - note = Note() - error = [] - error.extend(self._check_text_value(notetitle, self._("Note Title"), True, 100)) - error.extend(self._check_text_value(content, self._("Content"), True, 30000)) - note.title = self.xhtml_escape(notetitle) - note.content = self.xhtml_escape(content) - note.link_problem = [self.xhtml_escape(problem) for problem in link_problem] - note.id = int(nid) if nid else None - if error: - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self.current_user.username, '/member/%s' % self.current_user.username)) - breadcrumb.append((self._('Note'), '/member/%s/notes' % self.current_user.username)) - note_page = True - if note.id: - title = self._("Edit Note") - breadcrumb.append((self._('Edit Note'), '/note/create?nid=%s' % nid)) - else: - title = self._("Write Note") - breadcrumb.append((self._('Write Note'), '/note/create')) - related_problem = [] - for pid in note.link_problem: - related_problem.append(self.select_problem_by_id(pid)) - self.render("note_create.html", locals()) - return - note.member_id = self.current_user['id'] - if note.id: - self.update_note(note) - else: - self.insert_note(note) - for pid in note.link_problem: - related = RelatedProblem() - related.pid = pid - related.nid = note.id - self.insert_related_problem(related) - self.redirect("/note/%d" % note.id) - -class DeleteNoteHandler(BaseHandler, NoteDBMixin): - @authenticated - def get(self, nid): - try: - nid = int(nid) - except ValueError: - raise HTTPError(404) - note = self.select_note_by_id(nid) - if note.member_id != self.current_user["id"]: - raise HTTPError(403) - self.delete_note_by_nid(nid) - self.redirect("/member/%s/notes" % self.current_user["username"]) - -class MemberNotesHandler(BaseHandler, MemberDBMixin, NoteDBMixin): - def get(self, username): - member = self.select_member_by_username(username) - if member: - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((member.username, '/member/%s' % member.username)) - breadcrumb.append((self._('Note'), '/member/%s/notes' % member.username)) - start = self.get_argument("start", default = 0) - notes = self.select_note_by_mid(member.id, start = start) - title = member.username + self._("'s Note") - self.render("member_note.html", locals()) - else: - raise HTTPError(404) diff --git a/problem.py b/problem.py deleted file mode 100644 index 3090ce3..0000000 --- a/problem.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- - -from tornado.web import HTTPError - -from judge import Submit -from judge import Problem -from judge import SubmitDBMixin -from judge import ProblemDBMixin -from judge import RelatedProblemDBMixin -from judge.base import BaseHandler - -class TagListHandler(BaseHandler, ProblemDBMixin): - def get(self, tagname): - start = self.get_argument("start", default = 0) - try: - start = int(start) - except ValueError: - start = 0 - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Tags'), '#')) - breadcrumb.append((tagname, '/tag/%s' % tagname)) - title = u"%s › %s" % (self._("Tags"), tagname) - if self.current_user and self.current_user.admin: - count = self.count_problem_by_tagname(tagname) - problems = self.select_problem_by_tagname(tagname, start = start) - else: - count = self.count_visible_problem_by_tagname(tagname) - problems = self.select_visible_problem_by_tagname(tagname, start = start) - if not problems: - raise HTTPError(404) - pages = self.get_page_count(count) - self.render("problem_list.html", locals()) - - -class ProblemHandler(BaseHandler, ProblemDBMixin, RelatedProblemDBMixin): - def get(self, pid): - try: - pid = int(pid) - except ValueError: - raise HTTPError(404) - problem = self.select_problem_by_id(pid) - if problem: - if problem.invisible and (self.current_user == None or self.current_user.admin == 0): - raise HTTPError(404) - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Problem'), '/problem')) - breadcrumb.append((problem.title, '/problem/%d' % problem.id)) - title = self._("Problem") + u" › " + problem.title - related_note = self.select_related_problem_by_pid(problem.id) - tags = self.select_problem_tag_by_pid(problem.id) - self.render("problem.html", locals()) - else: - raise HTTPError(404) - -class ProblemListHandler(BaseHandler, ProblemDBMixin): - def get(self): - start = self.get_argument("start", default = 0) - try: - start = int(start) - except ValueError: - start = 0 - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Problem'), '/problem')) - title = self._("Problem") - if self.current_user and self.current_user.admin: - count = self.count_problem() - problems = self.select_problem_order_by_id(10, start) - else: - count = self.count_visible_problem() - problems = self.select_problem_order_by_id_visible(10, start) - pages = self.get_page_count(count) - self.render("problem_list.html", locals()) - -class SubmitListHandler(BaseHandler, SubmitDBMixin): - def get(self): - start = self.get_argument("start", default = 0) - submits = self.select_submit_desc(start = start) - breadcrumb = [] - breadcrumb.append((self._('Home'), '/')) - breadcrumb.append((self._('Submit'), '/submit')) - title = self._("Submit") - self.render("submit.html", locals()) diff --git a/scheme.sql b/scheme.sql deleted file mode 100644 index fda4eae..0000000 --- a/scheme.sql +++ /dev/null @@ -1,328 +0,0 @@ --- phpMyAdmin SQL Dump --- version 3.4.9 --- http://www.phpmyadmin.net --- --- ホスト: localhost --- 生成時間: 2012 年 3 月 08 日 01:12 --- サーバのバージョン: 5.5.21 --- PHP のバージョン: 5.3.10 - -SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - --- --- データベース: `vulpix` --- - --- -------------------------------------------------------- - --- --- テーブルの構造 `auth` --- - -CREATE TABLE IF NOT EXISTS `auth` ( - `member_id` int(11) NOT NULL, - `secret` varchar(100) NOT NULL, - `create` datetime NOT NULL, - KEY `member_id` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- テーブルの構造 `contest` --- - -CREATE TABLE IF NOT EXISTS `contest` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `title` text NOT NULL, - `description` mediumtext NOT NULL, - `start_time` datetime NOT NULL, - `end_time` datetime NOT NULL, - `invisible` int(11) NOT NULL, - `create` datetime NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; - --- -------------------------------------------------------- - --- --- テーブルの構造 `contest_problem` --- - -CREATE TABLE IF NOT EXISTS `contest_problem` ( - `contest_id` int(11) NOT NULL, - `problem_id` int(11) NOT NULL, - KEY `contest_id` (`contest_id`), - KEY `problem_id` (`problem_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- テーブルの構造 `contest_submit` --- - -CREATE TABLE IF NOT EXISTS `contest_submit` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `contest_id` int(11) NOT NULL, - `problem_id` int(11) NOT NULL, - `member_id` int(11) NOT NULL, - `status` int(11) NOT NULL, - `testpoint` text NOT NULL, - `score` int(11) NOT NULL, - `costtime` int(11) NOT NULL, - `costmemory` int(11) NOT NULL, - `lang` int(11) NOT NULL, - `timestamp` int(11) NOT NULL, - `msg` mediumtext NOT NULL, - `user_agent` text NOT NULL, - `ip` varchar(100) NOT NULL, - `create` datetime NOT NULL, - PRIMARY KEY (`id`), - KEY `contest_id` (`contest_id`), - KEY `problem_id` (`problem_id`), - KEY `member_id` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - --- --- テーブルの構造 `member` --- - -CREATE TABLE IF NOT EXISTS `member` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `username` varchar(200) NOT NULL, - `username_lower` varchar(200) NOT NULL, - `password` varchar(200) NOT NULL, - `email` text NOT NULL, - `website` text NOT NULL, - `tagline` text NOT NULL, - `bio` mediumtext NOT NULL, - `gravatar_link` text NOT NULL, - `create` datetime NOT NULL, - `admin` int(11) NOT NULL, - `lang` int(11) NOT NULL COMMENT 'pascal - 1, c - 2, cpp - 3', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; - --- -------------------------------------------------------- - --- --- テーブルの構造 `node` --- - -CREATE TABLE IF NOT EXISTS `node` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` text NOT NULL, - `description` text NOT NULL, - `link` varchar(100) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ; - --- -------------------------------------------------------- - --- --- テーブルの構造 `note` --- - -CREATE TABLE IF NOT EXISTS `note` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `title` text NOT NULL, - `content` mediumtext NOT NULL, - `member_id` int(11) NOT NULL, - `create` datetime NOT NULL, - PRIMARY KEY (`id`), - KEY `member_id` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ; - --- -------------------------------------------------------- - --- --- テーブルの構造 `problem` --- - -CREATE TABLE IF NOT EXISTS `problem` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `title` text NOT NULL, - `shortname` varchar(200) NOT NULL, - `content` mediumtext NOT NULL, - `timelimit` int(11) NOT NULL, - `memlimit` int(11) NOT NULL, - `testpoint` int(11) NOT NULL, - `invisible` int(11) NOT NULL, - `create` datetime NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ; - --- -------------------------------------------------------- - --- --- テーブルの構造 `problem_tag` --- - -CREATE TABLE IF NOT EXISTS `problem_tag` ( - `problem_id` int(11) NOT NULL, - `tagname` text NOT NULL, - KEY `problem_id` (`problem_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- テーブルの構造 `related_problem` --- - -CREATE TABLE IF NOT EXISTS `related_problem` ( - `problem_id` int(11) NOT NULL, - `note_id` int(11) NOT NULL, - KEY `problem_id` (`problem_id`), - KEY `note_id` (`note_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- テーブルの構造 `reply` --- - -CREATE TABLE IF NOT EXISTS `reply` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `content` mediumtext NOT NULL, - `member_id` int(11) NOT NULL, - `topic_id` int(11) NOT NULL, - `create` datetime NOT NULL, - PRIMARY KEY (`id`), - KEY `topic_id` (`topic_id`), - KEY `member_id` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ; - --- -------------------------------------------------------- - --- --- テーブルの構造 `reset_mail` --- - -CREATE TABLE IF NOT EXISTS `reset_mail` ( - `member_id` int(11) NOT NULL, - `secret` varchar(100) NOT NULL, - `create` datetime NOT NULL, - KEY `member_id` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- テーブルの構造 `submit` --- - -CREATE TABLE IF NOT EXISTS `submit` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `problem_id` int(11) NOT NULL, - `member_id` int(11) NOT NULL, - `status` int(11) NOT NULL, - `testpoint` text NOT NULL, - `score` int(11) NOT NULL, - `costtime` int(11) NOT NULL, - `costmemory` int(11) NOT NULL, - `timestamp` text NOT NULL, - `lang` int(11) NOT NULL, - `user_agent` text NOT NULL, - `ip` varchar(100) NOT NULL, - `create` datetime NOT NULL, - PRIMARY KEY (`id`), - KEY `problem_id` (`problem_id`), - KEY `member_id` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - --- --- テーブルの構造 `topic` --- - -CREATE TABLE IF NOT EXISTS `topic` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `title` text NOT NULL, - `content` mediumtext NOT NULL, - `node_id` int(11) NOT NULL, - `member_id` int(11) NOT NULL, - `create` datetime NOT NULL, - `last_reply` datetime NOT NULL, - PRIMARY KEY (`id`), - KEY `node_id` (`node_id`), - KEY `member_id` (`member_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; - --- --- ダンプしたテーブルの制約 --- - --- --- テーブルの制約 `auth` --- -ALTER TABLE `auth` - ADD CONSTRAINT `auth_ibfk_1` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`); - --- --- テーブルの制約 `contest_problem` --- -ALTER TABLE `contest_problem` - ADD CONSTRAINT `contest_problem_ibfk_1` FOREIGN KEY (`contest_id`) REFERENCES `contest` (`id`), - ADD CONSTRAINT `contest_problem_ibfk_2` FOREIGN KEY (`problem_id`) REFERENCES `problem` (`id`); - --- --- テーブルの制約 `contest_submit` --- -ALTER TABLE `contest_submit` - ADD CONSTRAINT `contest_submit_ibfk_1` FOREIGN KEY (`contest_id`) REFERENCES `contest` (`id`), - ADD CONSTRAINT `contest_submit_ibfk_2` FOREIGN KEY (`problem_id`) REFERENCES `problem` (`id`), - ADD CONSTRAINT `contest_submit_ibfk_3` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`); - --- --- テーブルの制約 `note` --- -ALTER TABLE `note` - ADD CONSTRAINT `note_ibfk_1` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`); - --- --- テーブルの制約 `problem_tag` --- -ALTER TABLE `problem_tag` - ADD CONSTRAINT `problem_tag_ibfk_1` FOREIGN KEY (`problem_id`) REFERENCES `problem` (`id`); - --- --- テーブルの制約 `related_problem` --- -ALTER TABLE `related_problem` - ADD CONSTRAINT `related_problem_ibfk_1` FOREIGN KEY (`problem_id`) REFERENCES `problem` (`id`), - ADD CONSTRAINT `related_problem_ibfk_2` FOREIGN KEY (`note_id`) REFERENCES `note` (`id`); - --- --- テーブルの制約 `reply` --- -ALTER TABLE `reply` - ADD CONSTRAINT `reply_ibfk_1` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`), - ADD CONSTRAINT `reply_ibfk_2` FOREIGN KEY (`topic_id`) REFERENCES `topic` (`id`); - --- --- テーブルの制約 `reset_mail` --- -ALTER TABLE `reset_mail` - ADD CONSTRAINT `reset_mail_ibfk_1` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`); - --- --- テーブルの制約 `submit` --- -ALTER TABLE `submit` - ADD CONSTRAINT `submit_ibfk_1` FOREIGN KEY (`problem_id`) REFERENCES `problem` (`id`), - ADD CONSTRAINT `submit_ibfk_2` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`); - --- --- テーブルの制約 `topic` --- -ALTER TABLE `topic` - ADD CONSTRAINT `topic_ibfk_1` FOREIGN KEY (`node_id`) REFERENCES `node` (`id`), - ADD CONSTRAINT `topic_ibfk_2` FOREIGN KEY (`member_id`) REFERENCES `member` (`id`); - diff --git a/static/css/bootstrap-responsive.min.css b/static/css/bootstrap-responsive.min.css deleted file mode 100644 index bc3f2ab..0000000 --- a/static/css/bootstrap-responsive.min.css +++ /dev/null @@ -1,3 +0,0 @@ - -.hidden{display:none;visibility:hidden;} -@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:18px;} input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} .input-prepend input[class*="span"],.input-append input[class*="span"]{width:auto;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .modal{position:absolute;top:10px;left:10px;right:10px;width:auto;margin:0;}.modal.fade.in{top:auto;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (max-width:768px){.container{width:auto;padding:0 20px;} .row-fluid{width:100%;} .row{margin-left:0;} .row>[class*="span"],.row-fluid>[class*="span"]{float:none;display:block;width:auto;margin:0;}}@media (min-width:768px) and (max-width:980px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:20px;} .span1{width:42px;} .span2{width:104px;} .span3{width:166px;} .span4{width:228px;} .span5{width:290px;} .span6{width:352px;} .span7{width:414px;} .span8{width:476px;} .span9{width:538px;} .span10{width:600px;} .span11{width:662px;} .span12,.container{width:724px;} .offset1{margin-left:82px;} .offset2{margin-left:144px;} .offset3{margin-left:206px;} .offset4{margin-left:268px;} .offset5{margin-left:330px;} .offset6{margin-left:392px;} .offset7{margin-left:454px;} .offset8{margin-left:516px;} .offset9{margin-left:578px;} .offset10{margin-left:640px;} .offset11{margin-left:702px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid>[class*="span"]{float:left;margin-left:2.762430939%;} .row-fluid>[class*="span"]:first-child{margin-left:0;} .row-fluid .span1{width:5.801104972%;} .row-fluid .span2{width:14.364640883%;} .row-fluid .span3{width:22.928176794%;} .row-fluid .span4{width:31.491712705%;} .row-fluid .span5{width:40.055248616%;} .row-fluid .span6{width:48.618784527%;} .row-fluid .span7{width:57.182320438000005%;} .row-fluid .span8{width:65.74585634900001%;} .row-fluid .span9{width:74.30939226%;} .row-fluid .span10{width:82.87292817100001%;} .row-fluid .span11{width:91.436464082%;} .row-fluid .span12{width:99.999999993%;} input.span1,textarea.span1,.uneditable-input.span1{width:32px;} input.span2,textarea.span2,.uneditable-input.span2{width:94px;} input.span3,textarea.span3,.uneditable-input.span3{width:156px;} input.span4,textarea.span4,.uneditable-input.span4{width:218px;} input.span5,textarea.span5,.uneditable-input.span5{width:280px;} input.span6,textarea.span6,.uneditable-input.span6{width:342px;} input.span7,textarea.span7,.uneditable-input.span7{width:404px;} input.span8,textarea.span8,.uneditable-input.span8{width:466px;} input.span9,textarea.span9,.uneditable-input.span9{width:528px;} input.span10,textarea.span10,.uneditable-input.span10{width:590px;} input.span11,textarea.span11,.uneditable-input.span11{width:652px;} input.span12,textarea.span12,.uneditable-input.span12{width:714px;}}@media (max-width:980px){body{padding-top:0;} .navbar-fixed-top{position:static;margin-bottom:18px;} .navbar-fixed-top .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .navbar .nav-collapse{clear:left;} .navbar .nav{float:none;margin:0 0 9px;} .navbar .nav>li{float:none;} .navbar .nav>li>a{margin-bottom:2px;} .navbar .nav>.divider-vertical{display:none;} .navbar .nav>li>a,.navbar .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .navbar .dropdown-menu li+li a{margin-bottom:2px;} .navbar .nav>li>a:hover,.navbar .dropdown-menu a:hover{background-color:#222222;} .navbar .dropdown-menu{position:static;top:auto;left:auto;float:none;display:block;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .navbar .dropdown-menu:before,.navbar .dropdown-menu:after{display:none;} .navbar .dropdown-menu .divider{display:none;} .navbar-form,.navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222222;border-bottom:1px solid #222222;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);} .navbar .nav.pull-right{float:none;margin-left:0;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;} .btn-navbar{display:block;} .nav-collapse{overflow:hidden;height:0;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";} .row:after{clear:both;} [class*="span"]{float:left;margin-left:30px;} .span1{width:70px;} .span2{width:170px;} .span3{width:270px;} .span4{width:370px;} .span5{width:470px;} .span6{width:570px;} .span7{width:670px;} .span8{width:770px;} .span9{width:870px;} .span10{width:970px;} .span11{width:1070px;} .span12,.container{width:1170px;} .offset1{margin-left:130px;} .offset2{margin-left:230px;} .offset3{margin-left:330px;} .offset4{margin-left:430px;} .offset5{margin-left:530px;} .offset6{margin-left:630px;} .offset7{margin-left:730px;} .offset8{margin-left:830px;} .offset9{margin-left:930px;} .offset10{margin-left:1030px;} .offset11{margin-left:1130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} .row-fluid:after{clear:both;} .row-fluid>[class*="span"]{float:left;margin-left:2.564102564%;} .row-fluid>[class*="span"]:first-child{margin-left:0;} .row-fluid .span1{width:5.982905983%;} .row-fluid .span2{width:14.529914530000001%;} .row-fluid .span3{width:23.076923077%;} .row-fluid .span4{width:31.623931624%;} .row-fluid .span5{width:40.170940171000005%;} .row-fluid .span6{width:48.717948718%;} .row-fluid .span7{width:57.264957265%;} .row-fluid .span8{width:65.81196581200001%;} .row-fluid .span9{width:74.358974359%;} .row-fluid .span10{width:82.905982906%;} .row-fluid .span11{width:91.45299145300001%;} .row-fluid .span12{width:100%;} input.span1,textarea.span1,.uneditable-input.span1{width:60px;} input.span2,textarea.span2,.uneditable-input.span2{width:160px;} input.span3,textarea.span3,.uneditable-input.span3{width:260px;} input.span4,textarea.span4,.uneditable-input.span4{width:360px;} input.span5,textarea.span5,.uneditable-input.span5{width:460px;} input.span6,textarea.span6,.uneditable-input.span6{width:560px;} input.span7,textarea.span7,.uneditable-input.span7{width:660px;} input.span8,textarea.span8,.uneditable-input.span8{width:760px;} input.span9,textarea.span9,.uneditable-input.span9{width:860px;} input.span10,textarea.span10,.uneditable-input.span10{width:960px;} input.span11,textarea.span11,.uneditable-input.span11{width:1060px;} input.span12,textarea.span12,.uneditable-input.span12{width:1160px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;}} diff --git a/static/css/bootstrap.min.css b/static/css/bootstrap.min.css deleted file mode 100644 index b01f92e..0000000 --- a/static/css/bootstrap.min.css +++ /dev/null @@ -1,610 +0,0 @@ -article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;} -audio,canvas,video{display:inline-block;*display:inline;*zoom:1;} -audio:not([controls]){display:none;} -html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;} -a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} -a:hover,a:active{outline:0;} -sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;} -sup{top:-0.5em;} -sub{bottom:-0.25em;} -img{max-width:100%;height:auto;border:0;-ms-interpolation-mode:bicubic;} -button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;} -button,input{*overflow:visible;line-height:normal;} -button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;} -button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;} -input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;} -input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;} -textarea{overflow:auto;vertical-align:top;} -body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333333;background-color:#ffffff;} -a{color:#0088cc;text-decoration:none;} -a:hover{color:#005580;text-decoration:underline;} -.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} -.row:after{clear:both;} -[class*="span"]{float:left;margin-left:20px;} -.span1{width:60px;} -.span2{width:140px;} -.span3{width:220px;} -.span4{width:300px;} -.span5{width:380px;} -.span6{width:460px;} -.span7{width:540px;} -.span8{width:620px;} -.span9{width:700px;} -.span10{width:780px;} -.span11{width:860px;} -.span12,.container{width:940px;} -.offset1{margin-left:100px;} -.offset2{margin-left:180px;} -.offset3{margin-left:260px;} -.offset4{margin-left:340px;} -.offset5{margin-left:420px;} -.offset6{margin-left:500px;} -.offset7{margin-left:580px;} -.offset8{margin-left:660px;} -.offset9{margin-left:740px;} -.offset10{margin-left:820px;} -.offset11{margin-left:900px;} -.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} -.row-fluid:after{clear:both;} -.row-fluid>[class*="span"]{float:left;margin-left:2.127659574%;} -.row-fluid>[class*="span"]:first-child{margin-left:0;} -.row-fluid .span1{width:6.382978723%;} -.row-fluid .span2{width:14.89361702%;} -.row-fluid .span3{width:23.404255317%;} -.row-fluid .span4{width:31.914893614%;} -.row-fluid .span5{width:40.425531911%;} -.row-fluid .span6{width:48.93617020799999%;} -.row-fluid .span7{width:57.446808505%;} -.row-fluid .span8{width:65.95744680199999%;} -.row-fluid .span9{width:74.468085099%;} -.row-fluid .span10{width:82.97872339599999%;} -.row-fluid .span11{width:91.489361693%;} -.row-fluid .span12{width:99.99999998999999%;} -.container{width:940px;margin-left:auto;margin-right:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";} -.container:after{clear:both;} -.container-fluid{padding-left:20px;padding-right:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";} -.container-fluid:after{clear:both;} -p{margin:0 0 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;}p small{font-size:11px;color:#999999;} -.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px;} -h1,h2,h3,h4,h5,h6{margin:0;font-weight:bold;color:#333333;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999999;} -h1{font-size:30px;line-height:36px;}h1 small{font-size:18px;} -h2{font-size:24px;line-height:36px;}h2 small{font-size:18px;} -h3{line-height:27px;font-size:18px;}h3 small{font-size:14px;} -h4,h5,h6{line-height:18px;} -h4{font-size:14px;}h4 small{font-size:12px;} -h5{font-size:12px;} -h6{font-size:11px;color:#999999;text-transform:uppercase;} -.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eeeeee;} -.page-header h1{line-height:1;} -ul,ol{padding:0;margin:0 0 9px 25px;} -ul ul,ul ol,ol ol,ol ul{margin-bottom:0;} -ul{list-style:disc;} -ol{list-style:decimal;} -li{line-height:18px;} -ul.unstyled{margin-left:0;list-style:none;} -dl{margin-bottom:18px;} -dt,dd{line-height:18px;} -dt{font-weight:bold;} -dd{margin-left:9px;} -hr{margin:18px 0;border:0;border-top:1px solid #e5e5e5;border-bottom:1px solid #ffffff;} -strong{font-weight:bold;} -em{font-style:italic;} -.muted{color:#999999;} -abbr{font-size:90%;text-transform:uppercase;border-bottom:1px dotted #ddd;cursor:help;} -blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px;} -blockquote small{display:block;line-height:18px;color:#999999;}blockquote small:before{content:'\2014 \00A0';} -blockquote.pull-right{float:right;padding-left:0;padding-right:15px;border-left:0;border-right:5px solid #eeeeee;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;} -q:before,q:after,blockquote:before,blockquote:after{content:"";} -address{display:block;margin-bottom:18px;line-height:18px;font-style:normal;} -small{font-size:100%;} -cite{font-style:normal;} -code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} -code{padding:3px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;} -pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12px;line-height:18px;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;white-space:pre;white-space:pre-wrap;word-break:break-all;}pre.prettyprint{margin-bottom:18px;} -pre code{padding:0;background-color:transparent;} -form{margin:0 0 18px;} -fieldset{padding:0;margin:0;border:0;} -legend{display:block;width:100%;padding:0;margin-bottom:27px;font-size:19.5px;line-height:36px;color:#333333;border:0;border-bottom:1px solid #eee;} -label,input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:18px;} -label{display:block;margin-bottom:5px;color:#333333;} -input,textarea,select,.uneditable-input{display:inline-block;width:210px;height:18px;padding:4px;margin-bottom:9px;font-size:13px;line-height:18px;color:#555555;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} -.uneditable-textarea{width:auto;height:auto;} -label input,label textarea,label select{display:block;} -input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;border:0;cursor:pointer;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} -input[type="file"]{padding:initial;line-height:initial;border:initial;background-color:#ffffff;background-color:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} -input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;} -select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px;} -select{width:220px;background-color:#ffffff;} -select[multiple],select[size]{height:auto;} -input[type="image"]{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} -textarea{height:auto;} -input[type="hidden"]{display:none;} -.radio,.checkbox{padding-left:18px;} -.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px;} -.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;} -.radio.inline,.checkbox.inline{display:inline-block;margin-bottom:0;vertical-align:middle;} -.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;} -.controls>.radio.inline:first-child,.controls>.checkbox.inline:first-child{padding-top:0;} -input,textarea{-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-ms-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s;} -input:focus,textarea:focus{border-color:rgba(82, 168, 236, 0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);outline:0;outline:thin dotted \9;} -input[type="file"]:focus,input[type="checkbox"]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} -.input-mini{width:60px;} -.input-small{width:90px;} -.input-medium{width:150px;} -.input-large{width:210px;} -.input-xlarge{width:270px;} -.input-xxlarge{width:530px;} -input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{float:none;margin-left:0;} -input.span1,textarea.span1,.uneditable-input.span1{width:50px;} -input.span2,textarea.span2,.uneditable-input.span2{width:130px;} -input.span3,textarea.span3,.uneditable-input.span3{width:210px;} -input.span4,textarea.span4,.uneditable-input.span4{width:290px;} -input.span5,textarea.span5,.uneditable-input.span5{width:370px;} -input.span6,textarea.span6,.uneditable-input.span6{width:450px;} -input.span7,textarea.span7,.uneditable-input.span7{width:530px;} -input.span8,textarea.span8,.uneditable-input.span8{width:610px;} -input.span9,textarea.span9,.uneditable-input.span9{width:690px;} -input.span10,textarea.span10,.uneditable-input.span10{width:770px;} -input.span11,textarea.span11,.uneditable-input.span11{width:850px;} -input.span12,textarea.span12,.uneditable-input.span12{width:930px;} -input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{background-color:#f5f5f5;border-color:#ddd;cursor:not-allowed;} -.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;} -.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853;}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:0 0 6px #dbc59e;-moz-box-shadow:0 0 6px #dbc59e;box-shadow:0 0 6px #dbc59e;} -.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} -.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} -.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48;}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:0 0 6px #d59392;-moz-box-shadow:0 0 6px #d59392;box-shadow:0 0 6px #d59392;} -.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} -.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} -.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847;}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:0 0 6px #7aba7b;-moz-box-shadow:0 0 6px #7aba7b;box-shadow:0 0 6px #7aba7b;} -.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} -input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} -.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#f5f5f5;border-top:1px solid #ddd;} -.uneditable-input{display:block;background-color:#ffffff;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;} -:-moz-placeholder{color:#999999;} -::-webkit-input-placeholder{color:#999999;} -.help-block{margin-top:5px;margin-bottom:0;color:#999999;} -.help-inline{display:inline-block;*display:inline;*zoom:1;margin-bottom:9px;vertical-align:middle;padding-left:5px;} -.input-prepend,.input-append{margin-bottom:5px;*zoom:1;}.input-prepend:before,.input-append:before,.input-prepend:after,.input-append:after{display:table;content:"";} -.input-prepend:after,.input-append:after{clear:both;} -.input-prepend input,.input-append input,.input-prepend .uneditable-input,.input-append .uneditable-input{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}.input-prepend input:focus,.input-append input:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus{position:relative;z-index:2;} -.input-prepend .uneditable-input,.input-append .uneditable-input{border-left-color:#ccc;} -.input-prepend .add-on,.input-append .add-on{float:left;display:block;width:auto;min-width:16px;height:18px;margin-right:-1px;padding:4px 5px;font-weight:normal;line-height:18px;color:#999999;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#f5f5f5;border:1px solid #ccc;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} -.input-prepend .active,.input-append .active{background-color:#a9dba9;border-color:#46a546;} -.input-prepend .add-on{*margin-top:1px;} -.input-append input,.input-append .uneditable-input{float:left;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} -.input-append .uneditable-input{border-right-color:#ccc;} -.input-append .add-on{margin-right:0;margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} -.input-append input:first-child{*margin-left:-160px;}.input-append input:first-child+.add-on{*margin-left:-21px;} -.search-query{padding-left:14px;padding-right:14px;margin-bottom:0;-webkit-border-radius:14px;-moz-border-radius:14px;border-radius:14px;} -.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input{display:inline-block;margin-bottom:0;} -.form-search label,.form-inline label,.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{display:inline-block;} -.form-search .input-append .add-on,.form-inline .input-prepend .add-on,.form-search .input-append .add-on,.form-inline .input-prepend .add-on{vertical-align:middle;} -.control-group{margin-bottom:9px;} -.form-horizontal legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate;} -.form-horizontal .control-group{margin-bottom:18px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";} -.form-horizontal .control-group:after{clear:both;} -.form-horizontal .control-group>label{float:left;width:140px;padding-top:5px;text-align:right;} -.form-horizontal .controls{margin-left:160px;} -.form-horizontal .form-actions{padding-left:160px;} -table{max-width:100%;border-collapse:collapse;border-spacing:0;} -.table{width:100%;margin-bottom:18px;}.table th,.table td{padding:8px;line-height:18px;text-align:left;border-top:1px solid #ddd;} -.table th{font-weight:bold;vertical-align:bottom;} -.table td{vertical-align:top;} -.table thead:first-child tr th,.table thead:first-child tr td{border-top:0;} -.table tbody+tbody{border-top:2px solid #ddd;} -.table-condensed th,.table-condensed td{padding:4px 5px;} -.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapsed;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th+th,.table-bordered td+td,.table-bordered th+td,.table-bordered td+th{border-left:1px solid #ddd;} -.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;} -.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-radius:4px 0 0 0;-moz-border-radius:4px 0 0 0;border-radius:4px 0 0 0;} -.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-radius:0 4px 0 0;-moz-border-radius:0 4px 0 0;border-radius:0 4px 0 0;} -.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;} -.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-radius:0 0 4px 0;-moz-border-radius:0 0 4px 0;border-radius:0 0 4px 0;} -.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;} -table .span1{float:none;width:44px;margin-left:0;} -table .span2{float:none;width:124px;margin-left:0;} -table .span3{float:none;width:204px;margin-left:0;} -table .span4{float:none;width:284px;margin-left:0;} -table .span5{float:none;width:364px;margin-left:0;} -table .span6{float:none;width:444px;margin-left:0;} -table .span7{float:none;width:524px;margin-left:0;} -table .span8{float:none;width:604px;margin-left:0;} -table .span9{float:none;width:684px;margin-left:0;} -table .span10{float:none;width:764px;margin-left:0;} -table .span11{float:none;width:844px;margin-left:0;} -table .span12{float:none;width:924px;margin-left:0;} -[class^="icon-"]{display:inline-block;width:14px;height:14px;vertical-align:text-top;background-image:url(../img/glyphicons-halflings.png);background-position:14px 14px;background-repeat:no-repeat;*margin-right:.3em;}[class^="icon-"]:last-child{*margin-left:0;} -.icon-white{background-image:url(../img/glyphicons-halflings-white.png);} -.icon-glass{background-position:0 0;} -.icon-music{background-position:-24px 0;} -.icon-search{background-position:-48px 0;} -.icon-envelope{background-position:-72px 0;} -.icon-heart{background-position:-96px 0;} -.icon-star{background-position:-120px 0;} -.icon-star-empty{background-position:-144px 0;} -.icon-user{background-position:-168px 0;} -.icon-film{background-position:-192px 0;} -.icon-th-large{background-position:-216px 0;} -.icon-th{background-position:-240px 0;} -.icon-th-list{background-position:-264px 0;} -.icon-ok{background-position:-288px 0;} -.icon-remove{background-position:-312px 0;} -.icon-zoom-in{background-position:-336px 0;} -.icon-zoom-out{background-position:-360px 0;} -.icon-off{background-position:-384px 0;} -.icon-signal{background-position:-408px 0;} -.icon-cog{background-position:-432px 0;} -.icon-trash{background-position:-456px 0;} -.icon-home{background-position:0 -24px;} -.icon-file{background-position:-24px -24px;} -.icon-time{background-position:-48px -24px;} -.icon-road{background-position:-72px -24px;} -.icon-download-alt{background-position:-96px -24px;} -.icon-download{background-position:-120px -24px;} -.icon-upload{background-position:-144px -24px;} -.icon-inbox{background-position:-168px -24px;} -.icon-play-circle{background-position:-192px -24px;} -.icon-repeat{background-position:-216px -24px;} -.icon-refresh{background-position:-240px -24px;} -.icon-list-alt{background-position:-264px -24px;} -.icon-lock{background-position:-287px -24px;} -.icon-flag{background-position:-312px -24px;} -.icon-headphones{background-position:-336px -24px;} -.icon-volume-off{background-position:-360px -24px;} -.icon-volume-down{background-position:-384px -24px;} -.icon-volume-up{background-position:-408px -24px;} -.icon-qrcode{background-position:-432px -24px;} -.icon-barcode{background-position:-456px -24px;} -.icon-tag{background-position:0 -48px;} -.icon-tags{background-position:-25px -48px;} -.icon-book{background-position:-48px -48px;} -.icon-bookmark{background-position:-72px -48px;} -.icon-print{background-position:-96px -48px;} -.icon-camera{background-position:-120px -48px;} -.icon-font{background-position:-144px -48px;} -.icon-bold{background-position:-167px -48px;} -.icon-italic{background-position:-192px -48px;} -.icon-text-height{background-position:-216px -48px;} -.icon-text-width{background-position:-240px -48px;} -.icon-align-left{background-position:-264px -48px;} -.icon-align-center{background-position:-288px -48px;} -.icon-align-right{background-position:-312px -48px;} -.icon-align-justify{background-position:-336px -48px;} -.icon-list{background-position:-360px -48px;} -.icon-indent-left{background-position:-384px -48px;} -.icon-indent-right{background-position:-408px -48px;} -.icon-facetime-video{background-position:-432px -48px;} -.icon-picture{background-position:-456px -48px;} -.icon-pencil{background-position:0 -72px;} -.icon-map-marker{background-position:-24px -72px;} -.icon-adjust{background-position:-48px -72px;} -.icon-tint{background-position:-72px -72px;} -.icon-edit{background-position:-96px -72px;} -.icon-share{background-position:-120px -72px;} -.icon-check{background-position:-144px -72px;} -.icon-move{background-position:-168px -72px;} -.icon-step-backward{background-position:-192px -72px;} -.icon-fast-backward{background-position:-216px -72px;} -.icon-backward{background-position:-240px -72px;} -.icon-play{background-position:-264px -72px;} -.icon-pause{background-position:-288px -72px;} -.icon-stop{background-position:-312px -72px;} -.icon-forward{background-position:-336px -72px;} -.icon-fast-forward{background-position:-360px -72px;} -.icon-step-forward{background-position:-384px -72px;} -.icon-eject{background-position:-408px -72px;} -.icon-chevron-left{background-position:-432px -72px;} -.icon-chevron-right{background-position:-456px -72px;} -.icon-plus-sign{background-position:0 -96px;} -.icon-minus-sign{background-position:-24px -96px;} -.icon-remove-sign{background-position:-48px -96px;} -.icon-ok-sign{background-position:-72px -96px;} -.icon-question-sign{background-position:-96px -96px;} -.icon-info-sign{background-position:-120px -96px;} -.icon-screenshot{background-position:-144px -96px;} -.icon-remove-circle{background-position:-168px -96px;} -.icon-ok-circle{background-position:-192px -96px;} -.icon-ban-circle{background-position:-216px -96px;} -.icon-arrow-left{background-position:-240px -96px;} -.icon-arrow-right{background-position:-264px -96px;} -.icon-arrow-up{background-position:-289px -96px;} -.icon-arrow-down{background-position:-312px -96px;} -.icon-share-alt{background-position:-336px -96px;} -.icon-resize-full{background-position:-360px -96px;} -.icon-resize-small{background-position:-384px -96px;} -.icon-plus{background-position:-408px -96px;} -.icon-minus{background-position:-433px -96px;} -.icon-asterisk{background-position:-456px -96px;} -.icon-exclamation-sign{background-position:0 -120px;} -.icon-gift{background-position:-24px -120px;} -.icon-leaf{background-position:-48px -120px;} -.icon-fire{background-position:-72px -120px;} -.icon-eye-open{background-position:-96px -120px;} -.icon-eye-close{background-position:-120px -120px;} -.icon-warning-sign{background-position:-144px -120px;} -.icon-plane{background-position:-168px -120px;} -.icon-calendar{background-position:-192px -120px;} -.icon-random{background-position:-216px -120px;} -.icon-comment{background-position:-240px -120px;} -.icon-magnet{background-position:-264px -120px;} -.icon-chevron-up{background-position:-288px -120px;} -.icon-chevron-down{background-position:-313px -119px;} -.icon-retweet{background-position:-336px -120px;} -.icon-shopping-cart{background-position:-360px -120px;} -.icon-folder-close{background-position:-384px -120px;} -.icon-folder-open{background-position:-408px -120px;} -.icon-resize-vertical{background-position:-432px -119px;} -.icon-resize-horizontal{background-position:-456px -118px;} -.dropdown{position:relative;} -.dropdown-toggle{*margin-bottom:-3px;} -.dropdown-toggle:active,.open .dropdown-toggle{outline:0;} -.caret{display:inline-block;width:0;height:0;text-indent:-99999px;*text-indent:0;vertical-align:top;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000000;opacity:0.3;filter:alpha(opacity=30);content:"\2193";} -.dropdown .caret{margin-top:8px;margin-left:2px;} -.dropdown:hover .caret,.open.dropdown .caret{opacity:1;filter:alpha(opacity=100);} -.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;float:left;display:none;min-width:160px;max-width:220px;_width:160px;padding:4px 0;margin:0;list-style:none;background-color:#ffffff;border-color:#ccc;border-color:rgba(0, 0, 0, 0.2);border-style:solid;border-width:1px;-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;*border-right-width:2px;*border-bottom-width:2px;}.dropdown-menu.bottom-up{top:auto;bottom:100%;margin-bottom:2px;} -.dropdown-menu .divider{height:1px;margin:5px 1px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;*width:100%;*margin:-5px 0 5px;} -.dropdown-menu a{display:block;padding:3px 15px;clear:both;font-weight:normal;line-height:18px;color:#555555;white-space:nowrap;} -.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#ffffff;text-decoration:none;background-color:#0088cc;} -.dropdown.open{*z-index:1000;}.dropdown.open .dropdown-toggle{color:#ffffff;background:#ccc;background:rgba(0, 0, 0, 0.3);} -.dropdown.open .dropdown-menu{display:block;} -.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} -.fade{-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-ms-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;opacity:0;}.fade.in{opacity:1;} -.collapse{-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-ms-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;position:relative;overflow:hidden;height:0;}.collapse.in{height:auto;} -.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;opacity:0.4;filter:alpha(opacity=40);cursor:pointer;} -.btn{display:inline-block;padding:4px 10px 4px;font-size:13px;line-height:18px;color:#333333;text-align:center;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#fafafa;background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:-moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6);background-image:-ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:-o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);border:1px solid #ccc;border-bottom-color:#bbb;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);cursor:pointer;*margin-left:.3em;}.btn:first-child{*margin-left:0;} -.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-ms-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} -.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} -.btn.active,.btn:active{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);background-color:#e6e6e6;background-color:#d9d9d9 \9;color:rgba(0, 0, 0, 0.5);outline:0;} -.btn.disabled,.btn[disabled]{cursor:default;background-image:none;background-color:#e6e6e6;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} -.btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} -.btn-large .icon{margin-top:1px;} -.btn-small{padding:5px 9px;font-size:11px;line-height:16px;} -.btn-small .icon{margin-top:-1px;} -.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover{text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);color:#ffffff;} -.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active{color:rgba(255, 255, 255, 0.75);} -.btn-primary{background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-ms-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(top, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{background-color:#0044cc;} -.btn-primary:active,.btn-primary.active{background-color:#003399 \9;} -.btn-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{background-color:#f89406;} -.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} -.btn-danger{background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-ms-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(top, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{background-color:#bd362f;} -.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} -.btn-success{background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-ms-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(top, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{background-color:#51a351;} -.btn-success:active,.btn-success.active{background-color:#408140 \9;} -.btn-info{background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-ms-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(top, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{background-color:#2f96b4;} -.btn-info:active,.btn-info.active{background-color:#24748c \9;} -button.btn,input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;} -button.btn.large,input[type="submit"].btn.large{*padding-top:7px;*padding-bottom:7px;} -button.btn.small,input[type="submit"].btn.small{*padding-top:3px;*padding-bottom:3px;} -.btn-group{position:relative;*zoom:1;*margin-left:.3em;}.btn-group:before,.btn-group:after{display:table;content:"";} -.btn-group:after{clear:both;} -.btn-group:first-child{*margin-left:0;} -.btn-group+.btn-group{margin-left:5px;} -.btn-toolbar{margin-top:9px;margin-bottom:9px;}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1;} -.btn-group .btn{position:relative;float:left;margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} -.btn-group .btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} -.btn-group .btn:last-child,.btn-group .dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} -.btn-group .btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} -.btn-group .btn.large:last-child,.btn-group .large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} -.btn-group .btn:hover,.btn-group .btn:focus,.btn-group .btn:active,.btn-group .btn.active{z-index:2;} -.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;} -.btn-group .dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);*padding-top:5px;*padding-bottom:5px;} -.btn-group.open{*z-index:1000;}.btn-group.open .dropdown-menu{display:block;margin-top:1px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} -.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);} -.btn .caret{margin-top:7px;margin-left:0;} -.btn:hover .caret,.open.btn-group .caret{opacity:1;filter:alpha(opacity=100);} -.btn-primary .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret{border-top-color:#ffffff;opacity:0.75;filter:alpha(opacity=75);} -.btn-small .caret{margin-top:4px;} -.alert{padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.alert,.alert-heading{color:#c09853;} -.alert .close{position:relative;top:-2px;right:-21px;line-height:18px;} -.alert-success{background-color:#dff0d8;border-color:#d6e9c6;} -.alert-success,.alert-success .alert-heading{color:#468847;} -.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;} -.alert-danger,.alert-error,.alert-danger .alert-heading,.alert-error .alert-heading{color:#b94a48;} -.alert-info{background-color:#d9edf7;border-color:#bce8f1;} -.alert-info,.alert-info .alert-heading{color:#3a87ad;} -.alert-block{padding-top:14px;padding-bottom:14px;} -.alert-block>p,.alert-block>ul{margin-bottom:0;} -.alert-block p+p{margin-top:5px;} -.nav{margin-left:0;margin-bottom:18px;list-style:none;} -.nav>li>a{display:block;} -.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} -.nav-list{padding-left:14px;padding-right:14px;margin-bottom:0;} -.nav-list>li>a,.nav-list .nav-header{display:block;padding:3px 15px;margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} -.nav-list .nav-header{font-size:11px;font-weight:bold;line-height:18px;color:#999999;text-transform:uppercase;} -.nav-list>li+.nav-header{margin-top:9px;} -.nav-list .active>a,.nav-list .active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;} -.nav-list [class^="icon-"]{margin-right:2px;} -.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";} -.nav-tabs:after,.nav-pills:after{clear:both;} -.nav-tabs>li,.nav-pills>li{float:left;} -.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} -.nav-tabs{border-bottom:1px solid #ddd;} -.nav-tabs>li{margin-bottom:-1px;} -.nav-tabs>li>a{padding-top:9px;padding-bottom:9px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} -.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} -.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} -.nav-pills .active>a,.nav-pills .active>a:hover{color:#ffffff;background-color:#0088cc;} -.nav-stacked>li{float:none;} -.nav-stacked>li>a{margin-right:0;} -.nav-tabs.nav-stacked{border-bottom:0;} -.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} -.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} -.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} -.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;} -.nav-pills.nav-stacked>li>a{margin-bottom:3px;} -.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;} -.nav-tabs .dropdown-menu,.nav-pills .dropdown-menu{margin-top:1px;border-width:1px;} -.nav-pills .dropdown-menu{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret{border-top-color:#0088cc;margin-top:6px;} -.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret{border-top-color:#005580;} -.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret{border-top-color:#333333;} -.nav>.dropdown.active>a:hover{color:#000000;cursor:pointer;} -.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;} -.nav .open .caret,.nav .open.active .caret,.nav .open a:hover .caret{border-top-color:#ffffff;opacity:1;filter:alpha(opacity=100);} -.tabs-stacked .open>a:hover{border-color:#999999;} -.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";} -.tabbable:after{clear:both;} -.tabs-below .nav-tabs,.tabs-right .nav-tabs,.tabs-left .nav-tabs{border-bottom:0;} -.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;} -.tab-content>.active,.pill-content>.active{display:block;} -.tabs-below .nav-tabs{border-top:1px solid #ddd;} -.tabs-below .nav-tabs>li{margin-top:-1px;margin-bottom:0;} -.tabs-below .nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below .nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;} -.tabs-below .nav-tabs .active>a,.tabs-below .nav-tabs .active>a:hover{border-color:transparent #ddd #ddd #ddd;} -.tabs-left .nav-tabs>li,.tabs-right .nav-tabs>li{float:none;} -.tabs-left .nav-tabs>li>a,.tabs-right .nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;} -.tabs-left .nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;} -.tabs-left .nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} -.tabs-left .nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;} -.tabs-left .nav-tabs .active>a,.tabs-left .nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;} -.tabs-right .nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;} -.tabs-right .nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} -.tabs-right .nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;} -.tabs-right .nav-tabs .active>a,.tabs-right .nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} -.navbar{overflow:visible;margin-bottom:18px;} -.navbar-inner{padding-left:20px;padding-right:20px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);} -.btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);}.btn-navbar:hover,.btn-navbar:active,.btn-navbar.active,.btn-navbar.disabled,.btn-navbar[disabled]{background-color:#222222;} -.btn-navbar:active,.btn-navbar.active{background-color:#080808 \9;} -.btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);} -.btn-navbar .icon-bar+.icon-bar{margin-top:3px;} -.nav-collapse.collapse{height:auto;} -.navbar .brand:hover{text-decoration:none;} -.navbar .brand{float:left;display:block;padding:8px 20px 12px;margin-left:-20px;font-size:20px;font-weight:200;line-height:1;color:#ffffff;} -.navbar .navbar-text{margin-bottom:0;line-height:40px;color:#999999;}.navbar .navbar-text a:hover{color:#ffffff;background-color:transparent;} -.navbar .btn,.navbar .btn-group{margin-top:5px;} -.navbar .btn-group .btn{margin-top:0;} -.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";} -.navbar-form:after{clear:both;} -.navbar-form input,.navbar-form select{display:inline-block;margin-top:5px;margin-bottom:0;} -.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;} -.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;} -.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0;}.navbar-search .search-query{padding:4px 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#ffffff;color:rgba(255, 255, 255, 0.75);background:#666;background:rgba(255, 255, 255, 0.3);border:1px solid #111;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.navbar-search .search-query :-moz-placeholder{color:#eeeeee;} -.navbar-search .search-query::-webkit-input-placeholder{color:#eeeeee;} -.navbar-search .search-query:hover{color:#ffffff;background-color:#999999;background-color:rgba(255, 255, 255, 0.5);} -.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;} -.navbar-fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030;} -.navbar-fixed-top .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} -.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} -.navbar .nav.pull-right{float:right;} -.navbar .nav>li{display:block;float:left;} -.navbar .nav>li>a{float:none;padding:10px 10px 11px;line-height:19px;color:#999999;text-decoration:none;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);} -.navbar .nav>li>a:hover{background-color:transparent;color:#ffffff;text-decoration:none;} -.navbar .nav .active>a,.navbar .nav .active>a:hover{color:#ffffff;text-decoration:none;background-color:#222222;background-color:rgba(0, 0, 0, 0.5);} -.navbar .divider-vertical{height:40px;width:1px;margin:0 9px;overflow:hidden;background-color:#222222;border-right:1px solid #333333;} -.navbar .nav.pull-right{margin-left:10px;margin-right:0;} -.navbar .dropdown-menu{margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.navbar .dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;} -.navbar .dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;} -.navbar .nav .dropdown-toggle .caret,.navbar .nav .open.dropdown .caret{border-top-color:#ffffff;} -.navbar .nav .active .caret{opacity:1;filter:alpha(opacity=100);} -.navbar .nav .open>.dropdown-toggle,.navbar .nav .active>.dropdown-toggle,.navbar .nav .open.active>.dropdown-toggle{background-color:transparent;} -.navbar .nav .active>.dropdown-toggle:hover{color:#ffffff;} -.navbar .nav.pull-right .dropdown-menu{left:auto;right:0;}.navbar .nav.pull-right .dropdown-menu:before{left:auto;right:12px;} -.navbar .nav.pull-right .dropdown-menu:after{left:auto;right:13px;} -.breadcrumb{padding:7px 14px;margin:0 0 18px;background-color:#fbfbfb;background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);background-image:linear-gradient(top, #ffffff, #f5f5f5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;}.breadcrumb li{display:inline;text-shadow:0 1px 0 #ffffff;} -.breadcrumb .divider{padding:0 5px;color:#999999;} -.breadcrumb .active a{color:#333333;} -.pagination{height:36px;margin:18px 0;} -.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} -.pagination li{display:inline;} -.pagination a{float:left;padding:0 14px;line-height:34px;text-decoration:none;border:1px solid #ddd;border-left-width:0;} -.pagination a:hover,.pagination .active a{background-color:#f5f5f5;} -.pagination .active a{color:#999999;cursor:default;} -.pagination .disabled a,.pagination .disabled a:hover{color:#999999;background-color:transparent;cursor:default;} -.pagination li:first-child a{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} -.pagination li:last-child a{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} -.pagination-centered{text-align:center;} -.pagination-right{text-align:right;} -.pager{margin-left:0;margin-bottom:18px;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";} -.pager:after{clear:both;} -.pager li{display:inline;} -.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} -.pager a:hover{text-decoration:none;background-color:#f5f5f5;} -.pager .next a{float:right;} -.pager .previous a{float:left;} -.modal-open .dropdown-menu{z-index:2050;} -.modal-open .dropdown.open{*z-index:2050;} -.modal-open .popover{z-index:2060;} -.modal-open .tooltip{z-index:2070;} -.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;} -.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);} -.modal{position:fixed;top:50%;left:50%;z-index:1050;max-height:500px;overflow:auto;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-ms-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} -.modal.fade.in{top:50%;} -.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;} -.modal-body{padding:15px;} -.modal-footer{padding:14px 15px 15px;margin-bottom:0;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";} -.modal-footer:after{clear:both;} -.modal-footer .btn{float:right;margin-left:5px;margin-bottom:0;} -.tooltip{position:absolute;z-index:1020;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);} -.tooltip.top{margin-top:-2px;} -.tooltip.right{margin-left:2px;} -.tooltip.bottom{margin-top:2px;} -.tooltip.left{margin-left:-2px;} -.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} -.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} -.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} -.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} -.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.tooltip-arrow{position:absolute;width:0;height:0;} -.popover{position:absolute;top:0;left:0;z-index:1010;display:none;padding:5px;}.popover.top{margin-top:-5px;} -.popover.right{margin-left:5px;} -.popover.bottom{margin-top:5px;} -.popover.left{margin-left:-5px;} -.popover.top .arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} -.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} -.popover.bottom .arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} -.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} -.popover .arrow{position:absolute;width:0;height:0;} -.popover-inner{padding:3px;width:280px;overflow:hidden;background:#000000;background:rgba(0, 0, 0, 0.8);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);} -.popover-title{padding:9px 15px;line-height:1;background-color:#f5f5f5;border-bottom:1px solid #eee;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;} -.popover-content{padding:14px;background-color:#ffffff;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} -.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";} -.thumbnails:after{clear:both;} -.thumbnails>li{float:left;margin:0 0 18px 20px;} -.thumbnail{display:block;padding:4px;line-height:1;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);} -a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} -.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;} -.thumbnail .caption{padding:9px;} -.label{padding:1px 3px 2px;font-size:9.75px;font-weight:bold;color:#ffffff;text-transform:uppercase;background-color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} -.label-important{background-color:#b94a48;} -.label-warning{background-color:#f89406;} -.label-success{background-color:#468847;} -.label-info{background-color:#3a87ad;} -@-webkit-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}.progress{overflow:hidden;height:18px;margin-bottom:18px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-ms-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(top, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.progress .bar{width:0%;height:18px;color:#ffffff;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-ms-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(top, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-ms-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} -.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;} -.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;} -.progress-danger .bar{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);} -.progress-danger.progress-striped .bar{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} -.progress-success .bar{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-ms-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(top, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);} -.progress-success.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} -.progress-info .bar{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(top, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);} -.progress-info.progress-striped .bar{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} -.accordion{margin-bottom:18px;} -.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} -.accordion-heading{border-bottom:0;} -.accordion-heading .accordion-toggle{display:block;padding:8px 15px;} -.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;} -.carousel{position:relative;margin-bottom:18px;line-height:1;} -.carousel-inner{overflow:hidden;width:100%;position:relative;} -.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-ms-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;} -.carousel .item>img{display:block;line-height:1;} -.carousel .active,.carousel .next,.carousel .prev{display:block;} -.carousel .active{left:0;} -.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;} -.carousel .next{left:100%;} -.carousel .prev{left:-100%;} -.carousel .next.left,.carousel .prev.right{left:0;} -.carousel .active.left{left:-100%;} -.carousel .active.right{left:100%;} -.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;} -.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);} -.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:10px 15px 5px;background:#333333;background:rgba(0, 0, 0, 0.75);} -.carousel-caption h4,.carousel-caption p{color:#ffffff;} -.hero-unit{padding:60px;margin-bottom:30px;background-color:#f5f5f5;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;} -.hero-unit p{font-size:18px;font-weight:200;line-height:27px;} -.pull-right{float:right;} -.pull-left{float:left;} -.hide{display:none;} -.show{display:block;} -.invisible{visibility:hidden;} diff --git a/static/css/ie.css b/static/css/ie.css deleted file mode 100644 index 635428e..0000000 --- a/static/css/ie.css +++ /dev/null @@ -1,4 +0,0 @@ - -.nav-list li a:hover{ - background-color: #222; -} diff --git a/static/css/style.css b/static/css/style.css deleted file mode 100644 index 880be57..0000000 --- a/static/css/style.css +++ /dev/null @@ -1,894 +0,0 @@ -body { - background-image: url(/static/img/bg-noise.jpg); -} - -body.logined { - margin-left: 260px; - margin-bottom: 30px; -} - -.logined form { - background-color: white; - border: 2px solid #EEE; - padding-top: 20px; - border-radius: 4px; -} - -form .form-actions { - margin-bottom: 0px; -} - -form fieldset legend { - padding-left: 20px; - margin-bottom: 0px; -} - -form.clean { - background: none; - border: none; - padding: 0; - border-radius: 0px; - -webkit-border-radius: 0px; - -moz-border-radius: 0px; - -ms-border-radius: 0px; - -o-border-radius: 0px; -} - -input, .btn { - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} - -nav { - color: white; - background-color: #2B2B2B; - background-image: url(/static/img/lines.jpg); - width: 240px; - height: 100%; - position: fixed; - top: 0; - left: 0; - overflow: hidden; - z-index: 5; - border-right: solid 1px black; -} - -nav a { - color: #FFF; -} - -nav .nav-list > li > a { - color: #FFF; - text-shadow: 0px 1px 1px black; - -webkit-transition-property: background; - -webkit-transition-duration: .2s; -} - -nav .nav-list > li > a:hover { - background: rgba(0, 0, 0, 0.2); - color: white; - text-shadow: 0px 1px 1px black; -} - -nav .profile { - height: 76px; - border-bottom: 1px solid #4A4A54; -} - -nav .profile .profile_wrap { - height: 75px; - border-bottom: 1px solid #1D1E21; -} - -nav .profile .username { - position: absolute; - top: 20px; - left: 70px; - font-family: Arial, sans-serif; - font-size: 14px; - text-shadow: black 0px 1px 1px; -} - -nav .profile .username a:hover { - color: white; -} - -nav .profile .tagline { - position: absolute; - top: 40px; - left: 70px; - width: 140px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -nav .profile .avatar { - border-radius: 4px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2); - -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2); - -ms-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2); - -o-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2); - box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2); - border: 1px solid black; - position: absolute; - width: 45px; - height: 45px; - top: 15px; - left: 14px; - cursor: pointer; - overflow: hidden; - border-image: initial; -} - -nav .profile .avatar .avatar_mask { - border-radius: 4px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - -webkit-box-shadow: inset 0px 0px 9px #000000; - -moz-box-shadow: inset 0px 0px 9px #000000; - -ms-box-shadow: inset 0px 0px 9px #000000; - -o-box-shadow: inset 0px 0px 9px #000000; - box-shadow: inset 0px 0px 9px #000000; - opacity: 0.5; - width: 45px; - height: 45px; - position: absolute; - top: 0; - left: 0; -} - -nav .profile img { - border-radius: 4px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - width: 45px; - height: 45px; -} - -nav .nav { - margin-top: 20px; -} - -nav .sep { - margin-top: 20px; - height: 0px; - border-bottom: 1px solid #4A4A54; - border-top: 1px solid #1D1E21; -} - -nav .copyright { - font-size: 10px; - text-shadow: black 0px 1px 1px; - padding-top: 20px; - padding-left: 14px; -} - -nav .copyright a:hover { - color: white; -} - -.sep30 { - height: 30px; -} - -.cell { - min-height: 100px; - background: white; - border: 2px solid #EEE; - box-shadow: 0px 0px 2px #BBB; - border-radius: 4px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - padding: 10px 15px; -} - -.nopadding { - padding: 0; -} - -.navBorder { - background-color: #2F2F31; - opacity: .2; - position: fixed; - width: 165px; - top: 0; - left: 0; - height: 100%; - z-index: 4; -} - -.toper { - width: 250px; - margin: 0 auto; -} - -.toper #logo { - margin-top: 200px; - margin-bottom: 20px; - padding-left: 40px; - width: 260px; -} - -.toper #logo .logo { - font-size: 50px; - font-family: 'Port Lligat Slab', serif; -} - -.toper #logo .subtitle { - position: relative; - left: 80px; - top: -5px; - font-size: 10px; -} - -.signinform { - width: 260px; -} - -.signinform label { - color: #999; - text-shadow: 0 1px 1px #111; - font-size: 17px; -} - -.signinform .btn { - width: 246px; - height: 34px; -} - -.signinform a.btn { - width: 226px; - height: 26px; - line-height: 26px; -} - -.signinform .add-on, .signinform input { - height: 28px; - line-height: 28px; -} - -.signinform .input-prepend > input, .signinform .input-prepend > .btn { - float: left; -} - -.signinform .alert { - width: 196px; -} - -.alert ul { - margin-left: 14px; - margin-bottom: 0; -} - -.sep10 { - height: 5px; - background-color: white; - opacity: .5; -} - -.main { - padding-top: 40px; - padding-right: 20px; - width: 96%; -} - -.table tbody tr td, .table thead tr th { - background-color: #FFF; -} - -.note_action { - display: inline; - float: right; - width: 30%; -} - -.notes li , .note{ - margin-bottom: 30px; - width: 60%; -} - -.notes li .datetime { - color: #999; - font-size: 10px; -} - -.notes li .summary { - margin-top: 10px; - padding-left: 10px; -} - -.notes li .more { - margin-top: 15px; - text-align: right; -} - -.note_notice { - width: 60%; -} - -.note { - margin-left: 0; -} - -.note .meta { - color: #999; - font-size: 10px; - margin-bottom: 10px; -} - -.note .content { - padding-left: 10px; -} - -.sidebar { - display: inline; - width: 30%; - float: right; -} - -.cell .module_title { - padding-top: 10px; - padding-left: 13px; - padding-bottom: 5px; - font-size: 16px; - font-weight: bold; - border-bottom: 1px solid #DDD; -} - -.problem { - width: 65%; - margin-bottom: 30px; -} - -.cell.problem .line { - padding-left: 20px; - padding-bottom: 10px; -} - -.cell.problem .line:last-child { - border-bottom: none; -} - -.cell .line { - font-size: 14px; - line-height: 24px; - padding: 10px 10px 5px 20px; - border-bottom: 1px solid #E2E2E2; -} - -.cell .line:last-child { - border-bottom: none; -} - -.cell .line p { - line-height: 24px; -} - -.cell .line .meta { - float: right; - display: inline; - padding-right: 20px; -} - -.line .num { - font-weight: bolder; -} - -.problem .table td { - border-top: none; - border-bottom: 1px solid #E2E2E2; -} - -.problem .table tr td:first-child { - width: 100px; - border-right: 1px solid #E2E2E2; - text-align: right; -} - -.problem .table td pre { - margin-right: 12px; -} - -.problem .last { - border-bottom: none; -} - -.problem_sidebar .problemmeta{ - width: 100%; -} - -.problemmeta tr td{ - padding-top: 8px; - padding-bottom: 6px; -} - -.problemmeta td:first-child { - text-align: right; - padding-right: 5px; - color: #CCC; -} - -.problemmeta td:last-child { - padding-left: 5px; -} - -.problemmeta tr:last-child td { - border-bottom: 1px solid #DDD; -} - -.codehilitetable tr td { - margin: 0; - padding: 0; -} - -.codehilitetable .linenodiv pre{ - -webkit-border-top-right-radius: 0px; - -webkit-border-bottom-right-radius: 0px; - -moz-border-radius-topright: 0px; - -moz-border-radius-bottomright: 0px; - -ms-border-top-right-radius: 0px; - -ms-border-bottom-right-radius: 0px; - -o-border-top-right-radius: 0px; - -o-border-bottom-right-radius: 0px; - border-top-right-radius: 0px; - border-bottom-right-radius: 0px; - border-right: none; -} - -.codehilitetable .codehilite pre{ - width: 540px; - -webkit-border-top-left-radius: 0px; - -webkit-border-bottom-left-radius: 0px; - -moz-border-radius-topleft: 0px; - -moz-border-radius-bottomleft: 0px; - -ms-border-top-left-radius: 0px; - -ms-border-bottom-left-radius: 0px; - -o-border-top-left-radius: 0px; - -o-border-bottom-left-radius: 0px; - border-top-left-radius: 0px; - border-bottom-left-radius: 0px; -} - -/* Style for Pygments */ -/* Theme: Default */ - -.codehilite .hll { background-color: #ffffcc } -.codehilite { background: #f8f8f8; } -.codehilite .c { color: #408080; font-style: italic } /* Comment */ -.codehilite .err { border: 1px solid #FF0000 } /* Error */ -.codehilite .k { color: #008000; font-weight: bold } /* Keyword */ -.codehilite .o { color: #666666 } /* Operator */ -.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */ -.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */ -.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */ -.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */ -.codehilite .gd { color: #A00000 } /* Generic.Deleted */ -.codehilite .ge { font-style: italic } /* Generic.Emph */ -.codehilite .gr { color: #FF0000 } /* Generic.Error */ -.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.codehilite .gi { color: #00A000 } /* Generic.Inserted */ -.codehilite .go { color: #808080 } /* Generic.Output */ -.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ -.codehilite .gs { font-weight: bold } /* Generic.Strong */ -.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.codehilite .gt { color: #0040D0 } /* Generic.Traceback */ -.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ -.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ -.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ -.codehilite .kp { color: #008000 } /* Keyword.Pseudo */ -.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ -.codehilite .kt { color: #B00040 } /* Keyword.Type */ -.codehilite .m { color: #666666 } /* Literal.Number */ -.codehilite .s { color: #BA2121 } /* Literal.String */ -.codehilite .na { color: #7D9029 } /* Name.Attribute */ -.codehilite .nb { color: #008000 } /* Name.Builtin */ -.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ -.codehilite .no { color: #880000 } /* Name.Constant */ -.codehilite .nd { color: #AA22FF } /* Name.Decorator */ -.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */ -.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ -.codehilite .nf { color: #0000FF } /* Name.Function */ -.codehilite .nl { color: #A0A000 } /* Name.Label */ -.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ -.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ -.codehilite .nv { color: #19177C } /* Name.Variable */ -.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ -.codehilite .w { color: #bbbbbb } /* Text.Whitespace */ -.codehilite .mf { color: #666666 } /* Literal.Number.Float */ -.codehilite .mh { color: #666666 } /* Literal.Number.Hex */ -.codehilite .mi { color: #666666 } /* Literal.Number.Integer */ -.codehilite .mo { color: #666666 } /* Literal.Number.Oct */ -.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ -.codehilite .sc { color: #BA2121 } /* Literal.String.Char */ -.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ -.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ -.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ -.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ -.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ -.codehilite .sx { color: #008000 } /* Literal.String.Other */ -.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */ -.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ -.codehilite .ss { color: #19177C } /* Literal.String.Symbol */ -.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ -.codehilite .vc { color: #19177C } /* Name.Variable.Class */ -.codehilite .vg { color: #19177C } /* Name.Variable.Global */ -.codehilite .vi { color: #19177C } /* Name.Variable.Instance */ -.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ - -.problem_star { - background: url(http://img3.douban.com/pics/all_bigstars.gif) no-repeat; - height: 14px; - overflow: hidden; - width: 75px; - display: block; - margin-top: 10px; - margin-bottom: 10px; -} - -.member_top { - padding: 10px 15px; -} - -.member_top .avatar { - float: left; -} - -.member_top .avatar img { - border-radius: 4px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; -} - -.member_top .profile { - float: left; - margin-left: 10px; - margin-top: 5px; - width: 50%; -} - -.member_top .username { - font-size: 30px; - line-height:1; - font-family: Georgia,Times New Roman,serif; -} - -.member_top .username h1:first-letter { - text-transform:uppercase; -} - -.member_top .tagline { - font-size: 16px; - color: #999; -} - -.member_top .meta { - font-size: 12px; - color: #CCC; -} - -.member_notes { - width: 30%; -} - -.member_notes_list { - list-style: none; - margin-left: 0; - margin-bottom: 0; -} - -.member_notes_list li { - padding-left: 22px; - margin-top: 10px; - padding-bottom: 7px; - border-bottom: 1px solid #ddd; -} - -li.last { - border-bottom: none; -} - -.member_bio { - width: 65%; -} - -.member_bio .line { - margin-top: 10px; - padding-left: 20px; - border-bottom: none; - margin-bottom: 10px; - font-size: 12px; -} - -.node .new_topic { - margin-top: 5px; - text-align: right; - padding-bottom: 10px; -} - -.node .nomoretopic { - text-align: center; - padding-top: 17px; - margin-bottom: 20px; -} - -.topic_list { - list-style: none; - margin-left: 0; - margin-bottom: 0; -} - -.topic_list > li.line { - padding: 10px !important; -} - -.topic_list li.line table { - height: 48px; - line-height: 16px; -} - -.topic_list li.line .avatar { - width: 48px; - padding: 1px; -} - -.topic_list li.line .topic_main { - padding-left: 10px; -} - -.topic_list li.line .topic_title { - padding-top: 3px; - font-size: 16px; - line-height: 130%; -} - -.topic_list li.line .topic_meta { - padding-top: 10px; - color: #CCC; - display: block; - font-size: 10px; - font-weight: bold; -} - -.topic { - min-height: 0; -} - -.topic .module_title { - font-size: 20px; - font-weight: 500; - line-height: 150%; - min-height: 80px; -} - -.topic .content { - padding: 10px 20px; - line-height: 180%; - overflow: hidden; - margin-bottom: 10px; -} - -.topic .module_title .avatar { - float: right; - padding-right: 10px; - height: 90px; - width: 90px; -} - -.topic .module_title .topic_meta { - color: #CCC; - font-size: 12px; -} - -.topic_sidebar .line { - border-bottom: none; - padding: 10px !important; -} - -.topic_sidebar .line .avatar { - float: left; -} - -.topic_sidebar .line .author { - padding-left: 10px; - float: left; - width: 50%; -} - -.topic_sidebar .line .tagline { - color: #ccc; - height: 50px; - overflow: hidden; - word-wrap: breakword; - text-overflow: ellipsis; - white-space: nowrap; -} - -.reply.form-horizontal .controls { - margin-left: 20px; - margin-right: 30px; -} - -.reply.form-horizontal .form-actions { - padding-left: 20px; -} - -.reply.form-horizontal .controls textarea { - width: 100%; - height: 100px; -} - -.reply_meta { - color: #AAA; -} - -.reply_list { - list-style: none; - margin-left: 0; - margin-bottom: 0; -} - -.reply_list li .avatar { - width: 48px; - line-height: 10px; -} - -.reply_list li .create { - float: right; - font-size: 12px; - color: #CCC; -} - -.reply_list li .reply_main { - padding-left: 10px; -} - -.reply_list li .reply_content { - padding-bottom: 10px; -} - -.reply_list li:last-child { - border-bottom: none; -} - -.node_list { - min-height: 0; - padding-bottom: 20px; -} - -.node_list .line { - padding-left: 20px; -} - -.form_index { - min-height: 0; -} - -.home { - width: 65%; - min-height: 0; -} - -.home .table { - border: none; - margin-bottom: 0; -} - -.home.newest_topic li:last-child { - border-bottom: none; -} - -.inner_box { - padding: 20px; -} - -.inner_box p { - line-height: 30px; -} - -.home_sidebar .count table { - margin-top: 10px; - margin-bottom: 10px; - width: 100%; -} - -.home_sidebar .count th { - text-align: right; - font-weight: normal; - color: #CCC; -} - -.home_sidebar .count table th { - width: 50%; -} - -.home_sidebar .count table td { - padding-left: 10px; -} - -#related_problem_list, #problem_tag_list { - list-style: none; - margin-left: 0; - margin-top: 10px; -} - -#related_problem_list .related, #problem_tag_list .tag, .cell.tags .tag { - background-color: #EEE; - border-radius: 4px; - padding: 4px 4px 2px 10px; - float: left; - margin-right: 4px; -} - -#related_problem_list .related:hover, #problem_tag_list .tag:hover { - background: #DDD; -} - -#related_problem_list .related a, #problem_tag_list .tag a{ - color: black; -} - -#related_problem_list .related a.close, #problem_tag_list .tag a.close { - color: black; - line-height: 14px; - height: 14px; - padding-left: 4px; -} - -.contest_list .table, .contest .table { - margin-bottom: 0; -} - -.contest .table tr th { - padding-left: 15px; -} - -.contest_list .table tr:first-child td, .contest_list .table tr:first-child th, .contest .table tr:first-child td, .contest .table tr:first-child th { - border-top: none; -} - -.contest_list .cell { - margin-bottom: 40px; -} - -.contest.cell .line { - border-bottom: none; - border-top: 1px solid #E2E2E2; -} - -.pagination { - text-align: center; -} - -.pagination ul { - background-color: white; -} - -.line.last { - border-bottom: none; -} - -.tags .line { - border-bottom: none; -} - -.cell.tags .tag { - padding: 1px 10px; - margin-right: 5px; - margin-bottom: 10px; - float: none; - display: inline-block; -} diff --git a/static/css/timepicker.css b/static/css/timepicker.css deleted file mode 100644 index 7bba024..0000000 --- a/static/css/timepicker.css +++ /dev/null @@ -1,566 +0,0 @@ -/* - * jQuery UI CSS Framework 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } -.ui-helper-clearfix:after { clear: both; } -.ui-helper-clearfix { zoom: 1; } -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/* - * jQuery UI CSS Framework 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px - */ - - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } -.ui-widget-content a { color: #222222; } -.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } -.ui-widget-header a { color: #222222; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } -.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-off { background-position: -96px -144px; } -.ui-icon-radio-on { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } -.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } - -/* Overlays */ -.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* - * jQuery UI Resizable 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizable#theming - */ -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* - * jQuery UI Selectable 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectable#theming - */ -.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } -/* - * jQuery UI Accordion 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion#theming - */ -/* IE/Win - Fix animation bug - #4615 */ -.ui-accordion { width: 100%; } -.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } -.ui-accordion .ui-accordion-li-fix { display: inline; } -.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } -.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } -.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } -.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } -.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } -.ui-accordion .ui-accordion-content-active { display: block; } -/* - * jQuery UI Autocomplete 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu 1.8.17 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/* - * jQuery UI Button 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/* - * jQuery UI Dialog 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog#theming - */ -.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } -/* - * jQuery UI Slider 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider#theming - */ -.ui-slider { position: relative; text-align: left; } -.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } -.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } - -.ui-slider-horizontal { height: .8em; } -.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: .8em; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; }/* - * jQuery UI Tabs 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs#theming - */ -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } -.ui-tabs .ui-tabs-hide { display: none !important; } -/* - * jQuery UI Datepicker 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ -}/* - * jQuery UI Progressbar 1.8.17 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar#theming - */ -.ui-progressbar { height:2em; text-align: left; overflow: hidden; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } - diff --git a/static/img/404.png b/static/img/404.png deleted file mode 100644 index 2f2f47e3009a6e7270e4040e66f9fd1d2c1674ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88597 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 {k(#8^ZIymw@LvW>L}UF;43BU;Srp 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 *ZluS1Y^L)>(%u|v;uAXCVE~zw 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 Ms@f{WO3#D;2Zty6J^%m! diff --git a/static/img/500.png b/static/img/500.png deleted file mode 100644 index 4c96a17c9d42628f220fc2c604bd56346f6e5727..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117959 zcmV+SKnTByP)7~9P zMFB+xRHO(}R0I^Tp(57{*Q>}C6ucA(2q8eIAtZ$Kc5;%__TDqI*7N?cW@eXj0-;HW zJfBZ;_MSau&CFWA^_1W9EF~g*DDSQapx)s*thFemP)Z>pD5ZLxeATK|c%H|K6)WiK z>caCpwC^!u*hsY23?AIt*O?J<=Z&I>?(S|x6s@fT*3pg_tu+=w;~@e{L2bXu+Eyb1 zSU@3Y6gD-XCG+-~5!snj$~#GrM6F@op0jdSPD<%uVr;N_QJlqE}+ zv3BiRj4`ZTyOwgf>^iWg88Ubif*@e**s-*>wlZeS7^Ssl^5n_Po;{nW60%^?LV5l5 z*Xiu+#P@SFH#akC)Ck6n8>1#qp3KhErh!t~07~1XvcGOXSp=~bUweoMB7)W$1t>|L zh9VjCHW`$lYMw{!amJYHV8sE7yPjaJ$^Z@P_Qy)y12@L>0-(1ewa1EafR1wSMXca? zL3RzTbxk`PuG#Q)W5g8op(gUL5S#p6|JgAeL`p$dR}bI+{+06Azy6g4ix#2;1`i(0 zq)C&=<#O5np64M7G{UQ|zRH3Hi&(yVIYWjF0j+2qFp#xt*AkW^)^xNpV#Ejr3~(Aq z7=|ocwuD?R$EKTZ%9fKSv&SBLaO!ENsr2_;t^fjJt4g#CBgwF58(pHyS3KDWNLqqiz?9OL_b1`rvbQUjtEJWtgD z;Ty?^AhMCkzwU+FM5$lDeWS0O z)P$#!nK=#R{8;we@_rupI+40)c2l?g9B>}o)>WW<(JE? zx8BNeCmheoC!VC5o11BAX+e1!8@mpk&cbOYPJJoWfoLg}Dw%zs4(z6;CP1TkJdYtmhB0Q$7>+vXDD}lJela;0 zz?+*f>+|}nT1aXlxo!D;z87F-&srdi!c05t>;0zBX=9RqPY`(zq}nmx{!Amu@e26X zx4t8@X3gTNtFBTbMvTDoJbd5B_x)auy(o&DQ?+3hwANy6jOPUz$hhq>N_l`LiYfpE zK|o|;H$cQvsZ{WST&8Vk4aIyDQ550l6q*1V3r1pm-)TdhaxS*iY3uvG)2KYpX+gd- zPf{(W)(lB!_%IB)@x~iv)v8sDA3vUb_uW^G966G5xlBGE(B0k5(@#ImFMjbWx%b|C zDHe+qi$yND-~#m@|M4F{YI@ZS9EOKG3 zMG1s)gs(kvxm;#WWY?{8Kvsdq{Z`d7s?i}0Dt7lN8kD8}`PDo_ss5>i5hixNk#u0D znpCZ{x3^O)7AX`8fCI=>gG&EutqFpF*|TSJ@x>R*Bab{nKA$I_&-2^g{#H$$I+aqX zL_VK?+fkZ0j?uot7~zR0p5U+d-X{|$PE`BuyD!6s56_-2kU4l`n*!y(m;76TNbiB% z8$|kgDyq-lY~62-=XvvM*Pl-T9UUDsH#ZZt_RB9ZbH-ELdh;#v;>)wS=%R}_?etTXmzZEm zRh_@O;RU~&&fX1CJ_HdU>rA3SQRk?H#2E;vWItPTv`Y3>4YP4=bfuPSU@Z7rA?Y=g z`<(8RMljOoh8T;|#?8XoCyE>c!&-~-H2EOs+MnIeST5AeHfM5_4lk+uNIqfE&&tr{H3ClDU@{~#yH10A+L6B+@ zN+Sy5*y1UTpeaWoN_i+Wl_(3h7BFc9=q($c029JonY8kE-9I;^EUZ5taH}kju$bBV=}vKmYm9)v#eB(8`&ZwVFukP+s2<@CQ*o z1Q9?|a7aMJZEG}NY{N`eGb=jERh@F|;iVHSAPIR4Y#5<)`MNWT2nvn0LM%2pzs1IJ z*4eweJ9+l$XSnY#_sFbgXYj-mGbs0j1C ze}O&r+=~M~aUe$?d8BG-=?|U{T4Upwra}?zc~vL2xM!=hk1@{V(;CkI>iKg2efJWE zA?<5A_{0DFNo}|7ws@Yx%lX;Fps6}W1?LzQWAU`drQi9MT=2E?RUB6wkOg^^@`;Ti zm-G4i-|y$B&woa4x#bqM$L=4cwRH$ebjI@Si&wHS0?CIULWA>u9r1jrGh*n~AuNJT z_Sb-k;>^ZRXFP>q!%sxY>9%9WjFO<3?jm1>%@Wsgq(MM|)cvSZ8u5 zr7$KU=lj?=0>Ja!EE>mQ7U_v&=l96ve2jI@T!lwOgcySoh41CueP~5&T~tSFO^`1T z#)fjaL`%OWtSAckX0(?l-&929npnJK1<$_x60@Fvju}rq%hDBViLA%U_BFJxi6~o` zvh7wJb|A_W_zWV+F`t#^o}a~||Cp{?`wb?aFS!1rswo2^swO(M@yWkEh%`Di9f&kKT5EL- zO)rOBcAm6TCfg+SbtK=dCF5BLl)KBccdVtOqk|<27x2%=ACnhnJ+lnO8+2p&3D#4F@bL5}AB16a1SjfWnY&a4+^^YWaztnCh2x}u#$ z%e$xuY&B&v#~gDkyYI258ZmklgN6*HSZK!6Ri|Ydt;&2%N^#>)ZjxJWxrIdwmoRbS zM6SN(Dm7)w6q=fv5^zu7n9g#8%B2#;g3rhI*hzkO+pRqI=yd-2;6t4Kl?&8nTTVr+ zpnRWu?)@{To_ewz_1Vwzor^D3`Fs(j1TXMWN-#$1NOT*cbM-?Ip{jFKUvFO^lJ2D& zzV~rXsqZk#x%)v2t5>gP>5_%4T(*K&=gg6Z9(s`J)BnNZh07@@Xl;SfBZo3{NGmP5 zfQg%pXUbL+88Lha+fUgNg+)wAREaTBh>0o)apsiulwfU$R*Jy$Gi}269T6<&`6x{m z6^X4yX-Q^bm9^a(P+r>k4GN1EP|Cw#&`BgiYcPpp*ny9A14ydQ;W&0Cl$ZpZltL+w z*a)H(qAb>epDR)*Hj^(FSlijd3op-O=5sGG{mG|k?=CTS{!&)9RfvEccA3hdpFENs zcHBu#+F~MO#*R)Bdy@WB7^k4OK>|2y|$wdD>wf%ZYc1z-QF+;GDUT=V^F zIqujKRI#}!12b@1QmxjsvB|$Jh*bUaRVe5UB9MZHGiOo|iEDnV9wS(kC>Li%XO_|G zRc*|jJD2C4drqEz@j0G);!&QN`7EVUM01PB8G!2X}u zpKZ3?UQOG1SLfaK`ZR4NtDKKpF>< zKIHQOx`y=NP7!CV>*?<1`B~5M)RQyhg;~$>%*>~m_4KoNz{pmZw8eO~-D)dF4c~+< zHs6eq!!}{`@F6I%C=5}h8?h0dGKe*JS;R;1&`Ibqam=c!sbQ7#Zz!AiY?SXz4h%Zb z7!#v)l>#r~(&{~>k=SV`(nxdwbQ+Ns5LNvP4rp{uHxevbc}a9h64I8*K*U-L%K3@J zB*}LeL^)@Ih~WFV#8mRI%17sl_(7h|9;cza`r3S6m_3&#pLw2FUh71B*k=2k*nQvq z*maNH)xn1xQuB_}_v4<^D=*LCx3~XV9{$He9CXluoP5fus(;G>bWQ&dJipU z+v+up9zB{Jr|rxpn{2|=sZ-Uo9d~f-Pwgn;RS?q5m@$LDKkzqs@%d+Y_2n0M<)s%X zcUv|eGmt5hwqS>Cw_)6{7DkO4!KR}}(v;6(O@y)*WewQanGU$HB4W@eH%L`APL!Gx z05l3Oq_xdpHL?>`(Yfxw1gfFYo zJ8%G5jecp2b`4d2fYLconzpqayz<&2o_X+nBg(iF*5QhZqgm1gj@ z#Go9z?X*3+@3JFfMh<4PF(YYiDlj1Mh)swVH@K8ih;f50p{ixh*FNuEE3hiNe@Q&T zN%0VRRSVHjKV|L0Ew;9 z4qQ8uYbVZKcdlxEkSr6|^OIU88WrT}EXOQf*};qR7BcuRqG%5(6Raf6%py>-1^(! z{>EK*{$5^u@kN#{UCfFVs~9+75XYTxJO>0(e4ZzSPzBP!4=*MUyH%4y2rx;C`v~ ziKL=3(~2s6JZ*=v^r1i2m_+q4vh+GmJ4&J(Y5R=Ryd(`(TTnrPvS><1(b*lbyse!( z{^uU+v2Fq^2PHwaL=9O z+vlCm0lV*ntX+-Dx6oF$obmNb_}pn{^Z75Hs!R-?*2IzJ;6o3Q<;$0I_uY4^apT6h zXY*ln=7T3`z6aW=#^rLEyY9M+>#n;-^7*1OS(Ytfuf6u-gcD9s`|W!G#pb4j;i)qR zU>sJ+=L0}kyJ|JR|K0E8)?06-Tw-&N=d~h9GDOCp?wUQ1fNoMj|%DtcyP^bb$b{=c-8ai>kVN%r! zlnW-gL8j7yn?BeofT)`9S`=1Q!6G$HP*o0a=9nb~DapQP?=86ptYlFkHt7RwA#2vGp}oDGPk!=n zF1_?pwaK6%u0xubLZOh+l;b$@>||-yWotZWo=fkO*G3halai-qitK69yY0yS=>Tykvp&IJ0YA7xXSc%TSQ+ty6 zZ){DwlqftDR*XBJcF_}*^WPX_C=?2m%Vj`2)~Yy%m(@P)T_J`3LwR!6%lzo(U-H}w z^BJ}2NXBkCg=?<;q1t@XWMU&|k1X}TQwif#DXb`BYv}51=jQ9aCx8FL@3{86-(s^? zh0>aG9HR;Y`QJyL;;WZj!=lcz>M2EdUVx`GqehLAopzqaJ@?#Gb>D4-+Q`NMB7Klx5}<|Kx(N zeO2bYG8-Sms+FsmFlr#DeDN6e+I4%Havs)1cz~xOih&0<#2SOIHJ(z$ahR}IT^heG zG+|?x52GZ>V1+DmHuL5yokd`3?yTl>JsD0@6Ef*bR01O6CA;ZF)3E8!4dw`S;Ni3r zja4Syvd&A@Mr-O-A_r>P`pMBTq7A8*VO7->Lo~kcV{8Rc;!+62Pe2Gf6k${$2!f;@ ziglonB+rTR=&nQv-f8{qgc$Y2c?&%;X1eD8`{=+uor1QSRHXq%evoE+vMUf%z zdz^aesq)z4PjL6$cdPN^$0x~z-Wxo%52kD!Ad-nILzp_?9)J9C&OZBWX=`g^<;s&AZen(z=bv6ZGvvyS{d+#=d&maA1_S|KA zy4zP$P!ULo_7zGTU?@q*U4h10gQqkms?gNbL{Co_#e9L1sapNjqQp+qsM9jCL08?R zl*`nq^+`AkweXQfXEO(3y3s8Maxb(%+R`Y!G?Gl) z;0?}GZzeUiudj1wfS5*ju&5-1+6a_li|8Uod`xiw_dM_rH~!*w7Oq%JOY0^){=}22 z|G-v)Tp_FEo@x$ZRA%Xdc^rS_;j+c1Bf0Xt69|Y1aOnajD3BX8nrnaZTONG!Sss`^ zLv@zQ;N>~-#FOQJ5Jr6r)SP^01}1>;Q0Z{b6)sz*=46LUb2wmj{dal_tB3^ z=Zb}l9N=@{o;!2*?{49y?|+L;2Nx-?SwgcH(&Sq_72_#q$176zg`jkz5!iYlR7xYF zv3QVXXyHt$-mjr{TWy(vRHWt~Nody%p!6TOftCKNd72I9vf1(39s&xJaYyPk9K&0Y z+BR5JO<1=!V$*nE>F)-TP(Fqbt6} z)U7t7ATeV{jg@DfnMF^zLKubs31#1s^8;F%nwd0tE9Na&#Iltu(Asxp0rGil6tiae zV$M1FSY|!(BJ*dzNWYc=DCKd{MHi_VPd>?Imt7{#WU8MWYyUQW{-DSP2_lV>f`&1s zE+@hFeT<2SoO#p-^DbR$J21Q)0!cRftw7&!=1t@qM3yCwO5umtJrp#~gK(#GwIW z8N2ByF1+ZQOrJiT+i$japglRwFK4Y{bK; zYUOqnmudDaUZsP6UWMC!dL5rWa8LH!X-mFw-g(?~{STy4sW@7G^2od(N1@olsKv^=29iT73`!1UBFm@ajzg_c<#WD8kycYkBtBXZh(*Z<3i$&tUGWuTv-# z7&2rSyY03M$DeR4#~gE9Qt&4Ur`nj#HLH2{rI)zs(o5uld;i9?Eyprsa0^F&@?bu7 z;KwjsZL}|$OWp(VVu-Cvkw=JCQj)J>B-OXot5Zp9{Uv=%AEBi;k?I;Y>jw(;1FzA? z@fNO|o#&l(_TE5H73Xkmyf3?s&uLrgpJB?M5dlfHkYtwkw1>7aHtfL@MQlP=Ett*M z&pCzRL++v}ulf2{zfPqR$(d)Kt(sa|P#)w8%?ukgMwKc?x_UxlG%6|Upb@OG6mvf1 zt~H!>>d}1t+;imj_uQwfg}}>k#9@cCV8H^`c6HJ+a1d4B(gr(^ueWTlAd*UI#?%hf zdGqG+qaXc9e)OXsF>&HV#*Ll8&eL|q)0%PP$MdOAAE~zAZpXxF>OA7U2XkI}k=t+k zrTpLr*D)aPvHvcU_}E9Laq@p0i>-9BcG>IXb&N*^W!=D6+C^Nnr^zcHv2NWImrIql zsn*Wz+hUG}=ehVO6gNOjSYH-2utqb1odeOz;0PS}Raz6a)dy;HcadtM))tVVt6 z2y;sCaEX657Qnb9I|YH~B0WmG%4jR+zr@jp?9EO)Yy+2H&!rb#j14RDmGjS2g?|0f zo=5AT!F2Y7beGF0?Yqoh6FI(`hElnQVxd1r9K1h2IQ&G)-5uzBk$(O9vDvusEO`Aj z^7(xA-jO;V$p=+7co0d=m~?huvSbP8pMSpGfB*fQ^dBek(Y^Lo`|bBJ3WWj#2lPWH zyblq3>Bq-*+lgb3JdCX;j-!3WYXrU~Clvy%5R^+( zPY6&kxL$4~2`l2(d z6bj8$SvFq7eS9#rk_{e2fVy<*?|tuk^5~Zm>3sr`hMQ7-e$2k75Bdi`_<>BDHjUFyKV8*U)An?_I+{z8 zQwpA#{wSAx>q2?#9}lznro%bygj3mL>J<7Fe0)^_!ErW{3rOS3$#P-cc296@Qq@;0 zHxy|cV13yK8*1C%eK7)BX$Pd%84+4+5-N7=W~VV#*ZV;ke5J59X4H^YzH-KCZ2IT> zxb)($qf9K@Z8ecV#jau-iBr8H2q4xnY{({Txy1;cpZO$({(~4cY#76b4+WerL`2~! zGPZP;x}YFo+@{jF6;G2+^yie4%#?jp~&P2VJTw#(_FrDP1 zyiYg24q5+M{NDvIYJDVb9!@ieO;RgGE3)K6jmsZ0%DTQI)%qrBHnWN=6t!mffC8U8 z;y`jfTz%QMIPB0P7(Xn4IJutoGT)gXE{QUZP!h7k_S^86d;Tovod0$8g%eIt0I`jd zb#I)LUTfzU@jSN-YOOg_%gj#mthDF7h1c3!19>m>&-gM(Diwa}>0DMmqnRSKO zTy3!p)jD056LNi>lW)z5`2iPkJ`k(GQwnR{fVax|OLPszM3h_I&qojw(Ufn(3p9e_ z=)(>m!1BjG{+=DrI0jD{$ETI*uv7xtMl=PQiiAwwY*QY4@(F@`p0VS`If{Z#xK2qW zc+YbtmMe4(AXF+9aycJsExBASqc*rkHr!rKib$^v;of|`_e3^$5J{2wPk;K8oPPT0 zYT&?ut`4#S8ymFm(cRNUzkbb}_=V%-fqVZ%QAZqmStK!!NK9%M`Lc+_7!fL=Fnrih zUijUgL3wzdMrmj2xbmDXt6M3T462kO2wZ<`YI5t^h&Vt=qmy1ATF5#9WF7Ke;K_zM z*=8alEMB~rabw0Za^y%n|ly?(NaX-+O8F4J1-mZ`DI%vZ6s7vv{bwTqcxIJ~AtOg; zwP#~%@U=&!R3=|6Fn#(zIP%CNC5j>{6;~g{)0$$gNJ~o#M||p2oP6qOYW(=Iq$Oj- z+GM?C@O+g-CErSJ(Yq(_yC%|C=0hW}4II?UPCHMdso0VY`p(X7`uA&Li}9nSd-ZZ! zyoj5=e;J=U;y^ln%!CDTfq`&Aqa0oe5K4j<7z*#WwtXf2B4T$4TQv zQ2m}&Ti-z1{;w2+)H|UiEoPmry{uf}C#5r!HGS`C>BY1zuh0#EQtx$?$iiJEA#*LCDZHRkT^NSx}!2~#S>dqre>pUjz>I-hAnYJN>uX?MSCqBue;A5Q~u zL>Pu_x9!#v5MsMmbJMj~u+0{mV!GE*@C1o_oJS)qW>j}}oqB$zpajo3RuiyKtNV9$mS}2fam$VRKFU)dmN<+Ym?STJ>C&Y<{`eEjoH;{g z&U}U?%a+pK-pRRzyKMz|EoceJ`=G>Nlf;blMT5&%(AK<# zfl+Pjx+;kMtL4o>1Zs7>dXQ8NOHR~>eAkt2ykP;!+XePUy|<4&-sBzk4XU;6akW}Q zBa~H+yB~a0e5K;I^MK!A+78lZWK}f;c7`G~*PooE7 z*7MJC-F4T=3opFD{Q2|QY}|P6zWZ*~+S*FG4l%G^k(;+G8-QcA4-iQgZc@tCfJj2I zt5>by;%|OK9=!Wbnmx-8ulyF!aPQ zuVxlopGXBf_3}JcbVqExJvWORuK%%2pFSPm_xZyg{-DN<8&?sx-Pez;AtUus+Iz`+;WRtef8B0 z88U?5{N^{kfaJZ9_XR}iU!lb&^Q5YCT2}ogot>Rr@|}z2_Fw*tQ9}oD`MD>u!fPu#GX5PuWt-o%y%tGQL(TYeQjug*6H=6+i z2eaeOyU^8BA_xNf#3vU70X^k1tJbdNrP*_tw_p)ZJ^MUMSGMu`qGgm~*kkW~Iq;Cf zn6mv;HD%lFP$~!FmRS`*Yd_2WtyC)H^Lehl_FB2-nrk@dpo6&Kh8vV)c)xdn*!LYo zgle{|qj#xH`A+w_`Nr$z%F8aIzh}7kYhPxs9kw9q>0m%HAWlt}BrRUVBw;%*q0A>) zx#`7~BbLGYH@ntWu7@hMe|ZpB*WEGS%{t zE^Xc>GhO47n;VC`y-8wS{*p!zG0G;1n*oa#FJtf~Ln#)UF(z{B{o07YcZ;PdrSJ=R zB2g5I{U}9-*B373wbvIj^ZA!~`o%fSc=}Z)Y&nsSA9x5yeCkLwW!f~rEpq0HBdH`K z*doR)pYh%ATq3vLdMmg5>{fNyVTaYXw_&w}^z+-5_uZUHf{z&M7JE`SKM1(={y+cm zPki&MXG{B%`F#7l)A+>RyHb!Ih+~R@Mj7XzO5bc|peTSomXZX#+VX{OYbJYVA>K5h zDpf&ii%+M3@{SGytwSP8Aq#@sT%fxx_L1Y~oXYE{I64szr zn#dY_<)IZkJ@W~^a{9?K_k~%U`GrsM`9t@k#gA#qdz8a4y zE?R5EnwqM(f|nKcc8h*Vk_oKE#deHXSEeFpCbAmid93N`VfHKYx&Qu$`QPa?88v1s z=X~v(>afoqOHbKQDCCo6OI&UaR#>!X5m#S*wM?EonbW^?M#`CJ7?1C~=E(cRSWT$H zX(N=*iV68zqZPERTEX?#T_?}YoWyk<~LqO z;q6EbSS6jI_TK8H_DT2mWPdPPMlt%dhk!Y;vBVLYW zD^{_5WxE4Z5tlxm)c>RoH*4A>Dk0*fvy-?mq!m<@e%=w%#DuO;k_qYGoMWf$x90TIPUM;^zC&Ou zT=3;H<%;iIEKS8cl}bq3_Y@Z8X@-v+!EwhOr`pd z?w%6p0Kw&ZSU`CWsOl35(|ge<G2T*R7=uDT*QA4=bnPF$W+ z$vVtB8K{ZIp>$GiKqYAw3Y4EPiG2hgF9;}=%cMq5Tg$cF zOan>sacg4a?^N^~-dxRX)?KUjF{xde+Ni0cv{vdC#?mf(xlkw)R$_cVhZR_}wv!iL ze1%FZsGxwCYeKvLD;}}67zBesq`G)k6_{LJjZO9wMYc#-|3QQJ-R*ZUXwW7^@jLSa zZJg3rq0c=dBT~&0#skrK%0pX08A} zU@oF)dN}*kdz`~n;WQ0bp*#TtQx6Kp7*HNc`^3q* z!Cjpl%%1%kEv#mhoUU-Sg<417fv7aWe zU3j)kbHOds5ESxsbam0(+>GE>Zx=1S9!4E~TT~XdwC{pr(Du4Pl0?7yHdv(-d((5v zLnc4FQjRXL-BYS$1JqeHX=*yo4xwJ%^t^zIiSY|X$`LGC-N}sSW^>5#C$YLaCN{3q z6!RXHo}NU*5lmX20R>bdz%C+DJMP8fp3VZFk6TkZDkNLx$f8?h({#bIJMiN?mW;&-8)EeGN z>W6zL@-M4w<{UWU7Wz>_7>4A60wlz!QdnWx;w60d;_tHS_TxG6*v~MqNkey;KpAWl z6KEe}ExDjT6g$nOs)9855|R)vxLqVEvg`)WJ9}u24A9!alJReqmxQVlz!7JsYAjI{ zQz$m`)YH!}b?Q_qr5@LOYY^qU^GbOr?K#$rwOI$1*pMq0Xz%KwWIS&C*{`_bx*uR7 z=!x9(HBpQnCp$M0#i8)=Faxy2|@-12`@Ck|A*zQz#TT^pJyP zv(c^Wy4_?B{rFxipZ5a&d;#l9#keq-V^BI?gIffko)c0Hx2Bv3t7>N8cQK8>H|N4p zl8wT>DBs5z*JiDtPzb1WcjD&?w6(R<+S*E-tYHJGpGTbYSNRxY-908DLu(-y48OpE8YpL&mY~#A&ou{!Uo#V)?=aygYNZqXYcoSuhr5{)c=% zpu6J=HXGfaou+QbUVDFxX}j&otv6oF7MqWkWvkaH5rwCHL@YMt1BuGGEl%F~czBy2 zQd5z-n%d>Qr(wccI!`*mS?DK~IF1Q?pR2F9T$V3-o!z&e$d}JJnWgjQFtDkB zDR(F556C8VQr|~4{8_b9-uqgj84zVQuyVD&)9{(G=)k8OhLppIC5x6YX~G10dV27c zp#6XqD^@Uk_{eG--K2$wcDJA;izsO?o!wmhPp$I2ws0{IPJfL1uDhO|)$QbS1%?b6 zLW?p~;s{?1l`tmA6%Z=~xg?oRH71d{B@~o$=3Z<h^6WD+<<;4-iM#$zwdp7LZQF~7hcFY zXPwE-H{K|xoN=ZK;|S05(CM-ml8o8fNnUKiF?oCPj?EcO>hDO^W4B!}b>QOc{bbN< zpD=V~;L^ppzkkK$j2|(GGydZknmvonYvOVVPx~0D63J4>X(JP{uT=Kh+2P%#xK|lF zu3Uku5s|9%o~JR^(tltp58wS4w%B3|!Z4zk_s{~BD58B$2NNewMobLKX8w|Nc)4W` zs#J6II0c)Vc^m`nB+GfGZkCI)atu7#yh`d$K6uddL`gAq3o{HYHG3Nl~?C6 zbm(wLAOZwMcSko$Df0QiIft!)C0WkEl%Ki`6lK?^v*CpZN*l|>v%YZzY~#>E())YkdrAFIRWg^w#ATFHcBfN}zzNEhM)L1001xn!sdFIS}jlr7?qg08qj7!k0UhVuL#zg3>(tI_%D_Nw+y?o#I zT|%K(;KjKM`RyP7!nZEFf>K*Mo(>#UJ&qYXbQq;lg-RvD_kFs$x-vR_N@%MOC##Il z;G#ILkdq%Yv0~L~2DX9_k}m|HbwZ6_zp!An*80Y#g}|F^l>j1|0mfx|!j z8GiMf->MsK{E1q&bVYqTb-fc$vU}M8Ktw68f%#Tbd0ML59(?d&&i%?)W!(79l|>T- z0be@hWEnTSiT(H5g$d(EAaRLe;DJqOyx#w3@6E&II?8k3UsbKCyZ5YFvL#ubXJaNC zZ05lPL%VSsoTkvF5hi4~pP5DzZk&;R1D`GY_IBjVvf_lO#|Yl%S7Y_*t}n4sNmqYWg@CY?^l@erUU zlnE{ToJwCc@`N`b5Gp2$o7{HWZ5*~@j53??+L>xon9F$l|Hq?^`BAyMSBj#j|6fW7 zLP;QC-|lVv$?yLTpZNWcS*0Xp=@*V5aP)a$e09aQ19i=(!P>e=fvnPB#flY&vwHO! zs(Vui;eplpNBIoliS$0IC%ZSMmxtw9#zhxh#Jk`7KKqiFy_6T7eKxHm=E}=1<=)$G zXF)^qU(SCUGy5Jv*n-Mhzm}$3<3&pb{3HTi`S=8m%+CEexT9+J?WfW@6><>8+_`Q& zBO@b(p+ZVX^Nc(%$&14AT&$}+2_=!z&6yNcUt!^-{1(zuGq7MW|NfJovv;b?`5*oe zvy+opZ3vZX^;woViIxL42BBj1 z?%hkPk)XX?{Xh!P`4P#ln!@*&G5XV7Vg1AJ$%a~Mtkx)LDY|V=IsRyNZQIP&P4}S$ zl)6$?``-t@HqB2#Ox@s02-U|#W$v}=3*Har25?Xrt3^@tLL})iVD=U90riCHEq6BE)BgBaP zLor#GdHaApG569Hk|YWHCMPjglO%};Oz}jx zDv~ou>8t|WIR>B-cJ7(r(|`FzzW9$9pl3TS9PW$$j4=!hjUZIOu6^U=MS+x(Zns-o z4hSLWrYSSCZGs?j7>BW*`tGADCCRdaM|SRE#o;RvN|C0ip-r!l$>!-Pe({jPKpaZ+-Cn{P7?Bt_=bK-W#XXj(0Q{zwpI|`TQui zR(P)x|5{})Au1efF8TB6#^z6H5wYyQ>r`$2tp86qW*667c@>}g+~1%=$;UqSF)=na zhLVD>eECau`$G?M*x~`+`sQD!Gd)Qo4AG@UTLCg~Z4Z&IlRFl?zF>ZjnChq=iy?V1 z73}?$2SE>c2hT|fB6jZD<9HoWf)f2wy64(gM;O+jhe`^vyvx~Vox!FJ_b|147eNrXzTqBAGlm+&LVyv~=Sx5D z!gGu85u;CatH=cQUv!-2`)SR_Q;tNcU9;k78k|<3eh^B-wO6m@PyXc3?8L+rfAoj{ zm9x)0gJvj6+k5!Vx4yx|o>@NgsZT<8nnV;xq5b4K)+U|?F0d%$ze`jR0QL9#Bf`+D zJUp7N;mMDxWZ8Q~3yG1U$NH?^X)Trj8#KB1!7VIYwumTp4)h_GKq=a3m%(Jf84;e6YaNLd*aB^Y8fA<^I>uD zqzbVzLKy3+Q&M^`wlY$ZeRK9`AnfDaa&x1|{&4=8G7g*)_bQV0QsFVPN(A73*Q=?e zz(^N?N(;)CgeFC#Q@rLyFXYRg|D5XvZLMcIdrSlBsK)j4E5R0ZL$1KLn*gX}6X2tf z+SQ~N6$L2AO?o=>@l<}P|DmZqLJ5gP5J*LlYsSaN`RGSKYPW3J%zNJR9^U=#^Fr)enkRL^!kGj%_$ z4%YP=5+I~x>(;FlML{D@P|Ag#oo>p^Y=>qmany9_xEWJ3lQdchVHi4$Ls&|kQy5K@ zwD{~_f1cO<`ioh<;&2)RgM?8;x7#HSLWGql75W{@vU1fC>>Zz=J?s27b?GDqWm!5! zuQce=(dy|t2dfQX7!pMZx88C)0zs!cOIhYLn=$S741lA+Td(-_x*VwH!_2Apz=6`6 z$0>_iJ?A|_{A$`WKIU0kN4Tu!OrsGPB4z1J?&TeCJ&(Wt+s^}*PzgdQ0M92f{huu9 zSHx@MHsQ*j=c`}&ioM{13v8_v=jjSQ4m=)r5qZ?`)Y7LoHLhGK9EDwL%WKa)*Y4T7 zix-anuGoN$HIAquEy{tOyaJMrU*GH$_?$R6_WN5&Fs@iim(ljMW63VP{ zYqJzuvtZFO{_Wp?#D)iU^Vk3Lb7X}k%MIE%V74e62yKnPN=2b9hpk-Au07)zD+%K! z-7KZq9H_O;+N+1dFmx$Xzx{x4T%IsUNHfa`$Df1}mZHpP4m6mZopouAa)K^{Qx!W= znfr(*>Jj^BulKJx|9Mj*SAnaT)jr#BA#d5;ai_EY}dkMyaP#iu$VVsf^_#PkekLnH;wIAQPJ-IQ8mtkbbz zCA;_SMFtVWqhn4UU=4-Vgi(WC`=@Zl;JdOZ#n8|Y z6O;R})?X)M2xN%Xnk>uafUN!grP4k+@VfsZ(GNW`$MfPp%h*q2&%SMl-+4w z{QPJ0&lg@`@kGt}-2tGF%mz*)6-9jPV;{4xc-hPC```b5KJkf9h(ebLCF@Oj{vCfH zj@OeNPxz^P)QjoAUza69DArzo9bf)mUt;<4rM&7@=kVHdU+?L*7AfJ9i+^O(nSH$N zymO&w(`>i~JdH++ZnurZk~AW^-HsF9$x6ap<(CI~Jz8$u?p>Sp zN~8$cwsQ|#w(aD|HODeKJVx5-BAv92C=MAK8gkVaV`;ZLv|0l$s*uVplqzOmbTME3 z+BYc-y!-t35G5f7>r=h}izWyqc~KBY4Z2aR^2QhVA!SAHl7PoCFGFWic3Fh2)ky z*0E*V4w9rnnL3S-mM}3fL8B3p7lrqCfV7)4Hs)F$I`(=DLBd@dAK<4~T*Zg~%ZD9n zRSBff1QH7WAR1!`0w?4`mqf8-aCm@$(FNT9&~~haNCk}V*-M-Zpe+PKq7;;-Ac_)- z(l~8}cFOFsFoaQpj36s=(ljNCV%pt|u?36Rz1y)MRS-Gf4CB*G1pAbG0LpX4^r*M8^rQ`m^<4`Unk4+Pp`;U)>=k&9OtKT(PnvIaGGtF7g zc@~#l{3DBYvWMEpdrnj$2*Z$@Z@Pi6f9;<*^UO2(%x69$oVahmmv(!M<^7KKAVhml zcoC6OKC0DxUTBhLgU^5d@9gx%B&!Zz$^Z4Ie=3YIURrK28ov6K|7Gvra38<@-rpdb z9;X#4D#E4|))C1}MUH{WOsJ}}!_%p<>^}~4GwfdpIPjtsg&}$BFo{w-se54r4{X`W zgPXUoV#NwZhlUs&90Vzt?RF3fTFnF@9EdzUJqyC6f@SIaVzp2-h8OXVU;75rX~`Sj zbRJO@5Gvv0F^95a1IIY6i&L6z)+Qbup)okZwjH}D3qurygkeaQIl)&Lh8UZ>Yl20n z04d!97|4h?Zn9z1{b&o@9@&Nrgm+&PELgCJoxArCB@K)Lp#oGG&}pZnX^O$R^d}53 z_$bmF@<=P|D8x3H4CcM(S9ly?^Q)l((Z|!lV9J8QX29vE9>;h7 zTtq1L`)lU9losiF3%f~+UF*`gm!i5)JD5`cOF4}bw$f2CSCj~O}AIMx=KllIN z`Odd#Hk&M4wv3m&_$3%!pgf7{;VoO(a{mL^vdha~bS8}u0!;0|RE;?jBPSa|&7;H5h$SDN`F;}j=k@ff9&qsdyLnKLrk`8bTf&hf^!asqN<%5t;SQUmL zCeJwIj5FAD|8Cmd4gfQqHgS?*jUbL27-L*(2_NQKBQT`}Z7{~t&2pj`?%S{lkgi&W zrP*wP(ag-uxag`h#BqZ{8#h&m!kP`CFG%r2-OiZ3~)z5!6=l6v4X`Zmez8~+VO`ACN z)KeKA9wyJ7E={T)d$m$vABx4~Ni8DtyR`Klc=xc}bkmKDj*jvh=eNHmrg>zgFLe_1#pG^<# z;91Xp9%Wt-$BMWSW2|Lnx=j+rghEi}E=(Vvnq+Wr5T#t`o*RRW6E3}KEoo->wO7A} z!B#>P2NXrN|8e#SyQE8!kqCx|TP#=@aO>@Nk_-$n+wRmf>nKdnR`^uGGkhwdpcKf! zwK14!!%JWGYIg40M`0{72ERfr*BW#_P+d{8 zji1jd!VQ9e4fkzA$&jL$+n1+*{-62diKjGk-X{cko};W`WO#rgYjfg>M{&^)zGoeA ztf~kKM;p*3N(r`X*@Cfxk&&@_Ah%%xm;A#1+uPpaZ%_wJ&d$zq%T3plwlm)F+E$Te@^bh&q;2>$5GSlujoJ5;By@B_e@4gkq*s|8-RLWv)AuBXWdQedGTCM))8gl;# z%UYM-rd@`b5zl?rsjR#G7BX+nkE6IbA55|TKM>j*?^O%#N4QpQ6mrhd|k2=sOi z7rwfS|Gn>hpD>6y{j_H}t*0?H&Gw2buHeS&ujBMn*RXoo0wQUlbp92l>~Z{`*iLh> zW@E0i`rP3bjK`$WOMz9Ac9x@6%&qJ0Vb}O1FMHK%*s}FuhFSweL4fjp60@ByqoX5~ zSxTTHCdQ{|G#a#;4M(bzA=90lpI^Baq6RN{#VctIwOm^WW5~M>Y!>vYL33+WPFG~| zjFV43nW529?zr<_1_s8Mp6L)L&H9=(;)F6UP|~+75D<78ytbBHm*l`Pr$39WyY|pc zOSF*$Q9_pG437@6ckk{R98QviAWE2=c24sMx|&NUjrN;@ z`>+aX2!dda#_5oq#}j?ye7;D(s&jg#%k6ipCk#X0`ObF=Y_CL@Wd*m~a*N%*Z8xue z>5CX{Mnn?V*~>am(b~CP-+q~6e)q3B0;yi;(;oDvZ&E_04I)U`Guh$0-@ll5od153 zfkF1}-OZwfV>IG~LR+K?di{2VL8yT7@d-u-2eHWGy- zI&%%1T_r}<^I8e1<{Z1UXj3q>crne^AX~SOQ);)fce`Db3eZJK90lmIbnPVi@C&5i zkzKpVO@R?GIX=a!&Ur0YUVROXq=iL+2pJt6Wol}w25W;LV0d_#*-n>EntDmPKRzGr z)c23qEY$N{$tPrhH837DX`Rtk+UYu61WTkK zk%HALm+|wYrSHc3)-YP&{H!dJ(B*;}thTNv^;CdPYV^ z85|zr>=(VrpPY+OHb3wnH(!4pOGgtM3ot?H8tZ>JtZlPf%*pamX_8p8vd}Wn_Vg>%92&9Rp<3>a=DoN(k3Y`kYZQ&W4LzRI^D!C1<& zVBx}rSZmqx&_nL?D~xL%mUpPeQ`61}Q8OPUf=e&G)M~9c|Gn=8;bh3tGh*(&`z~(1 zel2I8c{+>7h6qH7lu%Y|%R>9foA113`+lC*;Xdjx^nj;1WHQ@ZAPp5q#`RPcG5{$t zQqe61kL;c1-+uTr-ud1S5RZ;AK0eO$&;Moei6(k!DaONNGq zD2*m3K|>=%NP>8*4GPWbx8vY`Xs;WRQ@TwkE;3 z>*5ys{|uv_choXVkdD^VpFY(+Q~M~z6-cEj;+t_7xm#+|(l9i(n7{eEFEO@s z8Si}ed&s7ynVp(s-}oM)C?E&|B!Wl z9nWeRzp<`&tXJkrDUm=JNG8W8`TalsGydq$|AMiVN6^&;d1)9L9tL1$YTBn{mL*G; zV6A0hVglnUMU}pzdSK=())o28lM&NAXY~+B&h0CVYwP9^_ zqa6r5>rXolMpw1@=K;O)wGh2KzVwTVl+rU(-L5HpxyP4=BUh~^3KTcrb~}e1zKV(QN#`LVAr2D)<)S3vBO8lG z$llzz2&^P4au%&Tio@3&$L)9CMKsvLU{O&-%iA%!gE1t{1|wsm?B2B(Yn^(yC#38x zBo%?M8g)t|B{GOfV!^{(A0Y}IMZb5=4z_mcKW5ZDkmf8TZUjL>P43|ecp@7P|Opi>b;tDi%4K2P|Keun~TvXW4+cI`Fn z-Ls3&e)hAXC=Fqy$VD)*cY=-gJiy6o4(Fs*%ZSM-b&idIK!6lAwYgfI542+T_t)(= zd6`Q>>aFH;bQ|;L&Qy#~qyzP=b*sAPE>tGa&eIiSpeW1IsawMsT}s+r!}6m};cx!o zt3<7Y-}>-J=*~`K1x&SPF-9}gN)W<Giypfs8=iI9PyEZrhhpQ8sGt$aj(x7DUGE|7+SoXnOS(`kw=*B z&SDg(C`5&lWy_aP6uC>;q{L|Ds=ZjG^hP;K5l52t_;x<|sXyhn|I6>OXxVYK-NDGn z2&GP$7~k!f$E9KUq9sJ3>#HM0gt1i=WnBa%gm>Jqo;cX!ljM00%CLCR0QWy|k6T=9 z=-Ijc>h*~*`^%%xG|!R88dWqVE8NZFTh%=DKW9n`77R2ve$CZE3@X4feeA-oWVCAlRZV`|jI2#Z^~b zWg9UZf9z2VH6sEvf)cAOfmHi_?h`&}+Y`n0!sA}*)BpPXijNS|VGPoeW?4;ms?sEF z{S7I+vzk>P6hZ~$c}`K}v<8Ox`q%%NjSp?*UGI4(&1M8einW%>$!R*XCBkUOg%O6r z8f3+84FaN2ID149vU~47zW;-ZdEWD$$Lr61J?*J!@~lgs1c8ub?JhwOBZVR_HKvaz zB5I%#7bSU&ClC^};l*d2&B#d1^*7zb@bCz;(=)gpIVFo0E%Z2#sIduwLdn22Si%wM zjJ1Sez;P!Y$MGi~#}!xnoG40aZbGZoqSJ9I?4rzw8VO4eTfw&NkD$VcvL?w@5tBt) z-;Y*Ems|S#AdX|wnKoyh{SvOc;#%j3UpT{VD=bzxE64r?WB#uGt2BD;8+w(`Ja>lP zN-2WC6(Mw)a@g`EOzqpnrj2)5kVsT*k*T%jgCG8o*u8fTYu2o(`6AUg)N1G_9UoRM zR&JMojT<-e_h0y1Auxo2L`lbs*tc&V|MJa$=A`3~;^gCxChg9m%ZxA(HTK}jmcg7I z<%yl_TnFvPJ;^@&rRU)w=ytoV&#jz$ZrXwfR1F?G$(W?jme$Z9Ml|^1S1zPL@WBs% z7@cPX4#SjC~L4~iN=t$8m|9KX=t^YND)vN$*|d5KUtO`Rmh6NkKnd->uV1TAuYP^VKaVFd8Suk zp6KY0oTDfr&vUXY17Qgj1j4X-#Zpc<_6Y8|>oz7QCo!c{Wec3Gr3?hGeci7SMUk(} zICCd$_qP%_=*Ry=-&idil`n-0uhyogK>z?C07*naRN*UM`6sb-$?{&6L%SPe$M!93 z-?D{cRxRO(!4+Y$63bymdQ6LqlXmiM8;`*Zw+T(q!#5*U%gsA~%*sa{#PlW~S|;fl?D-S-ol{ z4?OSyaU+?tkW|;h_-IOc1#}n$M1dsDIvjb-F+8;0V5Gv-(gWuXr-gI37ycU87KFdT z3rc@_qqVbVh~n6h4AYEI7*;G<$dRj8vF^58*|qBtq!I`TWtkC#PL%hfAO1+xN@?G6 zMEdq4&zMN$KnGJ4uGgpV6#}F)C%Wp2OYK+_PB`K)7L5+m?sh3`KoGP@yIo>GNlK|+ z>hUB_v~B_67Yhq@saV*)6O(u=KPOm{0&FP}RyzB_M(n&i1cXuIf60aLuK!1d^d>^x zOf$S>C13u=w=hER&Ue0(_Qa$^(s6AYq9`EirsQRT2t$f8BaS4}6hu*g6|Mz@mJvU> z{2B`2jI+)nY=#(}VT{Hqr(bbxXG)SNq|7rH-dbI|-P;Nb_IQ%0%FrnCw9A6SmeUw$ z5f4hPy5VM)tXN4W?IJ})9K=+O(hH*zN>JDwBTCA$z*=WY)J=23Fh+`inaLSG`QQGM zkN?+CGcddmV?hQX3l}b?-R+QN8A^iAGZu~vGdeQD!w+vm3g_-wi7}mObuOD#Sg@ub zZO?MbX{TW&Tzlh<#LXt%PDTjBELP|<)nVOy9 zl8b-Ls^tqg{;1Wor>BU62x~yoqs>`zybnTW>DX@15H|++!H<8+*1c04w)zO3|I!y@%apPx+ymtqscY7(VfCt` zC`v<76hwg{i6c7g8NyJJ89@{`xafx$Gd!|@H@^8zWBolC5fH`=$}*o*IdSu#K?tHK!dN#ao!KsN+(2th z5W5x=XT0DAoN)39T=4b(O*}YEp)I3h3kg(IdyP1aj^ViDj-lIi&97|fN|)N(LsX+8 zE*j(X9-$Nzomq}PdWfsmUQ5&(A{iK_(@s$;a1Q4_VpN{_YJ4@&&C%TZ;#YC>8#TG} zF<4!4U3kyb#ez+`tDwNo^$6N z>sh&CIY%G4hA5D9+OwqH4rq<>H&oS{@u}o%W?l$82dVEX2hMj6@NSi~yR)cJ_AMMe zF<1qxT8mSrst^@6Xbunaxxf1&Mg)B1BOf8(vx_89Bwx)8SN z5u*!EIr(^ohK9K6>R%AWEp#c6qGB8ytT0$>>a?PpWe6{>Y&2p_>B8%>ENQh`%*@R2 z7ytb;eEEWZWhT=EjX?@y7#ka-&?Pgo9aIp}>1Kdo%@L~{p-uLr5cr;BU5DZn&OEIReb# zhp)hxl9{OqC<|Ay!0q-G7V+4=n~y%Ka<8z$8T3@2;kR%py`#A&V);g#2qBoA?GVSY z`##}1?8%BmXPuvGW#ZFK3zET6{`I>*pfr}U$a&ZM-b-2LWSPTGgs>nL14AS3GmIgW z3S~eSzKks;nKoG2;G!R2M%;pTo&Ro3d)l|dbofkvlXB~T17D@H^}khy&bUOwR3^5br-@=mN{B$&w|u6n+=AC zhk5mDU(WyYKfgdhfEJRW;Q=t3*-o2oQ4+-svMeJ>VuZAH*;0TjA^QiQYGP0m`-G*; z+njXb@$A|Ixeh=^Xj_u!9f~p~h+>D4cruzxWn^9c{nf!o=0^p6(TDZY3vbM9iky{) zFK6kJVSak?PnnpQpeTF%n*K2lftvR{2Y(@XYM;2@MRIv~QD~&FTzT0~?cxPZPC4;d zvTmC!?Sj!Yi?aq{*?$_JNNQt6f7ns2X8jCQf5RHr8q&3jl#Wh}APQo-?GBBkh4J4h zss>q5D@TQeq9_qzf{2>@?8;xTZ!+h1Kl&j^JCwO&e-^&moKnhh9e^N^4q*q9D0W;E z0t%xL;RqM~^g70tFXa`ldO2Bp8evP<{m=HBG*v9keqO~~K23E2rR@V;g`v>7)2%cb z9DVGuNC{V8y_TWj#iV)e43K&%L#z=<6mbxN28Axp=4`+PuJ}T$7Kq=Br#{sy49_v)h-7KuOU|ib~CBPIp&w0*su)qyB z-cECHkfJDvlL%85bkp2-kdr=-blmt~R@BB*?oVqi!$VCD zTfTsM?!AwhnHg6Mupn!l%z;vso=@8pl5`=vFWl3g8J1w?i_DM`|Fu3j4O-VVxJF}l#(xo$D2YMvlpTE`C3F&<56Doyiw|Vtz&cTL)E3dhZfx(4XDZMAE zTcDgU&WX0tPM6T9Llp<1A}%Qu8jFlWjz94PUiq5Wa^W|=MMpy+6$3+qEL^ydN47rf z2!|E||5>)`D~r$ZZT0^Wyi->w71|W!dCn25Rx>aF7hQZYMk=gSVBLInv$T#btNEE5 zeN>CCeo~R`FKawnX}Y%|NU#q47rvj9kWl6wjy~dW2Ah&?TOPz(jj`ILga=4(e_7{# z&=wJgu9r+rj&t9J%`99n#?fomP^N8)yn_k^GEk0#p{n&(Aw}>wpZw@!{v`Ex#;Z-0 z`)vlKGeZ_ilIN*=;Hf(9fv$Ic=k;olltv<=Cg1wEe@BaelTJH@V^2DPEbEd)P8(xN z$0bqTMoPMQ>jCJ92??KUD%K5cd0trAg3VZDd6 z&&J`Ix0cKq2kLVqjXO7Y4;!#KD_1OH`NCnYz3OtCciPlVunrL3{IdL44%#AOtm8JU zz2-^=Vpz3eDa|CH({>Gy8gb&~^%^A)#0lx~Iv#I`10=n5E-zh~Sz{?}U(;*p7@0v3 z(e-6%Lv7Zdtd1^&2+x@XnM!`otg7o|qsAB|>VXFI6fL z;A5e>Mo+0-i0)nC!=%CHE!((z(*rDAvY3;e^(?YZn?R{rx?Mf6(9eD8Ki_^XjGXgc zW6ItRuQf>+(V3oR)zL??aM2i@+;Gbs>k(ms^}S<+aQH|?!Cty}2}-%P1X4L0zABQ)k^Z_?FE!9;Dn0H$UQTPsk~ z^`*_zF2@{m3^N`0+2vQ!7#wy{VVKbEc59<(aNLSA%N=nJ<-z6o_lHlRpXqo>UxZbq z=n{w9=_2Krqt~!>(IVE}b{o1Z!HBxrd7#L{2bs?dve}$*faB4|m3x1B$;EbTFy^_Z zoQN$_vMh6D&M0y|BUK0s9+|IzwfPUr;~co1`}gYqjex>O9bp*OH>>N2pxC`+0PoOyJVVEm$A`IlHBUG)j=oz?u@d1OQA99^WG zcG_vE5Pov$m4wM4g%N1!7Mr3pb&=bmnVcH0DdYl0l`TKH&V2uI!$qI2s#JsBRhniU zNz#;>v5^4|Teh4#@4T}vn-{)$`};rm0lRJ6Hurh{-YRv;p*A-^c##Mett}hxyN^YK z101&4ribB0%oVcSjoEe_Y*V+Fg|6QnwmidAwo%_D4^YL0q*Ol5un41{5Musl?=b=p)+v0urg4p7i8t$pQb4i{OiBgUw z>Rj(c%?p?d{ycU$s#-|qFDQl{Q?cs(+Uay1Wjl6)rZ9@wbpL~_KH?~}Et%Nwue+D&**2%2ekvowErisrTw8b3>H}ki22nCNI7qA2!U{tW zM`#O4V}PGsb|o?pyy-X2gDhnriLu%#pJfpH@O5rgrXHR*aG=(om3E|O<5;n0wM&(( zK!y!od+s@mkB_tV`kPTGaM9!t+JXa2Ez zd_-H0KWa5&Lk+IE`U=31byK1+Vq|ETZ-4vS;;y^y;tOB+g59`rV~?NnOwrEl_iHYm z##l#^+O*+bA_2#(UWKwHMb<$oTu6;2D{{2WF-F(CjJem^MH2^#I;s^}TG0K%7>^bp zEf(QKTh=l;GlezNyZj0AuSAfSqursV{Jw#9G}N{3Pv0R=%VWu5n~C$21ZM7hNC>+ z#PWu>zm=m;Jb}OZhkv3IjIez=CrBCy3~EmM)#~Dwo|Wq)cGi@2Pa$I<4kb39<@wJ# zg+04+)*SO}zWKc$5swVgYBjLH)a)!mN{TFJcyIu#4Ov?F>9IXLq+(wPr!YTYCFBWa z(+7jdb|9KlwSgK0M*0oOiA209SAemSqOhEN{821jyoAdyzsmJk4g|&;!Z>2(%GF$W z;f3O|%P!-SpZuh)1he(`J^jPqZ#=y?$KhD@ZnAybLpF)vxMPkY&vW+e9VbefL}5bO z&HK9M^?;)%J1Tp?id@r=`d3Y*yLrac)D(@RMd0)J>D@aS9D<~!kVg9ENQ!p5O{+0L zV1@Il@R?{kGhB7;P3+z?$;!hQ3o0*;Mpbf-H)0Mxqrqmi;8TCkN-Hh^SzyU8qAE*rOp{b)2 z;pRCja-M(284L_WOwM+>_PU#C4vZjFfW^rHR1lGun#GG36Ni$S$tj=G2nwy;F=8o9 z;Y5wnmAA7jqf9&eOBW@k)Cg%9TQEwuYnYjt0q}Mf25U9vobzj(e){R$b=O^d^}>I$mP6Y% z;vl3mc*icok1qN?3r1V4IbtPgrvpg0d&M!`Ji{7+s&pM57jdb9d+EuP;VRm+5ONN6 z-U`TzlG)idNzx!t5kU~}$gZ6%Sw2ELouxC|Ve!I67~}AQfkqQu7~;^;tE~#y^zaUL z?rSqSqj~e2-^}90!$?~&zqzv8TOB#b_{d>m-#FcF7i|quqe(I_%%xXcMWHRPfBoy( zwe2A`ZQ8`p;-y%r=wvD2tp96$Ne$S}T|6v$uD@#EwWwV4`+Fu!Dane0BuVJB+x-5= zf0xO2#<#xveS)Y(CoP!nbdgc))WyO%mL*Zlz4vY)?UqOt*WhiTbCSf(lRjV}m0*NlG(6$XpyoU%LfBsKSS&#x(M3+TGs{UQ98VO( z!w+wRAm-cub`gU^BQ%>$+U+*&b{i=aX_~TP#R|4>-|pIS`bvlKV!uaAh5HxVXU6aw zK%b)5*KKHoA(4_$W~^GVlmNJU-JMvg>y{+VW|JV0eCbPH5_jKyH?#=h&lGqIJQ_HEa0Z_b(9ph9d27@(D*XHYB<1(x2HlssL>1@V_u* z$&w`;ee}^h^x$TG{_~&D`Hq7+v(z>9_RYu@jwChE zXs~?wa`Hk`A{>4ZHJHr}cW>Cl@NmEvzwozw=mQ@hPrGQG5t76bN#R6*RUR)YA>iB- zKM-Izf6Ny&x^k+f)l4u&!TG=WCN^)~#&`bxA{MP!$%|j|a_+h3UjF%?zeTPMt5>h7 zJ$1{nM9F|a0=mSOu5+F)N|cZcvTE1-~AUlWzJ{+?u#_WmXI3ZT+@tm zi5Jq4r(KVW_4@i49CKJo=Lr)ELEdij(igpu>Dd$^1NKf#bHx>xGc>keg zv-ZD5aN3eIWuV#eJOl`Y zM4N(8SORH?LqQOQSfwaDS?!WbuO=%4h6YFZ(ii`p;h~}W{41@EOO13*7OMfL1Dx~Y zjRU<$N=cdJ3=K4S+gsnv_>|_#>u(}6iYRLGv5)>P`}U0UsZV{12Of9;g<#!X8<0v- zlsUR^E^o#_q$J8Z>@RC~u%*FjjRcA;g;4PqfAv>fa^)?2>-!f|2xs|#6im&`BCR1* zE8660f-Qbstuuw~7Tq+nR&QvQ10>UulxZ{o!Q&SUc-n_Z*yPhd3-o9b2B@AM&U;7Kn0$%>&vzVTm zBI|T%G-Jlb#>lb)tP|jkkM9GV0M8owR^7)N{VQn2$?!Xjb-zv06@H;T z8S8Oo{W1S_{{`87N23ulH8sI$Cm+MJo^=!tZr#b1*W5^)w8*blX)x>O5VB*h|Lzwyp@@Y%onI`?nig;oKD z1?7o{LI_NmyQ-3>!MlY+A#u)JfrQTN6fZpMOtgkwyLNHbS!c2K##`C3bDTzVkYr$( z$*CECFBEtx!QjrnRoa72Vf@qd*o1?Rkd0z7A;zY z)-XLafx=RjE>#r5v9(V*m|WciU}}DDb$-c%4Ls-h&tbvn5OEM9k(i=%Wnd-9J?*;6yA{qAtkoLC3WW?? zq*`*xWmmHHh8sz9c-!0FMwaJL-VNQaZtWjsSu!#*grMZZ zAN~m2womi3%hzI+3xW4;dx#I5{~rFwfBy?wtri0f_~IA8$c|k*>7+T`++v8ZxW&&{ zS1GVM$67;{r*ykrn#}?BZQaUe|Kaa>*7Hv0qkr&!vwK#P%NP+Qbn+7GyZcp|9mlhA z@NE?>SV|fVXB&Cai7U}sGdMiT!@Fm>?3!z_Dxx(wOef2jneBLd&5~sqD_5@cKDoy6 zS^97g8K^lp(=UJYe`h~1exUc7zQ0+7a#)usQ%*YWXp#^vzwATHZy;kgE!3rXvS5Yq_3Id9vfZ$c>y#zu_NCN3S+t1l^o-#APKjt}QlK>&;9bWrd zHha$5r_Ic_e9B=*9M1Uh}Z3X#4JL4uyK^wuwEjzgU*Vl68 zZ?9#bQfBImZaTZ#uxJM{S50$nA!NgU$ID>lyN{N(xD|Vq+3q?)gmjClLa=1fm=+V1#3x^(j5HqGvrMtb2n{WIRZ+Yw6xZ(&WM_XLqehPbE2&hfc+w+{Gw`19$mfa;Tgnmi z1goV#%is7uF$HW;B*7!G9w`d4w5|?5(^wK= z(V1GCNvbS9>IkaChIN}Z^Sal+na7`8&BKo^LxnlIM~`7}piC`}8Vhk8MdWk22D`gn zKQqQ;5}D8_US?@A!tUMz{ue|lBO3^<0KDv8y}+Lo)}e}xG3d0$)JfwAJ;CbLs{t<~ zUD^iz#`k@S#UeX*?qu`k&Dp2y0rC6_&vBm?k*3b7%@oNc%a$!eO2N#T(e)$WD5KSMOI7-24d|%=DGV2Hkhgg*!Rv4nx>44OtVMcX# z;s=UKt%AYQU#{@jlTVXsIN*Q-m^^MAHi;V*^F~OV6}z-autK5n@qz-YpI^s4_dUSc zb=#RVX$oKZ%6V+uw1wUt&8erJ)+iSGo*MC_Sle`Q-PbI7uD7xy@13xXnV1g zXYsL%$QOMce*7sm?<^yO0-g{gwE?C~97ULe=hm#|qDwB~g71EZQ%^gYKmPH0-u2%1 z@wIP$n_vCvcRaIv9YL-GKWs;Oc~=;1a6^Mi|j#!zID zVG*Nzkg9PX-NLR>flq3z1HxHL&XXLp|7>&&!<8yCXYPj=1l)7~qiosHzh_z;D zu;SR)#t?db1Ke0g%32&La>TRO!nJY4x27}SziPa6#NE1>wKOpr8;(M!DRXAcqCH<^ z>7$Q>Xd17%D9c6r6DCYxXlSV6jMw@(|E#f_B2eoE-u2(z3A9wZTR<#b9qpv4VYpf* zG>RYy2m;S}f&yWfr&ilZp;$y~?XVr%?Z)-{wfCW86ZPtfeU7*`TrJ~y9))5qlOq&( zex7yfHxXxsO!WxFR~{X0?I;h7@JOv>pi<$1habZ)2xiaTkLlBS3XI` z14)g+4}4^h=XZbn6F;)e7B5~*N7qpdQC7ihU2qsRQ#-_C^>FVx4TBi~xrBjC|Yv(`sX)@S^ty>3xY*u8?Q(Z~0qoa+%!9n`^ z`Ya&o=MOJD*I(|~ZBu)p4;|4agN6W*F$M(OfB*dy^NIsz&t_<#4_|o{i){=?HKcOg z5a&_jBmsIHMln=LS-W|F&aN&FoAsedWq z2z(AdAraQnSt@ecDW{TeEAo$fA7s;xJ`!t4)0EL&odgPcw(oGlL^{SN<+Kx*@R1L_ zkIR1YBR=}kvskryH9z|46@2-t-{eCd`4|^ma1r-Ex{Pqtc)~H`z|SFrka8{Jumy*6 z{`bDfA8)#gU;gGg@};hfxtt;;C<~zwm|D$=X6qD;!4sN5TISC?fbCnivVPNAj(_cm z?C3Q-@$^c12P<@Rc7yaN4-Gf)AWlA^RpqY!KUo@S>s=ew5HqU3`2R{3Y)@n4ozL)9 z^^_|+b|o!BN9;FaG75NZ)$`=SuqhgjyVs+;#~_4YusqbLyS19M?JAW1%8&OYM&pmt zyvR}FAlrk3gBSy&MvtaaskksS2%V;bP5{$z_o|2Peip9Q59Q@jmg~9;&bK6`T&)o1 z0t)#O#wt=g5-VB1c`MZzydb1hY$sm`2|VAm|9~LKQA-UEKluz+!Pp67nK5%J(i*fC z7%Pblq*h^6K(T8K29HaAcqwmt+yCS0tFL9jf(88g$}3oK*dh4RX?i@rZY{k7{T#RC zXfQE>@-h$O=Ge6+(pXeqfG4vrqYk!G2-4U^hV_ontXVU7{Toi_?gt)b^|}oN`8I|s z!|XR>Cepx`4I5oFkS2tl!X^=2o$V}IbQm8!=Yw2(?Uj7SkxG;_=mW}t zG#20Uz*vWY@CC;myNKbTnCI6$&jE7}WZ^M~bJJh{!G^6nsilVf=gw!%y7lC8g(g>I z*TvZRfw(ralEjI2EO6yewN^Tw&`7f2|J7*0P1P#~a-@E2ofcrz8oD;f-2G<|c<}h+ zOOX;xR`-%ww{Y^*DWqviPfri!;R;}ObDeyp<7Eq+x`hO!bZsQxbs4iTfXZ6hB`eC`uBo zNlii$YbX6DAPDnp?JraFI(TyVN>X6Pj2Xd1P2O~U55M;3Ama9G@J;bFP z|B78uSTNQgm1_eUqwxZt?$KQ=IbjKZ{__po_ux|I&7MYQzCc@hC(|a4=lRvoWdu1z zni>MnCr)FmN$F?{DdZb3LQSjb_2Z zqgb+JF|Rsq2_HP?qYMt!xZt~&5(EKnf8)uhf}$4H@PsQ=2cAcHIHFK$!={FzC}qz6 z`{60rxNal0T8#yZ7V@L}mvZkzk1%!ezagb%{KUy@+PaB}q$&mJ6j}dA9jTVkn2B;m;!4v|MrWgaBR7hhP)73>7z^2U` zTsDKsI+kwK4dT4a(;1o;xb<3GeGcvO@iz|oC03>ee7ZHCq8<&nD}UN)C$Xc~Sq8MV zwK?S~WAT*}4fd2kHfjKMfK~Gj?ak!b6&ml5u#z}&F#ERlBB^!;(E0W@ZoBJl+PbJ-{(XA5AHjBlHEOLdedZ?bPCgRnM)ZT!o_+EhbJ}`WARF zqFviEoH+9fT!U;!-3_9hDTD7icC+J_{4vGh9i$Uj(5KAeTh19Q}iXAO%WE^7)X33lCuP#?7o*vxXB+colOGp23yZT*rnjJBUz>89Oc`VMeG7 z+}^O*$UIzH9yqpc-A2#OUg9{V&i-xHHxWWO_4WE?{3iq_drSCh2oq&*_}0>0>SW6JsXY74 zb8OzalS7V}%W#@dEEd3~cv6p8uy8_F?9to!_W569|CtBy{Ho2YeSRHx-gYlv`104d z;`e`mQDZspvS0Cu?_b96?t2z7`CvNd9Dx}%j<`^uYrTv^5Uge+nD6R(SI1 zXIXO62~3|klb(LK{hkL%)0iZ!(b>_Bu|5W`(GgQE3%AoSu~;eT>m8sxSV3zC9yC^g z@W48y{Z!P6kXehr<pP>uVjo!XI?6-X><{UV`B!MPvH3( zz)RstNfJkBlhWBaI$LN2(hrELl?MIa&uHIuZx-1i%`F;WnHL^)A)Ce|F~;T3R#V71 z&tEGgD^{*z^!N!(nLZ6Lic5E)H5(yUs!4yB;8y&WBE-u~}zbK*^9Lea; zPPDc7UO*JbnPo-`F9R}>pOKiEy8Xq-JF@SwwYAp4`%^OulgG+o?XetwVQd}>)*sv%bwzvzum?g zPdfqW8%DQv5DyQ#UYN)v5(Jr|T8bg>imJk+T8$`_bPFs#GZz<5qZM1HMC z7A46GLhKuVAp2H-CX97T_(tQ0dHVbNS+r;&p0aG&wh?Qcmyo;JK&I5^>X-)V+B7Y2 zg1TtYE6LbAa463p2u9HIcOAR6g^Xq8%9YGH@Blo|BS|z?8~0^3O1kjNT0y>4V&k?g z_?i1%y@05cTX@neDse)~dvj-6PTOdN@TirCD1~`EPf|?`iG{l#c!;2V937oq9rut6bF5ggg0s&0AW9nIisr~8=5fj?r||KQe+-16 z+&@62(nle4hRX#WwIssx-SM<{ci|V?czD?|%H=^0m^}kuN$RozR*+d{G_I^mM+9JH zrhZ{t7LJx;Ykg1J$2;zM4&EkZL zI@;PBZE>R$RF=dW1R`r0*NKDxdEdhtP2Tq$_z6vAXeX%_EIRUF794XZ=YQvGL_-xG zTDp|S9)F6fulxtE4#_-u6#XWc&R$ci|PS4f7;{w%!o+SwVy?6om)*AT=BM}K?LMAU>V{Pps7;8BD?6d6^mtXEwd5j=RVD{`e z3=IvDCQ(N9H<{I+d*GBGG!`Ih-9#}N8}{XZ&6-#@OOVTBa3NV3hQx7-wvwk-tYXFL zH5|M6Rg51$kuF4>zw=d>ZuRWd3J9-K7IifV8Yt$&tc;`D= zy7WG7x%E~)e$Gc2>gi#)zXwT5-j`ss69h62^U;*!6Qo)YCneH^oJA%!5sYDl%g z3q8y(TaA#mMP1AN($z-~Zl4oO8~H_`rwHWbxu7IpxG-Id7lJH;Pt%lQq0RkH8x|aS zD1}h6^pQu%<@4CgiZxA}NL}e=R-4)9)eElw3^n-1%8_OkkS{b^i!nxP?!Mj!4gFImvQY}|pJIY#2VhBpUBR`qcxuB_i+frr5_(VEFUuq532s%1C zkY0!+VAa}<#{4nkNGlsem}#D+2BMswjM zKV-?PUj^|nmEJz8{eAdKP{_GmJS>)ot3!>@7eHAFLS_Xp!PwDbcrty4V-_7v-~}W} zLa`8{bwU)?2)(d5--JVx(y-6W{<-lmiN;R!%7RWB$7_YVUd|!{taSF9wMv4AlX{MY1Cqx3yBcT$jJa$i}X|mId|QUk_t$4?5G0@ zs{K2u^={{)pZ$bSp8YYt_~kEf?k7IMJKp*R0+rHTd#O@1@u)9^qNNwsE)6%0{E~C60CQS&lNMq~fE!5Mb zdc(n5XXP?|`gA5wo=lo(r03AA?sqz?Rqp#}M9q5>iPTr-yY9RPom$#Dy0QYPGa+&+ zQ#D6=vVu5vHWE>_238Y#K4cK`U0a(k`>=&=?AE@Y#|uJ&ut+V{Y}wJvBabd)!j#D< zCAsY9KWE#v9jxEDfgfD_Berkb%5jU2;Jhz=m~Wl`HQx2EchNskX7>IwS#tc*?A*A9 zq28UCw1yuDw24U42;cW94-GUrO7*!dgsTs@vX`Nwvq)e6PR5NNOIv%%8G6Sx(l{a? zN!ep8k&EmLILlo#lW3^~-KYS_3`vIf|6UT%~&=&d(ZrR8W zesnQk{PO2H|2r3P^;K6gJkZ0o_0Lf0Sxb56S~jnGf+^j3PCR-JfBC~7_{U8*LE!WH zH=ItXvy-c?yO|lY4UtLdciwfo?eFjB&_fRuQVAY--~pS< ziH5(eu&$Eqc^-vAfmFwMLLk-1Ft5Rvc$t$!TGQOfrL(Cl~`^fMfM z=poFTKaUT8AN=;$SMu#|euYy`TFj!O4&$-M9;2FDnd2Sv0!wZ=NTawcj*OI_cGPcD9qGRiqT;LLXA+ zF4x*_Y(5i;fD0Bx{cXD%jFQAm~x@p2g2t`z@VYMOW`OZ9CN-&0kC+Xj~ zh7W$~qg?!x@AAtlui^UN-#`>4c!9#C5v9OmLYvS0*)!R;VGG-~Y-g~ipLf6e-AtZ3 z85IhCeEF~O^6kXNEyzY|taaT)E0i?`5DWAuY-isK9q!7->;rWJL2qx)(1snm54R zC9O4KA@6)-3@m?cJ@|R%&p#BU6uGt{v-Y3GhD|%!xOpo(wr-)ncL&ws0jk48Jo)64 zw6}L~%%X)541_lW)GrPA(w#jv&l`k>`{+on%X{qHL&8Q8v^5B%rHnLK40+qdL1BlK_&Rra&C0_6qSV&zougp!~Q!dT)oA<>ziv4vtTq;Kmc-tw+@ z@XM>O+p4@6me8z&g}ij1tCvA{dCLgnywTG%(&5GsMH|ALkf#c6Qng%D#L8tT&AP5 zn?nvcgt%IDZ8DQOT`P=46(Ocg>Qgu)8tRL!+z)~x;MXzwDbRvQ4J zIF2z`q@Q6CvWHC48r8V(^<-gJz}PFM;Cr5jQO+aCQ$fQtJkbvD6$nMt z-^aqEkK!knUqQ`p?h~L(UP7G6~PU6tR_T%omZe#QMb)@}$eDKWoFna7L z3S9-h_PvV<+eT4~9RjwM+-QW!%+v(q#!sZDr!Sja%|(7s*G}w`hO~~lGMjrthW}^) zzg}FH@P&lA>HxXM&spb2sLUTZ^H1*VY9~!&)~|iueVTL&kQCN+0*%QG?8OL$w_VR~ zU&n4>vzHnxSFU7eXozXkrZvcSiP3nT6UzPDwARwvDxjWCVklt~Ri5aLX#n#ZeCvI!+fQ^WMB(-=Q)95y>Y$6C%|jc^qA77|qJ zx&JG)D@KkzUu$cPqcLRvrmR64jY(5JeeP#D=9ohn*tm&&E=OWT#{ZGKAs?m1x#wBu zajc|^IE+p4Jc%DTuCHoO^9n%W*vAS7yjfjChm72=bra1 zZo7XerS?%woj#pommJN?XP;x+<_*-U6=Wd!%;!Euqz(5!@-$1Ieh!&yC$Tuwb*a(P zkP3ko3T>gQYc!o5-B_D#l*%oX4G*6e;n1|6`>sT`24sP~d#?AC{_OfbiEKPKPTWfq zM^$Fe-VdV-Cj&m zyrznpabCYtO6mk+WiiLCnaP^T|Yx)nlwfUmwv=?OxLI`zVh|2@us((!S^rv8Nd4NACS2` za}GR!uI_-Ro_LbD7BSGflhfXKI&&W+tQKAH=Fq*kk8g&gVsGa`y%kssa)8bXqT>K zyHs8H*Q5y;Lm(yAq;BC1J+#g`0y=e&YflnKRRSsS$pnqEYPq%Gd46{OBXjRPFBq@1 z5LPdMHf0zaN?3J6vAXVv6(mCyj$O2nu8tz9jtO%Llg9Xg!VeV2XwnQ^==4%GzVA65 z+9Y<9LkUuoAf!YF0Y)?#+x2UugoHFj8mBqydm+L&9B&{}x;pZlb=H}D?Bk!}nm^pc zFMf43M=V^(;fEc`0}nh%x$FRwm7eW<>-?`VR4McPhAmw8r(5V4GY)N>8l5qQB(-QO zKzam0j=r74U<9Rnso`JLc)s><51Ra=CdQ&pWD`=dV@Hp(v1kEK?#qtfnnu+-Tb__8 zoO?R**(C!@pP3=CxMfhXJ)X zA}p5B(&Nti9%1sdSxlWZ(}_Y0s6`0}9eyav_t>#>8;Opw(nAFu+;#6`%$PNkF;gax zq!HFAgz!ldoe>CKq*WJIw$`HK6ln#%@-m4>$6Pk(j45ng%BCb1Csp7Fft#Gx<);pO z7h;9V-e2$SXAf}8?lh7I^GYNFT4UvrpHq*r>Rvuck`O3~HBL@4wVEJM#BmjCorHpO zIn1I;DG;6_CF^z|oNOWrZ6%2j#0Vk{aca>f>kJu-V--6Vx92G^mZ&yN;ClpCLsBJ_ zhP?0brZ>HbbI&`EzukEUS6_1tOO`BQ`SRs#+qR83s)CMKaQMNz@$}a-P#NZzzqy8O zJ!SAh5^WIHMacDYwniX;p}`8n!^3WZ>b=n0Z}6U)o=Mue7V(arosIkGtV~)L6SLR% za5o4*ON~z8pas4X#KRT3+d9AqmOuRr0NT0|LT6{E^ES@s2y$UlDjb;W7O@@(xY#m+UZMPd*TjrQ5g8x4jf&X8IKK7E5jtlzwiat-#I zeE?)|U%>4wLCCy==Ck72Rd~5PwN$X9zf2{9Q~vE_(ADhW5e^ybXOWY3sLnWcIFTU8 zgY>AyDYeuvRE>zV#mklOawWoCiF{i(`C=Dgz73>LH8NCF7>*2DNooloeBwkq2}f)2 zb53!+jwJlojn?a3FXXzA-PE-^JmpY`CPm@+HsJhvjdcp*LP^4W9_jfQZ5fVJh7$vR z4(sJmK?%QoG==VQ+ymdI!+u}&$~Y6HDsQ-lm0ZXr``3p@{P>Virz(BDr`XhWzx`Svylb08$O zzJ8v3^a(a>*gz^A20@#YL*^gKyu*(G6qpn{T%p?AODPPnIw7CSlSEnj*!R&Rc0r4< z;w2xheIMCFF5NWol~a6kn}HxnG}=1Cpf6P>4wNHJ4T&}=<&&fuV(DEqgCu!GZ-`dg-Nn_3PiJ*wM+VHES8JRT*7qLl}rqT>h(HaK_uu zLh&G{pR}9%04LRJ3lq6A=S+iyk=5rV+T^C0LSlRSD9!ZAGo>wWT+muQv(WdDe zRI9~}?u@p=$u2eu{|@yl_8{G0$xy1oG{A<|8Uzv}1lAg-lPfb<9^p1^V_fln)~p$% zw?Ew2gzCpLYSbvkk00NV_^hkDwH8%hX*vHz7m?OHP6$D@S|v?Wk|bf#qD770MN#4i zKi1;=A=VBfwAksV^9>zJn2}IV-09v5#BWor9jA5Xuks%yj!&;413Z(=|lH!E{c`v}Eu1lk& z^X5&A#44vG9;cd8dnW{W?z;DWF1qx`JhpThNgSh$BnSd>xg1dvH`76FNW|@!nnN+i zI%V9X$-Mq`r}384-@w81=Rp$D*RzvSApmR9LQ!b%pc=>IJ&)mX1xw1LNt3wnf{Xaf z7r)BY*WJix&;10oT8%=OM{CUquX#0xEttd3P3!so4=(1qD}F}*)?uWVkwc{<%;oWY zpH)|Afm$?5^D1 zk@q$u8;|%~^%?Hy{q7mjX@beXWIEPVDi!jDkX&Bz*T3D$$3Ok)Mx@c+-p=gVv$^xm zJ6W@44Kt_D0P1rudmeW2K6<(1MbnwqXaQiyjvdr$HIg(TUnn)yFS@!q&>AEuX;MMr z;I&@hqi_$L=lkFZv>XYs5=vl&b-uK9je|^CqdA(@Y-y#_V=zu!*LqL`9(!gbYc^Im z?8rr+d@4~)KFpyEcmkqonFU85g_naTSF9$;g*^Pw{k;2({|D6?);iw~YXtc)bi1LF z7^#Saq^DBD7P|4qOylDp|16^?PUFAM{R+>n-bkr!48`_Q)P%>@-eHzMzk_vKDm=Hb zkJTG@Qm(|r!5TZa(*guTUB{kyPceA`dbouB9XLR3R<0E(Ks(7nOY+ znShZ?A~WCD?BkU39S2G{k!_Qt#I*>MXrxf2+Ta&*2wxJ#h9va}^P~9tZ4YqN!o|Gx zE$?9YvXum0fiUbK6+Zoygy%Q)uyMx_Pp@9js&$*#+B3k;-XUsQp@Sm%jxh|^Qm*{f zH5|L-)y$c5FyFiQr$jP`$agW63WjQ$sy2AOPZU@2{e*l@l0?H43jsg<@x}bxDT{e- z)w2jBTBqdv7!&Q_=l}gfHgBo2rO)uIYyL#o(M}R;d@ppEkfe%`hW>#8jDTFJL=>k8 z;UR>V)uVLwZY z6t+dCQ|%*%t@S)!a?}@-?c2B0+uO^5bLW!J1^AwO`=Uk12yon)?(S}49h0=UyA=ur zq=SCCNkU6oDT5~OeMFLhz_XXvUC?j(%gwZR2OM(vAz)HG=^WV_PV-TXpuNPL{bzE= zy$>LZ-K^Tw!*M5^3aQCp-)=XFlDMIDk{UxT(u|rso$GJ7k$i3xf4b=}w0CyX(bY{9 zr}XspGf*Dlo$q`nk3abY#%iJ{a$O^%862+g?eBe;lTSOxRQa`UZ!XX2Pi^!5$m z=krt}jqrT1O(2mmt_YnZ3DT=~H1>R*_C3FCcDj7u&sd_CAjrEyXD$RK8vrM1B^IBW zwtV@wc}!4I%-;n4``v1!W|hRPMjjv0@iFY$v*E@krcxqRsCkI~jKhFn-As=9mP2RW4I zLV4f!Nzw?dW4`&#ud(*|H4V9gFbwepba!>|S|I=qujHu!Z45yek|q&J9APc2UAxxJl8iUxd6H?)+BxoNEMLByojZ3japL4`^=gVXCovQXrN-o|i@BggL;b#?O6Ce9jSJLx z^fSJ~uA^03!(}G*9Mh?{Z?7cO4EVV`^A9-$6Ibz-dtKeED4)wgRO4;`{swON-E|bZ z$FqD*FN;ok9sO&cp|coZ)08+#2*LoABu-Lli6B?%X7Mq{^W;;@nKFG6AW5`gV6e=R zCCBsq?|+wR)20D1T&d9C-`{{0r)f&5Sma&rdKYKD|NVgBj@xhN?QefO9o^$NX34Ah z(&s+SIp>_saPLl>4Oezelf=2W6&1tfGC>f!XkuSFG%b0!fvnNo#5kmxB38~1Nwg)= z4o?x)YFJ_Mf{-ZD7;V|mGsG#Uo<_NrFnZz?`uh4gX5k_}``OQN+zH2zxNF11We|q` zfnGcnu;`eh@%_cS+*!lYM<3;a?|zRv@4TISv7H0QP2{Fq{?2blP2$&A{FFDn@f6Da zJE-WGAjl*j5m5|f71A^%O`Si^Lk~TM|FICz#BoI6H8DIc^)u+KVr9`LzC7n35&gvJw?-8hgG|eaxb#7BjD$|;NIM{wYdW;cLGH=fQ zU}63G_04&cMYQt{JbXPj-IIxxV8&;Ah09^b^h_uk9vU-ueFV{*A1apYj>%J+zplxi&^ zHiG*ec$7JF=d*IvTDrQ%5G95?A*E2F_=Bi?Sj5fKA)#p zEE2^r+BkCCz`zj4E_oGOwr=OhqmIT83ViE(Kj2fJ`Yd6w4TJ*ek)(!vu80*d(AP&k zpLf^$1s0IjuGbz%i;SYA*$JqB55o{C6j737?N$hKIgo-}sf}7y#*$~8_?E-7xCkvyQdF_Th7B8-HhnUlvLxEskt9Z=g+vQM z%^2d;>FwrnIcM+|r^Ip6Ok=Ic=1aYR+tS(<&0{bb%Q%Xwbai(kZPS&pPV)ztbKw4* za>_}fj>$?>Jz~-Lmx0Z8{a|Y?Jv}`P3=FVn(NV&&0_(kSfsoMK+l%jopqmf1gNW~r zNof8sa^-0Ku@!zSY@I3U>LuD*w1FTjvUO)an>G$3gkt@(s|dn8fuBdG0+soR7~{xs zqSVGIryRxq-h3lxp7B=FLDyxHo{v?IWQOvHwc?^nF5~?lIGa>U!h8uY$Rnl4Lk~a9 z%{SldJWk7Hq?EL`w>Mg}^#$4KxjO8CL#Rr}zp2HP%VmCZ)m8lN`Wr}7$qhICg&+O* zPw|5so*yE;kSIw=Q%!q&NA^&pz}~s!z2Ml5i{W-Q=Lw`*=n00XTE+K5`um2cC2-q4 z5AoJ_pUvz8XE1)^WIplnPjcs-ck-&^kEd1}c8Ew}91cT4qEm$ONi9@sF`gITNrmq_ zL}h)k1&9)NO)BLwpZw$}S^DTw-v5EKkfG1mi4$4%+Y0 zg@>>bB|M@e!S_PqzCkX!_=ntb^Pf2W*oByA7%&*AoZpC4^bOVc`uP`d$&dbrAlHGm z9$~J)A%`Bynzd_bYjdt*`Fx1y$t)~(9Ub5I8-g}i{kXot5vSSs*|bxNtdgWK-7 zhcn*uVdfk(kHt$~#Z|xkEoYx|4%KRvq4H2eUCtVTNi_=L!g(nP{2ZzUHvx4jdL88~ z2m%kOAj}60SIZ0z4f6SOKgW~Hp5oMhJDq%6H`T=Q$xnZo^S^T;wFC?vaSEPrlOo8h zGuztQ8ugP}d6D2W1NTh^iPdrI3UvjKtQQz#E zwFx6!VOm&=!s6jJH)~wcchk1*jGHtXt1S|RuY9zXL`D)DNoqYJZJm{=lo_rCFg8nL zo67R7UD4)n5u&q1b?KIpt_v2$Rp!i@Ot~_cac6*fbSl+|&AeWtuWxLxbnNvfIG~k7 z`lY7nahe)UdwVAas3mDLBoi&6S3UR6idC(t&BzpH_sL;JOG~UlJG|w(y(QM;M0V<$>u*MHB{t3VN z?e*mH9aLjzYwzaF_kW1rUw=KdYQ;gsTf943)4EnpLLF9IUsUUL5-B~(!xg+B#0x@R zd*X?F>s#Mp{l*Ra{*O118X7y5^8H5f*j;mI?N;sEsJ}PEV+essTm)7BJ0Q{8B4ofb zD^~Hr4}Fxwk35Vs&peZ#{q*Ndn?93j-fMCmYd>6xL~{7?*NL;ko;fP0ohd zd+OBp>k(X>B*^SIq9~zOj=AKLpK!qsE@t}l{fV{Yx4*ldZ-4&>^bJ)Aa|MhhYel=1 zV7OAl_nlC5;49*|h7^|0&Q8AZjjv%;o*QqyjqQD9tn!#XYX)P+^6u3fhoC8&>6zDnxlXwD1th zLj``LcBYidbZJ^@tq-Bf%;@EmOVh<=k zD;=`b^LcK~I)cz+!la38*|Les&h1$g-~c;`c8i-Q6$;DX_U(M>OJCrzWlO2mhLOrA z)q+F|uDkxvT=t7!;e`cisim#Glh1$QOMK>Y=Tfajw3-Rk&(9cx^c0EC@Fn%uxFAz@ zcMn;;cW+VaJ!s&Qojch;tbz&$b9O329xC zvSIIN5TvA;UaMPhGC!h>8ElNnh?_1IOlmbwJN0#3_lG~S`1sdQO$=B3=4yU;$$!&7 zP{w9%0YWKcreUMC#mgiB0$*WFic*3(v-juR&wYW%pIO0Q{&qV<)f(-cZ5Sn3`TSb? z2CGEcG?rOwBtkgWGDvrCWs|{djKLYD<$3byXBa|iLCEMK*OyB~g>zu)r^ zcR#R{ru`o$5UtkYN$Kj1#x$fVtZ-5jV@7pgO~SVA zTN_)AyUFzeSo6bt-$lhrsm3O^ucOhOc`5K$E7jSPK6RFB-4{dof@%^wi9Azp1~_g( z{Sz%3fy7E@T9s&xCsm`vV^f2vXD#(($xwU<>}cNjhSw1%Rf?h$qv46CR`AoyE+@>lks3*{ zt-$BMa4u)O<3C7i5mHG^#=>pAUP6e5DANeP(~QZB9a;F)BEeXNLZOrkf=ZJYNS-?Y=L*G>?SKD zrU;q&!`Kv!#_E{SW5@CHUtZ3qKlw4P{ms=}{o8ApJZ22wGR^pSh{^R55O;YS?82`8L@k%}W09nIChyMfPq>^&sIJMpZ= zmtmuxCZ%;KY@C^vHrgSZr9gTCYu9h$wAcST>v#6^w_9(eQW>TeyG16K59sUbp}(&O zAteisJdD#$d=+>W4}%wY=**e0b+b@Xk=hg|*U(ILOqP>4G9H*DWy<79r13or4D>bT zY#jq)bvA#6K&KA-Y#(>vSQ`4 zgt;7p#yt$F(GK>moRF-@0DA7Gh(;P=Qg`9%d1yWCcbXjz0H)DRc{d?4f}78pwHv6_ zVBXw=iQ|}Bb(obaSF&iyvFK>XDX|M@=Hujk1imjpXo{r}A&VqwL@gFv{>!Uaw|)zq zqsK5<9_IfO_ug@K9rfM+d*-xz@Aj2eWz}rCNV05MZrI3Rsx4eG7zl;{NuB@+53vK} zNuH397)T)moI(na#Bl;4Jb?hgAruFUjd7E3mxU#(_qz3#Q)cG($9K-TD_JHkB)@sR zRxfF_d+)h(=FEJ{r@Z@@e~CB0`3*#oh*KB2@rv?UwRs#fXVx7<|7HePsND4d0v{Nc z0hvSc{~-iw%?o+gfKC=JF~Gy&EW{&3cw+@-OuKx;)5CA3;C!Z0F;^bFx2nWHrA z5Jdus*Gf)#V+>IkS9K*FL6-RlI0)$L>*J$;@Q0Wz=WGA+CI0HOf5Yl?&g6pgR>{%` zBLW}cMS;fVSp`RM4xGv9?;Ya3H~b1W{P3`m@q?^9a|QK!op~ek7#bX=(bvQD z^fY_+?BR(YZ{(Zb`X)cT{{i0rE5F3t;a+0p2%RB{W6#)i9_nuWdzV@wVjH17gWfsg z&Du1R<73p5m`zV^1SfKoezgeh$cPN{jcu8cCASXh=2u@XfUSWN{>CirunyIHzf~@4EH&06)L^a$}SWA?|Y~8+% zIE48la|oQJ(}9OKJO-Y&fBaC^VKKsTj6!m2=%hJ6y!SqC`^JATd)6Gr$0vF9t6$AK z-}z1&jRtwvA&vuZ4qLcN9qQ?+T2~>?IahgoD5Z#_sM>V2a~>@!Oy?>>v9f4ps!uuB zZOz)^L}BN%tBsdeMu?T1`dwHj@AVAOJ~3 zK~!mZYRJ>fb33FBTIS!idJpw_4~@nE^;$1elP&ss2dUS3h~qj*TnAqmbV?2;D5E(k z5(ZjRWCpDy70HU6APPLt4Qx>`XU-gc_ro{w%FABOjy;FD>G%GSgNMgKB@~4w2otGQ zcvP+~@kv^Pa^zW?#fum7yC3-|_pbX98-Ki+Q%+mP_{0>auUNs?zjFsg*h6lWk0vFm z%JUorgnkVQkWs*t53hfaLr39dYp>v{*I&;S*S>+vuDps1E?&b)r!8g9yt$mRY#A?o z)vNi1UwStm{-aMYk-`7{oj+o#4VHw$h050gWX z)G2b)Jt=2|@#Vx@yoQGFx0l98)rsa?vZ2=?(W)DrNU_gH7eU0KLx(7G7@ao)&N63C zKZnPT!f}&Ra&458D!cW7@=jV%YxMHRpZpVa5RqHM;>8QO{`%`#v}h5|TH-jO-ELE> z#mCi!o<3JInabs7(OOgZ&9YLJavplFx=QW_h104ch{22wmhVWFu6S~?&b*Fi6OE{2 zFd|R?Z>ee2>vfEA6luoUXPrfnrzA;25{2Yhha@SvA%62n8YHy_xBut&_~f7c1y{ZH z^;~uB8@c?7YkAG(SM&Z~|4shluRqPU9Xsji9i&$40Tk_arwYrBF;br@wOUZ1gdK}h z{`&~W$QqU|UCLYE_I6G>bt&r}e4MZU$9EW?m?nxFOi#5$wY~J!Q31|xUXorH7?X4E zdFOHCufCtpec_*3uxK%NKd_FE{?W&|`Op4}`Abg0s1V~1JmZQg?6=O-6T*mgnu*tu zF$~UvRp+0_vNKiy5C#ExnhK`G6Xxzo}NDD;C`XZ@n^-I0D3`% zzA4B2`SaD_;2_(!ZL4;$Ads5I>eZ|1w4pOKh0_5+7*(AS?aidE-&KWTZ!v|Ch^%qd z#-Xa;kq0o%+T9uhVtp6|A;}8aM743Lxyt6Y?rP&v7{Ac}mA#yHcXlW{f2-Qt%3Aajk~I(aKW_ zA0c)+9shX(>WyB$_3iKSic2r&z3=~Ze*a^C%n$Ba$6Y^sfCnCaoO{+k$`}6S%l!GL z{+jFFcsQu>!Z;#KzU-uagAE7A!{H2i&!Jn>vgO#L}5slrW7Wt3bSfQo8@@~zkDy_yv(m($F0w(i}} z*%z+i=(yvDcixFZV|7RnC79g$;&5sBtw?iAz0pst(Zl0UY@oNd4j3o|Et|DFz7`>X zv`}kN+AF{sLCW58>pw8rEcoaj+{~Q$Co|oa$Ucf9Oi>o?L+?#A<2F`*k@?ej2?7QC z_U!@0Yr4w{*EA=_+5F@NvP|w@`7DNE{QTBZ^~%p-EL^yd{{DUr9XKd>g6gAKPuYge zTeeb58kl@0aK?2b4yTA?DOQDn^sh_MjPtFh&_^9dj~-=evRUaumOL1f8JyKLdWYGt z@k!1;`*ea(um)H|YjT1;J9iPqapi+jT?-oRG}b8Mq=z(h{N-Q&Ew$bn1u$=PJ}MaLA#yeoDwWTAUnR+y7FUjP_;&_l5Ue#8bK)q zpdzdjg{-nQdi;3q(MWln-H_HQFonYu1#y!2=+cN(ps^JI&MHM1M?MXaP4CY?_1FBu zyMBouJ@Po4Hf?3@=we=V`4znEvdg*t=ibShS6qe)>OA$-cAj|hDb_#qIPZJ^uXFXa z*YVWm?bPbM{Q*V!ekyh5;HkDO%m7XbUMUwOcKT3cUdzuIE$;UyoRBXx#Ujs zFJJj8lg(++jxdU_PP9~!8TNk$fW?`DI26UbUwY4bxbDqw;;F6sK*8(Zw3e^lb{iuL zMoF`RJU3PSuS`FS!k~0WYC$KxY~8+-%hz58=@d~2CeNtX8w6gs%34R3r8p)(t&RQr_j7dYh{UqC8(IBVb}|3ecuv+=D_5@Mq?1nKD_{9aC5f1uf_e}$d-iOM zfr0)Z+U+q0>vAe|+9^Ru#UPAp3C-ptK^Rv;Mq#K?K>#+dB9K0FWgBp2mxbVemIO*h57#}~vM}P14`PnyLN2}GOmV^X402O$wg+<}p$l4JY zOJEAxxj`j$R-St{%TAvI+VV4Rc?Z|O{w;jygBeL26DcF9x3vVy;t0@M4!-G5PU1oi z92{fzXb(d77Z-y(&u|X%tUv_;^+t~;`DJvPZ5oXRSz%dq@r!u<+g``V|NJkx=Bi7H z8@)8!6V#IiVHl&7!#d+rny?FcP(gQXTSueOz*&gGkVE_TGcs=hGcby5*sy`QBXgB# z{&>w3V_tA~<~cT!9^Ecq&g{V-@cQzP>=M&dzj8ElEPEHd?ktoe`e59s5&J;o%6ow?JlRLoVyz-?N@|~~$8<(uTl9qwJ z2abx$nJFsG4dq+dT5HlYC5h|Q28a3HcOT)R3ojO#Oe=?vQd+o3TG8sXnV6iEZdL54 z*At3d1f<8Ok8sl;e1ro>;HzJ|jUbFkdK+X;x?Lqa{zUvXU(N?CaS#$9sZiEQ<^Oe; zxVLH3Q*Qsh!%hd?HTBc*;(b<|NR_wy5GxEr9)0vtG)k}=dBNf(Cs72j5slwrwB8HH?#uM->q300M_C3JRMO*K6E* z>n-&3^pJ!J!^5+<`s&w84W{Uzlp_orxSYad=paJrn7ptO-h0~!fxO3T*}9vnUiUN1 zS#%2j>%G6mpMU1_eDCf@`N$vr8CSjG%|tzeeDn|hlt%w7vfPP1MUhgAIE9v$a~_x~T3EIWhW`0&TM{JM8=Xv*QDepFJ2C_u+CE#sg*ND=kpl0iDu zXxfOkyz@r>>eeqZGi=!BPY` zn^Bk+xwE|Lm1`O9o5f%~;UhPF7#-C~eL5W?oiK^_3L@7b^nDxRnA}++3^b>B)74iH zhXz!Jaj0}CnA`W7rLebYZ#9OX^Ex-52e@FlP(`mMa$ZCoXNf44m5!eD$ z+jnTB^8^CWtYJ~<7#Ey-8dI$%Nq?V2U9S6c+js3`d~!^HnzDGMX7~cb+vlVwqLgC! z^5qN;53ys%4re_n-&p7!><0sVy$$M(gie-v%DE_cM{!LGa{=txd%!OUNr#doBC{D` z9MdUsTAh@s>1n2$ZMJON%Jx0GP*F^$(;@PJu7QC8);(|^fr8p%B3i9! zk|bhmY>ak0<+nfdyR2G$4&S}=ZdRUsE+6{c4|B&4?&6V+8~MTg>-qHG-OAP1y^%lo z#3!lu_Vd)%?bPahIHhT}g}+maL`h63uVtYFobMz#C9LJ2G@d7{)#vQ%dvjunBlbdAB80;K|iFs3k$ zMT?g3+rM=aqw^OrJUpBCzV`<1zi%DW)06b|_0h>v!J<_4n;H5VN?-yylzaPGPO@CYl~jq*IY#2j%NqKQjo4NwY?gECsi%t7sV+F{%u)6o*emPSS)x*N z*D2pr2*?UU5XS7=e~>hTv(G(;Ac|?G8SPZ)ARqhVPjKm#m($ljpW(rITy^yoY~Q|< zB=J#|QkWv6Gdao6z3UfA9em@P-(X<&Flm}ntJOr~CG!#+C#pawi}i)nPOFJCmVf{H zH>%GIqV=<5=T4R^S)wYTYRX#Pvs^aMFrIUXzt8Jj?%cUkd@UT6gy3+0$h~)q*>@OA z#G<_baI+~0Od=6g-nwlEDil|)tjH;fjKUS7)6twF2to!22idlL2Rruc#}d%!?I-WF z3F8K7mXW4Sq5$U2n@85^h`xih7z6wF9bo_Ny+lD+r5?sOTp@jU9fkb;E&ssaKtel9 z>Fw|1+;h)`vW={yh#Lk0Stms)@zPb=(MenM^z?A}@L>)g9pmb2uH}=T_!G`P?;<{Q z)9>@SFMNqBUw0iYjM=_>FXPQNXRJDpkNn{$_|w1oET^1)I_F>bVm|-HFA>EJ0$&|h zSVApUmRf6c5D|EEu=Cgo_YAk}xk2Ag{C($~obq1RMWOxsBWb6#96Wr4TW|e5FTLcI zy!EYb=g{FJs359%P0pi?XKp59a}Wx!OoimuQRJ{}*%|!C|NR{npL{xlv*vKaufC5X zN5*KiT4ZTXPfw530ge&q!FM_3Lv&ixELpsWk-2jS;sytfwkfQxqQv7tb;sAolyfLo zP?(I_^X4&k?p!b_{k=6oeg>kwYOOR6Pyt~e;!#S6s3_v$M<2my=pUHHWHY5GG*4~W z$)d%l^EZEYD`V5s-1vca^IO03YaH0SkGH=4ZT#@wdr8wAjiR@fkfv=`oqrw~aM!)} zVVx5vgHDG)Y2qmHA6!4}vy^Kh2(%!971U~tV?O7Rv7@wFEoRLb5szN4M*jk7Gv)1g zcB5RRt5&U2vu4d=a&odNFzP4-6c?_!n8{X)pe7-Ii8NG&SVkzNDAJshPhP^oL;K~# z50y`o>fjVAh&Xg)45t-wEy1{e-MbGmF_n_#mZ+A{Of&ii2U)-FKF(czGUG=MO92lt zF1A1`%jskV%64TB!%#?s1|u4)4?F;9lDJNiB)strKT~ZUX_{6&^fGTOyu@6+(O`Uh z9BX0K>T}t&V<(rr_Bww5<2Q5p)vx2w(Mb-EP1DYSFrm>mi-~5z{=-wOTzvsI|HWrn zan@?y^S|HASHAjhg1b@}Y9N5(U;yJ?Qpzg&BcUT6Gw{g-tm2O7)nHS z+=f|RQwdQ}LEr^`0&JEsGBOuj$W*J%oH=u7x0_hs+SNgTQqsi|%tlDPr;qJBcQI>r zox*5>q=$76J<2OCeH~}4I)lIZ^k1|7k%#%ckNqAW_|4zoAOGp|^z{z#m9Kn-iHV6y zE<)7h4Qtn4!d-XYOHbc0Sz5|CifFbwW*>D@uR%Uz7=}!YkMpvZzC<)zrly2^;2faY zy>k!y_aDR+rutsRvVVc==~-_gRr@l}3B!O^2w+0*oMvQ-g6MABGRlN2x9Uy6$R@! zKq0t+KsknH&%y#n#>UyRZ!ZMeb2Ge9i<8g}?$N%~k= za;KPRrL4K+&l8Wx?pj6eL?AJcB99{wJ7`NlIqeC07=OC$tOXArqikH*_z9B{8v*dCohjY*;~!A3d^}!m?-I zUgnOD(oPL`e*cHO{`K$RqBUo7%dNL^`88M3+_#^pJ^Ps0w~rNPp2=^0=(oA&o_iQO zaulUQj8oL>3AQ=O+E=}jT{}8#+i{RE?xlQ0oreL4>!hCm+cnp+#!#!(=(Jkcyx_qH z*UwlSFg7+ur`48&zr5F_D*X#2;63MbMpT^&`uchRxw(Ny(p`S_)qL-+2R&*v$K>fT zCwUYmwAvlcJ$DUHZQo50_0Y~zw3ZK2SQs0hA_}Di6)4TTdGi>bm}d9>L*&MiB=Wvm z2TV`5S-4=a*CdsPtR6>L2We-zGOyBMAcD|NT4jy6&aPd%I6B@UP7<8b^z`(S)M_-_ ztqR^g%!-ayoN4TB0!~NLx+TtXV^?9Ww~$h=Ty<+xs#P{;{1AW;v+T1yPn-lK3*abR^sDHq+D7SlflYm(9Ev+M#*Y zn@G7^jgF2|^L=LL#2mX6;#s_Su}Tt{^xiaq5|%UgwXY&NnPuLBr9Ammi)N=oTuT5^ zhe8KTw>l7bo{F{f^$!v^>O8q+3(ZbWC(Urq5cCeR@ySU>W{-O0ouh1B4fJT*Qxl9G zJ?zPQ7+IdNR$(o5F@+80s1>b6HlmTqQgno_UVx%=*W`1EH! z!`uan_+P*H%hc-qWVyoX5T`=$CzZ7p<$QE#km)~loe;M=FT79!)>?S zMiNFdHVJ=11`$@PE;#LlYsgeLUN$RRf#16SsnDTdEG!yhq0!UBKY!`VGzNz_bM-l7 zg#k~I7oKI=dNycm1D2mEY?wV zgp^mLmF}3U(s-pc58JkEt@tbeS&?$eX{XU_ z!NEg^Me!?7eO2Ch!4=4jWoTp`^*(rH!xO%p>aYe}plM}Y425$JrxmB1b~@`Gc!;ry zNs1tlFjej+v**sk6dBqYA{`KgAwvWGOizwibsJ@6q70&;iBoLbwoS~(qmVQ!IOp8+ z{e&oKT`RG_EU&{9jyS3jh9NiHcq6mt%;&UaE4kzqmohfhs!l%Zw7}FA#6f8}AT3nm zB?vRC&_PUAD1QDIf0;uEj_|dwew}8k=?lRE_HtICJapTZWVxSE6n*x?0iLE`JyhL? zrKAPSBx+d&_dW0cL$iiC^Q_fOHQVBdhv-{K^kH$@b>kZ=tXHMw;dG{u1?x0n5MZ43 zqCYS--Qwl1xRge3ACEn@fvKsf%IpkgL=vtG9#kGLlD1n6&zeQM76!v=<%rG z%wJ=`v5%~XkXJ-X<#1L~$1R(-%$P4Ydi1CpA0L-{K{pz)KZVHlITcn*oJf)+?B2T% zkjXDEY|)}6pyAM%?1DiM5PAWX+(B+N!z1(f#y9_+fmwY#y5R|Qn1B{&x3R*@@LVA* zjx^0Ub?IpwJ$jT~d-l=F9fT2t62>-?8lh4sXE8IB)y5}VOiWBb<*y;ytbvXp3?R@H zMmDb?3WaPp<76r)Su6`fG3yQ!?!SK>KYnTp)193EeZ#M^@6Z@ZM>r)qDUx@0b4~H{ z6=0as4(AHrrHHUrbMi^cSbhG5Jn`cvS-*ZgVHgtlYbc!5BAnF(RT=HXh1KI(#Xos; zF(uA*bw;cg*On9&a6%my(`UHv{(E@Qg%|pIO1Env(lMSCIJ2OtIVR)|0);gxr9~y$ zNrV+>(lqDAFJ40}sZ&_TJ@?*Aqfy8BO~+YJkx<8@VQeK}edZa22-%~b{7a0??&wxbExxx3YMTA4)0e^*VFr%_R&&#>Xc; zNlYsHaZiJVCylUk&t7y85r#3jb)Z6#gR9rsxOEp_`^LX<>1(dw;m0?l<30=lPK9(j z8P4MwvY{%=hoSn|3C?CsX6&C}7^)VXVo~Kp1G^Fra@>%(U9ARE}7u z(K=8k`M6(CREyL#I-sF@aoI1;E9c!xc$3#fZvF$@_SEMo<90Gr0Gv*lsFLM zJfz-v83I2?&N-r_##39i(rR`%_uTVncJit)Yn4GqT`tbdx$APPWXPvb$8=0oAcst5 z3P$G5Wq5ctjYfkLigK7% z4wI#54A?@@`(S{n0eBzT)C2ZJz?X<4PNnGP?K28 zrI)VdM-M(sRPUuQ4wM#3b(o-P1KjZIALPw%`vtCk!_TT8tlt7jKb=DQj2*8)C6#cw zS*|dIfnwS6)41~oKO%~I2z0{cO;0j+1fodNj#4_nVHg}7L@9CX8#{UwgQK11BypWM z2%#`y=&VAlk-AQ;7Gq3aDM6Jc%{mZS!+N8^uHAci^ofm~!|b&H03ZNKL_t&>otWk= zZ~u8Fr$r(#%QE69!Z{E+brXVB;!)ijqdQh6P&OC=!mWy|75XwVfMCwo- z2Y=K~US}p$%nKY)ZaPAps8@yAIrBzvp=NTrHKTyoO{->pMy)k*65;%{pLfB9m3+kG zk3SB+rXe41My-i%I4{cShBy}A7v~(Ij!?kh;GpNL1k%N!)Ok@9#-YN9ExYz|V9api z`#wOHbx5LEHm1xF1tCg1@;ntLF20+h6xP6^MT-F0aLU@7Ekxs^Fb=FpY0A1hw)iU4qg?~{9xYFW334FJrV zU}ZK_*XY!)Uj0T2g4Kvkjlho?iN}t#N zraQKtR2_bWXnj~`a7qzGAwPO(JzBxSg`<^zZdso*PE4#+5TWaJcJJBGsmm5KZ*&2( zW{nWU355>GEZ&Y&5kxVa!azAUPAoQk8N7M@R%35Jm|^qJXcpbh)f8C=oK% z{hP5IBIzuUL?SgXbK@~q9R8-JTb{cm2v?Yq;ylmsob*IW>Az*mmN7ImMC!2`;O!?1 z!zC|!rFvrHW`af^sgVk{juQ@!P4X{ay^Xb3y`Hc>#K6d0COeKzTXzsQdQnQ#Za1av zDSpz)8p&AYdz_1b}6f=W6&-xPsibzx#TJs3mnyJMDBfZg_%+9(qVl4-a}%N>%oj zvM7G?sc}3}?-}mwF$+NXyt+CPw5D*v&Jc(=+E}2d4_G%0WA<_A2;6$o^gX zNwb39-d=9~`+wjcKlcT`efym><}N}f4Rjn+SnZ3{vWYq^Mf(E>_px}%5?o%E`@uDtp+eC^-AiBck^U$$ziVj18}L7?T~c+o`{ z@`L-yTYLc5(gN-p=0r2N)b2rYH(=Wv|ynD^@u≶qikq5~64aGSD zTPdZe#|ddWrP1hT#fp`r?KWGtY@yi_ia@Cp-vx0|JwPWKGo!`ly9lfRYr0q!00 z+QR7QC|Oou3s+e~U>(X>v{N2J-K|4Z*D?bJA1H_N1s|ovDpVBToY+cOCxY5^Td~Jq zWmO2a!gJSJ($cH0yqtEY$>881=QbP7vq1DuZNq=tIzJ&KIO78&#B z&u9MVT!J*&({`ac^e}Y#apg=klFS_s? znw>V8vDl!_j(ua?`|w8AzVNUO55tuT=yX~D zwA*c>C?cuV7@0pxnAF*}eJ9(u?W8mtGOnw;`h1XuC)!j_v<+!Fo{x!QDuX2j+n(CQ z$tRssnP4mb+7)QaI@usxRfNE)E(E~o8Skom5!&hM^~#!zbB?%{h{5$SToLPA$flZ8 zYaPnlLOAD0^Ny^CPMca?Q*i~9*IHH5+mMtQk7(^~W;(1v81mi!{0^(mIE5^4Q%{71 zsL_HV4icR2m^{2;Bl`{==9+7+;cH*{5=RbgVa4*($=Vs`oO2$HfdNbqL7=_Rw`k{d zI&EI^k~P%gggj4aG#V6z#TM}6bq^9Ms7H!W<;0=K%gl&OD}CG<#bVgq`-aU;5Jv}{)jg3{=gB+grm?-)AjOSfZnLBqbH{N)of-Z)nd@wJ)^im#p-~p0G z0~;jV_s|A5Y~I1kFTGq143CIJoP*a~{#vC1xcB~b%$Yl%1BVWSQ=(i|6k;c#6j3e0 zVA;2CAG3!CxZ{pHNy3Ew-T{HWd(|mXb~n_M2wOnA*&+9B-=Yw;tSswP#ilZfX*QeH z=W@=Ggx*ldblZ7PJ++Cc<|JpXI!o*hm2fU1PmC(8LmekP-F;krQ_=~7GSI&JolhP!5I+(U{x2mHPcqn7}*q??G}WZ zGtXYd7| zrwX8`mb}s;v~7&ky`s2A7;4&`78hT50i;1kQnmm>Ij}8NlPBxinwpp}zF$WLsr_-L~OJDywr!PI3{+?d0f6LowjEq!h z(*P$@k6r*O4n&lolXXA`)EoV5*szg6!P2D*v3ZKgyNK^@pT1BY;KQ@u_5vlAlp*qDtbJ4|@s7E(Gg$;XX+mL%7 ze1g-?IF}VGR}<(6t%NnX;;iKq8g9S)ex~z)u--=yg=ATqFoeA5;5=kEj3b`fx`k`6 zdjog<;34sSwHZ;MXs0447ig$QA;ZIi^2~bqMdL95VHgU#(MWZ?R_~$N=@7;;nUT_j zDx{U=I4z*IFw`jJxbMFE$gE@0NvF}t6d&W=;_U+@qfddqoFg&A3Sj0t^Q#(P9fBcPpv(H+=DsmY>sRhzXk;Fp!ibZ*4#|yF#VsQHHa<4N*wIN=opUayo-&tBn|{p5 ztl1bN5sR4k$ixO(>TO4lj59VdMI6^CtfAFvlD1nES;|=}SJIpo6)XYq$Sth3yJc7e!vNnTLi4*|l>gV`F1ppTkuc zfiQ~6&9kebKT}<#N>k|G_{zScRG0Uy@+gjJPEPraHv#3CH#!&P5t0(M6lA8rsxC*R zyGBY1znd`!<$FqQua)@uNHRum}hFxJr1 z(?d_aLAyD{$tN!njE4u%$tLBh*9*hY0|OmJmJ)@UMo%3~K~DseW8-wZ)~Qlr#17u1 z+=5miJ9g}1a$1U(Q>`Ywg9AiK%=E+<@BXECGB!5Gx4&~cs?kFy&nOU+tI*RM0vsl5 zQ{*X8Ex{48{zs2sf%DHlA6KS8+INR$!qbld+lci@6if8l>2$za9)0YQV-~`!S+l6s zVm3bUq${miD@D5(FrHsJbKDwL;PX2-R%NlSa??|e z%U*K@aYOOV@BAl?o<50Gf>2bQoOc>49ET5%p@WDmTetGRe(@bV{@5do&YMH-4V!J@ zH7JpOxz;c_-J;p*V7=u)636uR^`I!2H)jN!i{-_F1q%Q?Xvs5JJrORBYP4IaSSVy( zj3&#NIqy%`tFXuY{n(8}hk=j+%Z*rB>h(H91A|~KM<>Q9JpEsgk=@#YeUA70m}|4{ zn6+2kPNgb@qfqa~mnZi1fIIHG6QYoX3m1|VDVm^S`6}=4BLKPMt1Wg0k4A=eGm<>t z(TU>_<6G~08Y$$Y##lmcMlGXw%R;(aNgyBs9Y1ZPB zOJ2g%v}Nn|-4KWsL=@NQ6dtf^ECB}P3RGCOj~x#^w2^^dckuq{R!l>#n;XApr&YWiq1Oei z_w{rBi(jgq*t(nXX2x0PoX@GJF9-18mH_QJ6R)^*t(s09-@j)aBXdVRJXe$Z5UwZ; zNz&lSP1{&{+HxLw{4siadwA_@uV!TST<{$PPm6w&>Xklh z*@;nAfv*I{$?FR7?wRJG+rd#z{D1KpqG_H{bUG|vxQIX>J6EMBQ<)wqCFo|YLyF9> zXwhO!o>Na6jLe?v#iayITc%QY8`dO>&_JGNWJN(3Y8s80#~)fxpkVomWwhIEkDJln zJ6ID1Awit5dCODmJFu7DUa;2qs4~NM=S9jOfLa`b(;`8U8gL=XD#AbswkQ-hL*XoU z-f;(wIt=vGm^C~^pv3#9v@I1Wg6`TXBdijDSZcct^!3wfcF6s+B!0oL@~ksixNsrs z)~%z}>OAMQ@=W9TZ6dx-*c~O;#J8K0I;$_Zkd6zmVS|^v?A2;y&U{HXoJ_jb0i909 zDW@%CaL#NVdh~IWjxpdg0#j2{RgI@|(JLdYXK}wzv?$7GU}hvxUR8xg)}lx1 z3Riu8fT4i_aGL3fDG`yb5RU#{J?-s|eFx{inDOOQcQYsz@IoE1>Bmn}>ua!J!Ft#IE)w@o8*G?FQQ1Zs%B6oGD4)Ym7Aba;@FsFnb?3j z(JLuasZc9yk@@1izjr#|$oLrT)+DE&b}~s65b1z=l3?=!<+KP*85kPqhr$r*NWPR9 z%?oWvBARBWU|`-TfB*M?Lp_F9zWicZQ{xhScr#R;-a$l~SQlNR+vSrx9a^S!L z5APR`!-WeMGdz0^Teog!a&od-ga2c&_y1~?aB;a{O?_ZC*IakKy6B~^P_Mb_8bPnh zk%m^Gs4;0V6#B(?zlZgYZf3`x1JoOR(jh2Wo=Vfs3#QsBLvt3WpL^GP_}AOMMbhXe z%|(elFDysLCulW01YV*596*`;W#qglIZn5?U$?@QkDWvT`VVv}qGc!NU2YM1kO0u(DxQIw?_|vGGZ!C&pPYcZ4YDc8L_i-adNpAW;Z! zdc*6mooSTEJIR$BOp&7kAz~8MX-!VEe*JnP;H59RfUG4QLu0y#Svgpbn@e9SQCP5& zo@bpLtYhbn9aSU-(#Bu7a3Q_D4K{3e4B!~OpXWP%YMY3BNS{~h5FIAWUwjg$pLrHe zMHrm-0g+wQIZ^U*#__Xne}~EnSoh##B)z>TttpK6pg}X$N;x{+qGxb6uY2n|)WNYS zHa@kTu-3p3Vzg$@zC*NH9a)&Rz!crOg^ofg-g!S7j8b|6JY&ATG=XELlT7)MMk^R1PUgnCaT{sPJn?G>$&W_JS{BoH6b-4m&d=q z?M4Gh60vFH2HfJWoZ>R!O>faSIapwQXBd8DolmI3FU!7o5Sj_ScOHV$DbI&`A+wb^31tKDZlBJ`A8oT!$q<3(L zsNTRi&8I$ni@N0t{|{I1VY(;?lLiNl93`qZP&y>3*BBZaAkQW0C>I-m)&T($(=T1J zw9--qDm61_T*b(B&e7l3Co+#(6Gp)duEFu4_Ol=529ktP^&keGYF^&hE_VlC%rnmv z`uxPvjTmNpullEi_n}v(>k1=x-3S*iUI?~e_wJq4YO&l^HDk_>t6Nmd%6DP9o0gpc zI-9{nwT39v?A-nolVgXt?9x}s94qy-V(m;KsIjs+S?f0i?HC_F%A4MF9Yv=@h@?27 z7PN|S*3WB~6&q?v6_o=OM?CV#!z`GekfqaNaupmav0%}tC}C`}L$d?3XO9xb5pgWF zv?QvLwmaPY{X6)}Kff8q3+sfC3BnRV#6&aHoYE1}Y?z3ft0o%53CW+)T>1Vlt%#2i|09}IL0t#196d7r|$>i8L zSj(I_v+3*WsX%hlRq5XB6P+B#e{bf$k59c$v=5a)tgxit`^D92wHO*2futcc36TYbSq{I_Xkcc%&q|vA+JoM0ym_0I!Wv8AdCEMz{yBkj#Euy5GW6Kl+ zD%!%@wQGeFq66YE0^i0K{!uJ-3#Bl*M698LJU0+G*tusnqYFkTObe}D)!DJicgmb5 z%MIgGP0|A9EnG|(hU95VsG;6S`1Geg%|}0S6U$FM1(Rk(I`Hq=jn<9Qw2h%>cozTm z#V?XhO_EP%yzOV+KyzY@NQ;$4d8ix%B=lM+<*b&`sq=W9#fukXZI@VA{hoqTPd|;G zo*s7Y-06$Kg%BuT!1$@8Go}7SsfGEpH}Sh@S1C)rZwk=>nQl(=#-F)fwK90%p~tB8 z4UrlLI-;2t?A~{X#Y;~jN^1VSLjLIHPpQxT5!2>lR^Ex|tY|XCB8t zTS|H9fLNpl0RMMGt2K?%in;Sf#K^iZByk;^7l=5H5VB5may%{4c!m&Fx)jd0WV=8m zL}5jo>^mK7VW`Cd@m5N4)~Z!J`tXAc^!5;kfiQx?uKHPZ>Q%*0d1YI+j%Qwu>ng(+ zSwTObRj+y#J-v0Zv`vyk-Ou6G$fS5Jn`-F_Cvir==FOXV=evH9sGgvr zh;{}pNa&;mR%?=^Mv zDh2SFAnkOhCv|G|1~>el4{-OohuD8)0v*(GIv}+f9g{M;a4|`} zMi2ya(wrBqS;LuUuj2L}+yikhx>hHy^;S_uPffrFmvz(A%9YC)=xg%FHFpxl66-lHcQksySGL;8=)lUodtH_# z+eSxO`@sDyUb+i|{R2*{$XKk_NT2)*WG_wMUpl1qH4~51sEC595DQ=K)kOuoGrZur z&*7KX{+xj*q|6-(v=V|ALLexr1uQ>S>vMfW302?)EYejAYjCFjmDoh;Bgm6Jy z?m28+aWUZb+wbIvXFiL(ouayKr}8?blx*HI&iV}-*ni)J%pd9pt5H(XZnscMFmK*m zq_9q`EpW6B#yS}cYYc^kR=c1vyqJIf)J2R>wip@FyyqX^Mmn~IW*qqS;*iAky?f|= zwU)Zqm&BliGbF86ihw#X4le&=aXG6Z*FB!iUzG}Ar=woa)dkM(Zhz}L-{y~Z{n6iy z4{59=iJJ&Q+J)gA?|rX$c=H6mUvn=})DKpY6)98g7Q61cE6qkf`17bZ;q_;}nScNG z_s9y%n!6w6p8M|yD+pEKLl{@~ilcMjHWP_APP}Q#6=f=hHrlB8;p&OQ50pJ zfDEM~2_vE)q%}3g>(4liq!IGdpI*(}xpOGX+(XPOF4pb6lIdYir?JiT>-0DK5Y~D| zd3gBYN7-ZdJz2D95rJ~Aq}8UD>2Ou=4!X4a1)K5l%!XXGPzRl+lY_BnjK7}BxCKfv zIWfj5uX-gD+qQ7y4ZmVwu*39U_xOmakE1$ybxpmV%Jjsb5Q2e$0dBtOH#Cz52d-Z2 zl9`F)N3BM88B$oMsatA66eVCRt*I9K?|%R*R;*zDq9x2-xQKzpyVAFKR|XgFh6)>u zO}5F5A_zi+icw*Vl2wD9t4tNGl)~#kS0K8&qg((&uyJIZ@$pHfCPoOAB?=_%G$n2{ z$-D=Z6`3oUE69q1iZL!$F+td1aA-c){m*q=b@erD-MW>Ro%l?a?X{Rt7D!tnd``@< zo!PqTC@NlD+l9;V3(XY(3=LmFbd{G*C%6C>ELgyzMT=PX=mv^h*9he&GM<9 zOf%Z0WpL@PJoLz;y!=Hk=Hvf#K7)-uZoT;y#>U2o!vtfDgFKs(vT%vlg$oz5bjc#d zMmBNXwZEvD*(Ey$>vUH_gmC>6d08+xI7r@3kq9P6$N0^Szou-bEL^ydMT-{s-N90M znlezNg;QXwJ7c@f`&cvV!a9U%{dd)WCG`uH=Q&xH5k-*`5Yw824myZA!^3>%JKtew zU=UsAzIxNUi&c~dJxfb;8V8NXhF~;Rx6$~vt=xIX?Y#K7;~5+raMd+kI+{t3ji`3v z4i?7|VwbwpNgO9lF1hqF&V1upy!0h6XVLrx4E4|9Rj)jmHFw|5ygiqZT7@N`)oRru z>{@GL74XpQzo%$fUhv%KGL^QSM?I_HAW0HFaPEgiTU&1X<2|Ux0EG$IefQlN7;uXVT=Sm$JHhvV^b_%w zum3w?5)d^KP#)(HD$3IFZbnf=JIfJ4lR3NX!%JWMQcipQS^U%a7jW$_Z{ls|yq#m7 z^Bm^QTTtu7BuNA~1fWt1sY1>>?>vU)4DcV{`UVT<521^!r`%g5P%>O(kos<7%KV)`|9rIn#QneRkKI=5q7%8`ynkY7(LxHN>2EX%eNT#1AwiT-v{RZ9 zv|1xhnbGHpTn*vy?K?ac{7gr&D zbLaEUcfXg1A9|2SAK1Y8AAAb~kzueAVszo~F-nr=nakPuISghj?>kNvq@tDO^!N9X zwMBCZ;BN&auy7<-W@RfkA%0_~Y+?$2Y%r8H0UI2VIt;$K|cagRHgK($)4u z86vGy;tRvrCw?uqY_a9h2l?age#5~B?a%)E??ui@K3iYlE?pfw}X^a}dUW&ap*_FoC;r8DOxCx7xJZ1qfFzZN?GSlpd@oP=Tb( z3t|1#NF;&z&O?1=;HOl2vTfB%PK>$a34D;XXdB+sTuA}76Y@7f2Lm`rI7&*Q|G zoW#e^yMS~4;hjv3Od+JpkW1x4r^)~ra7i&CNSb|wae`7IlT(xY{Aa%)n;Pe`OTR?k znm`Ii^j!MhovIPd;4lVp9HW%$+cDbG-{@y@V#@W&n39pr8~OCd&tt*-IUM%%gE{<} zhxf=;mk@ zzq#&by!##J@ZbaY)89y#n(~+m1aTOVr)|g9H86+Cc3P|Y8RImWrLma8y#T-Z_4V9v z!!J4IRj*)pc!-KLIm-$n6_KSWB9O$5(B&9x#lT;9FqWV+1*LFQoX!3|tQDvzBsZ41 z3l_6!>o|E{k|;%J9nE3j`E{jq30Il)^W!V81_?(Vbp(04O(RYStb$TvO2>OLIyJ%8 zZQHOGR_?cqIfH!|-^>>T5}ju>qL`_P7LBAyo~I~fF}5IT_VMHY`YD%O@@4X=Hsxf& z1s^+?P-Ix0)7Rhd&)!!Vg`6>Tt)Hhys@9+J?`GPbpuZV0HZsahH{C>)x9ceWNs2<( z?I0a5<+0&KreDinXhgdEAZ8xZFDOY8mM>qnjv6eUw~%w* za<=&WZNEnb5i3_eg`xQiu@)MQ24$f;9G*_ciX6D}Pj@poIE2D=+GfTQ#*$_;;i?~8 z!O+kUFM7pG*u3pgqP`AGxMRL5yU>jezo2zNo@P)Q$}A-b1F(jxuf7st+MNBCGl)cn z$tGzEiOe;!G;ZM;M`>6T1x1meB7q7^#>Y3Ypczn(ZKjwS;fn8H&O~d1gAO`~*PnVi zlsUo_2(7V&!-$l^l1YmW1Xj9i`)u=E4QsX2IH{<81z2Ixa{GLhqyyFhhYEFl9R)?1 zIXQ!}&EQ~@W&7^Km%jY}`1ybTn2SGg9zVSNGWw$o%5jSJD1pgQqNJGwmDYEU|?VYS|;c)p-=&-vDi3aB5lz>rypGw#6d__ zT1pwQ=1+g-k}rIX`|o?0$&m@p{r^s9Vbc=mlzDRo85)D86CdVhdv8+0utLhFE7Vv6>71hMfMipMp1YG>92Y{3` z8ex6IVW=1$n#0uS2>s1IY|Z-Akveb?1pgul>nQ&*7+cb8CIF0%Y~}BsaTxD-`#-R8 z{li>*;b)mQXAW7~swoxA(v^^f&#DVgY6CDdG|0sG7KF{Y>c`*b@_+v-d+xOdr=NZ* z%lBP|E>h%QMmy|9pajh*B%K^%VstB) zf9q@f{Fk(g*QJZdv$k(RP~>@mlA&MZf_5t-ZY2Ei?msa$I*K)hX0u6>B$%wg z<|WOfk1RK6BMF0mY-*B`k*%EfPv>*rgAekV&wPe#bW0uf8B>xMC5>i3B9LrY_aMy( z(pDQ4M3lxjnb^qX*(@+RGS2#STiA2Yr9>5Mz;mILWr-4kD2kkc1FQQK7`sL?%Q>sKkcVlM{Y+zb~yetikq>rpD zh?B7H!E$W}j)>XM~#zwdD{`b6-cbxrJ zZvM>;eDp)_C6W#dCX96;Ep2?vZQa5O1jZDMjc;RWbPHd-^b369qEEB`0joIeb+6*p zuRevMJ?WLwN=%+&$`(SqJ|9`(26m!5v*R%hkk-98O-JLkk}1Gyj4p8ua+cB)*@Q}P z>T6Ho%a?qS16Qq}HMx!VyzR}r`yGGJ%{N}lx`)=1goZL3CkYKnU}z{w*_y(ZZN|53 z;Om$E3s?W>2Ylh;&vL?X&qe6MvBnF5)nExgc;KIbX0xBx+ z^KAI8^Ei$hk-16J>kF@|fdxrT|cQFPWK2qL7gH781@4Mc+9+;}bfE*th; z-4ZP%D1kBBa|=thjg7Hs^BBADu{U$)&P8~`S{At@57NeYp~fAzRlwc%uj6x{|03W2 z!GE!E{s1fYTEwefemui{A)&}YXEc(>N;+kyJx5z(hoqFWvlOKiagsRd3sd;db=nhF ztXRRoz<>k5O>0}2an*E%%`+wM|7J$STFa3~9?5|R9>`T!UC9kM+)!Vf@kGSd;uD)L zew#CQh~r;;qR7jV(Xoj-ek)DK0CYpT@4n|=qA14o! z8e6szCPO*p8So8(LI_WsBxih>v(5WIG1vJQ~DUAb5Q(ikW+@+<{wX*3!XMd8Zc zSWY?l#ydspZq8{Tz3thzTl(0;k4IMH(|S zuM%12Vp>vmHFEtxCk5J^A1q&9DBr$@LKo|mS&H7d;KZa40+wc4n@Bh$8_{P6~ zpM}GHEM73kDK9&Y;bw@`8I(EJ6sUk2ST@s`odTj$*3h;@MGhRedjI{%(~POfcJ)we zxPY~meU|MtV`#FYbyO8Xrh6h!3}x~dN3}r1Fyy3@P7=TU?QiWl=bU4I@{^y4<;#~l z3PRQCk*J!_08V)639R3+zK+KL0#&K9JAjnKYB&SbYPYdC;v#`!3&OiF=^JKg5%W6^VWCLDn}M0ghC2IsT~YG%U$R)I<|!uJntCJe#@DB z`m-0adE-V-J^hU=Te*_{Mn6#$F*ZKJ`bQpR!-jR-eABPE@+Utg%vv1({O5A|>8JA2 zmz>~oCc+Q^rgWq{=nN$d#yEZpBOE6LSf5sYqV~V50gh^iv9)`mupkY2nPDXaVT3U* zhY$uKWvOYmrx+fZ!^hA6DEHt006)FvXWaJtJ6Q9_yZFvm{|zfb1_uXOuwX8x%*peN zwRf-Oh-W^7^Dg}Y#~=4XbXidlDzwp93rW(X-D(j>4Md)d+q&@XT*U8or6@4@Y#aV#`E09AOqHI*u=tx z3!Qf=C1{KAvJ*zYSZk7p*KYs}%l6rm`NM-?O|3U=tVIN_w??X%|GeVIeCnc$S$p3j zEL}9flHq<{`hsV(`@(rhU0_N`!Vsgu6pju7Yp~Ni4QV?ejp%Y8ryBvK1j4u+Pnzbm zS}pFn>n?lZi6;tUU85nw(In0rUf_}1(PJ_uRd;tiH(ldzVnnLUJirMjoWPY={+KJS z_z~}V*SqXF=bR&sJ@(mvQ&ST{p`-&33F(@jmMmW44pbp41$C!sjo!pT+_!BTB?uzQ zq9gPShEPfJqJXmC?z`6TxzAn1RBMVL2r=5!R$6#i`pC8s!XzdLV=Cev2bs?ZLWK~J zBr!@T-uk9DFxc$l(#tO6gYSDg&w0-Cm@_!!NMeeNHEaIBU2E=SY|BOtI^+;ucH;58 zvs*6LTjY87$GUj3~eO4?Y5LRpLHf#UUJu;*6{E{kMh6+53yy-7Vf?8Pb9Ho z&fr|$e8y=Ueaunpw{m~d)Ny81NneW~ib7{pmB5)=6KkZd~ z?JHj<&vQrNtX z=dNqkdg5#8%=Xy$IO{fUKuTD$WC8vC{p9Hcg~x=TEm3n058n3x-}vUYx%8`FA;f3tA%X~!9a>@H3LhF=3hLm1{v+QYBbVwBkbn75~UDc-7YZ12MWeJHz z=%58s62+a$OZEAE_S{P-rEI65G4ts0^nG4rCWG@gF(S~3tE7~?=RNNcqod>Yr~h*e z>({Thr=0w9jz0QmaquCB)E5k(jYfFlBCNxf0CXts4Z0}7!+bH8^&2-ZFfagtBNkFh zB9)-jIRpJe+;Zcu80v4ZYX4P?j!qCYV~mggm6RYLYqz-J#$U61#R~Raxze#-S&Jm{ zS}YDr5-QgbylCDq=bZf(p8oVh`N`G)%~e-j#htg`USDHhUq8nja}0+Zd@x5H^(+p5 z#?!FY(rS;>NJ7_KrgPHv6gqQ&FW10XIxh>*o@q=Nuso6WZPCf*Py3Das&f_i%n0jS z{vFy;rwSQFs4xMk5Z0oNz`A;4&APvO^(vlnz-oU6!{#j;(ONUuKZm})L9{8z@(e3N zglAJTrbPMO&Uu3P9FsvQOPY?8x5kM>L1`_gob)n;v3%*0FR^CL8a{CDM_IIVS4vZ2 z1im}m&0o@NGO}qa%}9VL5FXc4YE5Y*su6*JGZ|OsWy^WRD^C$eAAO9^ zkvNQk6cU8QdQFtl6dt`N9BR>O_FcXgc|J*?5=v9;s!p(~B0y4c$Tz?B4bFJ|>DWB0 znck}|-Xv*~wWs)(f4PW-3m0vN}hh$!K^-D z6|Z>N39R3^k$e91N9GUDW7nli*=?7lEM2;kW-}o-8G#or52Yo~+GMRMgf3mva8)s~ z4kKcOFK0h77Q5|+quO(bM?Ql^^O{$^g4dmP1}{JP6b1$c0n6EMc_T+0c7Rv4(=MT!7nDX& zn$pXNgruIcBa9$xd-cH*tTArQDFs$B-b#67(EN@Lxav zDL3A93uEIWG~yU#3Qm0S^Evb>2Qq)Kk9=|hWk4wFo-rj@mw4Am=kZuK-#Z>Nms-ob zaHPGBq?y*E0x#2c=1A#M&!M3MOo&x;M$Hto7sN%S2H4&!KhAJF*H?TQ+w^T z7a#i2hs29tbR3_%@Kg5MYp>;wJJ#^WHTT&6e&#h?aKQya2}f|NjpI_Sb}AL9p7RJH z7#^O-#y@Xk%jh_}?z+@zlPX6)XpF&@1xU#~_ub3!FFL_>SEeQX&3<3zQrvLeFZieP zKf-g5J%;07a4e=sK}drBh$1UJPNk1lmOAp8Toc88w6hk%I8vCtM#2FH?9a;mSMrQ! z9!e+`fe7etG%1S=onn34H6n=+^LcAS7W$PgUiK4WEOm zmj7a37#2&E)%O%XSm3_?Z75xE_Fgfk#QlIE~= z>lCBouwrN~3l}Y=F|>dmeeb(m_HSQd)A~(3`0xheIA(IP&7lV^=lJIw$-aB+iZVH} zND*C~-_{z0b(|@Vrcoh{aPZb1&_iYDdq>?<(*;IrHk*u3r6?6KH0X%R`}+rRygnTk zx`Dwyo_6pdju<;{lf+G`^)=%v=>n-$0_xr4uNuxw_e7+WHLy%d$-Lnqjz0Qm4tnZp zv32tn&OiSX_WS>N1rI;^2zT9em;LaE&lLwBd@#legzUs+h0X~*2WZ7)ofic{1&mL& zkfAdkXKQ?{DMQTW{fe|M4w0Jo+#n{>TS7 z{27PR--sv+jm=wRlbWR21SCa!f+TLZ^T~kH6eLMRS)>%DBRDeJ5QPDON7)8KqD_vl zIY9ur)D%;bwAzyd0wQ6M#wCfZDNwQ^KdzwkokjGQ8Ib8^!A?T8KAx5Jr|NLW;t`R) zb-eywP?j2@HKxoEzT4S4P&R>=X#jz-78QhKMUE+RXM8+YM<`q=IY4_XN#O~Pa#va| zGo%6~eJER%PxF#EjGW?NmeWi^-f;SBc>SrbkHBF!lu|gS#4;U7Hk(XUQBu;H9H+0DkZ#$?x$k@zZ^F}u}6~^siW#|O=7JeiW`)9Nug81xDTl)sTL_QH6IHh`P+?T)-2!ks= zmIMfp4jr6lQ>0nyxKoUAo`P@&2CqJdkQ8Y~62-)ELYAf8%aO!EKqF8z!X|mDIqWG1 za^Q-62?AHG>F;;Vab;Q1Xf`leN)QDEGIAQW!V(C{#(VD}O-oknw+ay`l#$L`KvG&u zo)_GA-+hE3{O~`2$W=eNl0XQGcE;q`1jfKWob?L!U$vaF)nZ=L@v;WO@xownxfP>3 zeN{-16|BJtj0@8XHJEKoN3d#b=4z`y{mGT*^>xOM^eeWTHEw58pIOS5<) z-QJE6qV9^X#^0(xpx*{FTjVjR1Mt^N1kpDVAtQk-_$Y4)0Ht|8BJ`?=43 zPOMzHvgf9(bym}Ag9-!2Mn`G4r`WV<6G}NMMPo|xJg2X3zzF~u$fqVa_xMlL+Eo`p&(tafD5p#+3P`xmJy74>=@osQCOQlA}hxa@3H z@)121AS=;$PSE-!s;fiSci?(vd}9j&i}NJfDMed?bc8`+kf2nI^~~+A4+qFwSfgoY zEwnDYHnXhrB3M&vxdeVLqQG@+=Xvgh>ng8b0<~mLnZC~wz~2ss$R72 z|-CZ7hG_GShQ$~hu`)p*Xy$6 z$iMqL{_{KEK!p(&L7F<24rr~+001BWNkl@jf@h9 z3Z*1T)WGJ3Ki_{pNx!2J=%mR3igRbk%6CCHdd6e79i5QI2!q-I^3~04r`%ipwfm*p zp$p$t>l#B1(r5mw*FYDVyhss*7-P}x0Ii+mrP2jLT0#MFD7}oS!5Zs(N8F`WggW57 zO>04_5GgH1(UE@)RX`vEwr<@@k(IuEUeMn^he8|fU3)je!rXy=tQGV%BFfSdst{of zMV2C!z#3@A32A$Z{?H{=5rVvcEO%PHbLS27{3D;vL917>V0aF;%#cP?W}_?|NU)|L zu+~!~SmG$6)p9frSc}!xcTfA>-H3X29p6m%1D(x)Ob<^xIjAIYl#4;A2*Zv6aP1+Y z{M>GK^HSK3rcv0%Xh&N=5C@z6sL*~>4# zoM#_(w0+I%P8HKxn3M!`$-uw>g|^(g_I_UQf){wAY~y!O1tLbu92ErI@%!7k<+r!8 zb?X?7MuRiYJk!O=tw}Dt@FMQI^ADVQ>T6lOdNp}gk|ZTj7-Gu;C5(%eO-WK2!>mOk z3|-rP1z=JFVRPq}Ywar#5>vYJoA&det#J$+!nNoNS#SB<&7U(c9Y9`ZbZfxOJbHiM zk-nV$4@6I@t=ouge;%I4xP0#1ok*_Np4`s{a>7#z6-i#2eo52C;tqdi%*wev-d?))6dUv2R^PD2+y! zB}o{N>yn}`rz?CG3;{`n+HLaWuH(Qsu<@E|Q=T^>Wam&OWELU?x(UtV+2IhRPA1}E>zzFQ#> zR(Zl3|1)=@?F@+n*!9j==l`=Ut664$w(P7Ald7Y2Kcx;ht(RA;!$b}Uhl*5PSL1A= z@pes|b0wr82x^|sSHAL<{N^{m;gU-(;hW$5 zhJE+D-z^%AK2#X^rl^=K&pdor)E2fVidyT&8bO>i7}>C%)hkzU*`;4*ywyTmMchcZ z?z*3G+s(h_v!DJ9PdoGw{(SFRvaC%IxN4G+US&);_gz;HMs(kUUob*|Z^Y|0{*JV! z`+adGI#It&6-TL@rKDGd3cU-j`&f@Hwh=yoYHI^mmuTwmWzXl`zlz?F%2jLpJ$Hp* z5?h;H==GYU@5=2quD#dplBpJ5ON`*p>)d^JT!lahMV^pW81b&tKCRafQG9l+0zJ4Pok6g_=2 z9rS9~#^L2X(soYYK$F%~o2NeYsh}_G0MDk=2Uv#=pUr!nzP5lGu{ymv^Ed6{oo%=z zk7qRZ7YefOp?UVRpDmUzU(Qum{Wp`7Eq7B!U`hwZ3IfS4yY511EUk9R`i&cj8xcl9 z7>AVPltqidISEmsSifmKX}d*{PO#yDwH$HCLA>W5&td7}dHng_wZw6ZHU%oMgpmWZ z8LV>+rN9VX%Pv%-W=!wOhEE^XRvnks%T(_n8%`I zR(U|xm3NLm^Y?Cxz?*Ml)vpru7{5jKkQrbt5C2H&RYbvf+`3*mtkpc*^SKNZn>?WHXS` zY{c~U4-)tFg9<#aEF609p{`8tz0JZDw2Pca9(|C$80HTo#7RQMYg%<1R}~dSN1J&2 zr%_31bc>zKo}^~YLEH7$H4B|LpuHT%?jdMnkdbT4070lCG_Y-Cf~_NC+dbFEi+HY@ z@2d8X?(w8BBG9SeRR6E6owb(dKKHrox8Hu;cH3<{`skyztYk&^W{hF^vVBFVp|r-A zu_SqBSulSgLj!{(ag3CbBuSV*f7sFTn}WrQ7SL+77#|;XY*`YFDeH<+7zJJNdUdVa zYnOIt5qI2O>lRT}GMnjhv+oSn$2!yJs`It8$NBgc4s=*adXK!lv6=1o!sA7%;a-nU z7xwIiud5o>bL{HAI|As9Mgyf(owQa;&}hUR-VCitTWy4JIx}Gy(%07{jzbsHBoV*9 z=|++SwvCN@PMER|5Ap);T6-UJ=k>94$wJB^@0kzXWt=Od^vtu-xwjrJkiVd^Rt=Yy zvvmpAxR{zrujLyAK^H%*nK3!PvoRCYy?Z<ss-)CxHrajm-5DGlDZ(aFle`I6-AV5Hi(DvHnFL8X9syDC=6;b&;bYMKc*-NDq*vDT@{@AkR~e zCnyn0(%0XtNt%%^z;JmMfyE+)lLwutJn}>qg*$*xg9(H6GzryQOgB*7IDjX7-oNsw z_s*Vss1rb4W18D9ItHZL4IN#9a#b8@>2EYCltx7%Ns`cL#^kLWVI`9j6O?667zQ*N zP5Sy1m#zWNh42vSP&|7B8CTKy%$!YrC-> z6(>!1*wKCWGbP3!-{|&$yN^>8g(D?5j@3_c2+qLxnc0!Zw$7APd=-tsf2B8-RQn`>7z-&7B zXZvGLzb?0E9uI%S4#zaC%1%FCxxv)05Rcg_n&CX1aK{1D%F+Wvi3<6&QurJ z{n9|^#ag*?Wlf4BaXcYFO-H!je)|I;ML=ORBjaNj19Rrgsf~dUpbIBAQCLG^4FrnP zYDA#CFmr^86f$s3+of^&2FG{i7^{TY@x)Dc{buqYb~LQ5Vq#axFlOeLPIQGv-RE(x ze)T2l1lr@hj#WL)?Hf1a(N$``6RMwduop!X_a=g$je~d69u5ZVm$9 zF0UYI#w3jx6-q=PFv=p7Yw8p-LLIi?SMeY~R^*J1jFTiz8GXUR z`SkZUL6n4%Kt+?UAF;&*%q{SBD$&t+UnYaEp&;9 z0t!lUTM{HOB2bjtHFIX#P)JEyYE+}ircGNg7UmAkb6gxMqyRE)_~SkI(BBV>7S6{N z+hKl( z8Op*tySK;n>Hovg*Vjk0*`(cW*ArfOELBg$tj>E+WykHpl_Y4D1M4JV{rz`^ZoOfgsee`<)%p#=|ISsFELvE?IHH}U6s17~ zP9B6HLdzI}h}QTdxBu=Al=Naw%?8%`HijT!&E5CXKRC#uMGGl)=Cq7^%C7X3b31qG z@1!TZ=@brJSmy3qiD23WHGN(59=$Ro^|`I~^Jr@WJAZhH(UGmJTel8;m@Xy$Gj4wK zJVyvslRDS=rpMv2J}HgJ^p~!(j8*^4^ti0v!2?G(uwm0iCMPHBtg;XeDJVRQy86>P z7gL=Vuo$$pbrWCh;@M6`0lHn$?Z;!C|5+cD_aZdHW&XRnc)LHgBbP^*X<>)x{QQZI z9T>9hh>m7-(|Z?bWjtm}8oU3SdS1JGIc7cwu3{mbs$Zq)Ten1HB}T+#+A^?k3Fn^s zQHF+w$qlGDW@>86znFroux!|vk|YVc?y{J&Xycj!O&7If$K&e`-DVnAxa-b!NohT! zu}yTcWy>)X5LXPfIM zr4i{~Ox-ctfd?Ka1_uXG9-U{5AM=mBdk_gY^%CS`^z_i!~4i zQI7$shWGY*-V+D((yrU3#y-pxe#|~*n*8o$@=QZodSo12rDFT$yT>>Fmnt|r^@wK1 z%S=xScZV)J_SicA@8*T=3G;lOOn6U0YfT)xc7;aLa13<@qQ(HFhB*tCa_;*+#DYb; zFn`e!G!QouROmMz8FJ6s`>+<0C}io9#n@7N%nnp9qOqc`sEHlSZ#OGht^Q~$Z**tI zeR@TU?aH+kXOH7Zfkq>)&sWV+1y``v){U?iUwpCs)TcfLxI#pp=XHbZ^m(3X%{?iN zNcZSyXLKg1D2jRl;yCu?ypnzPUQU|2Ht~TugJ^5eR+Fb0N(#!nQhV24!_d*ZFs{6F%0_xw;ufO=vAU z=bF)|bmpeMuC6>y_x#Pi+f^^v%ppvDNuopUZM}={0Duy#B}+5nAVyf2oNO^Le<2rs z@>Bfw=36=BX@?OceHfsXwJA%-?rv4UZFk&3UlaD)Z5JXb>aZ3}J<-bfr*&P~)t})x< zFwkY_{HL}HliZ9tgW9<^IXh;l^OxH#*v^$$YqxuWDgvkKXVn~8YsuRwf%2m9R-#bM zox6Zbzwjl#^__2X+G%GnG`s+z0#xLTQ5*$iMTrR_ZoK6dn*AZG_uH4ri3y|#e6Ni0 zG?MP#cWB_fiX8yDqBfK+fj=#wx`QaWcaAJQO?938hU?2wLC|RxsM|E0WNqbHR29+t z?z@j8k36zIPW3m{2EMaI>yzGybT|A|8RW7o5kh%)HLfS+SnB#%rC8^c)CiIp z@1r*dQ1#5rP+hT|SZb!U>&_S1OaWS@_D6l}ojv&3e($<@txsGUv@o+8BuSSCB0JTT z`dDIi&#m*bD%`0&QsMIzU7m}e=NQ6xF*0LmHl2u56gNmqO<^V9``#5?{QthloB#eC z_SkbT!pLdd*b)cZM^coAM&BU6`~5ol`}(j}>=n zc2$UFEx!6^y~ofoevj3F%ru<*gA?)6T4S_k=`Ksyv}psIHg5(bMr*=A)*g5iMLh7p z14K#8_~Zo8NgvcI3NyehrjIAJ5vg|;ucyyXXh&DlUCw?2NpI;0vW0M*B7qbvm^Vz8Wo+EI(fMjhc}w2OGqzeOX*=iG zV~+)>z51CT1+Fwd!>RxBtN!bb?u27^>8Y=;&!bdb2S&H+b=+~sxrLs$nBO0B+AB}w zsrxNskEL_@=D%Og2`@dFAn9l8mPxV#!bTravq?M6K`5dqafvDGjD+<&i=kT~uLJV! znNQJ)*=O5TtDUuKBHQkBvJ!80Y~6UAO2_g{uej`JR7-hUmU#OspYi+c(YT%OO}88E zci8S-)CwopVXfYd>hJM|d(OyAZ{q7-wpH1_V(m{FPWVbGg&`nL`Wc%@DP_RVeti?C zpLI5;o%Q#e@X}Y1<%V24q9bEmc$;Pg1R+WP0M}ptD~9@D)xIm37#kyr6ao!_!U(V4 zW1Tl!J(sH8zq;O@u4kzD6gnH^3?cDOXJsbbjCF}nfg;N?x8AI-4OTU0E;Ol>3*Z;m zUT+(XK1`LOsjHBkTu4>LoUI!6q%|TlCD4QroN>k(qDuTI+#(K@qe;|RN+X0kon+mE z_psmIyYT+EzloK*4YTWlga_}xhvmywF;Rq!r-sp~ly<2Jl7zA}zALzsIX4L3!73=N zM58E#!r;DK)4Ths5{8vxofV=s0*(Nv+e`3Ki{~nJ;fBXJ2;&~UHXRQJZ@@&CF3gO% z4*^#BFMmx|feo>EibL;qS000*!W!6}=Sn0Fe22U2IvMS~st!+y1qnt~*ID^Ll1_*+ zLnzlXdK0bPJEJpNl0XC`VFE~kARq_=#zseI3=U8lLs}Zf+nTIYT>jl3ani|WaP+ay z=lBy&WU`$je4<{40TlquT8ov6c2RQQ{SOiZ5zF^kMp@>rTwIov#wqp*Pe@&ws-w4h z45q%f>E5FCS~IS7K>G8_#}&%Vv`KaMZqgK|4l_A=q4{vf-sOAu>VRXM#dT0yqO}OV&APds2GnkFg8b{F~Yg%6$`rbxD;U=JlXiJWQ~(!s9N)T z3;}K-yGI&eX86)VqNjTX!gk#5ofMReF_gZ%De*~Z|0R9+0(2QGSJmn^9Im1%=|$Ae zeq!6@de?L5b4f-E^1MJ78YLv{cAGgvL$q2`SS87Az{q&UKY#in&i(Mm`1`m1J@5bE zM<}%0RkgJU<#yVl(&tr*yeNnpO>VyR0UFId_S$D}taUojLdj0QigCukO6RFoZT_7U zcJDmn^Jz+jJ)ZXCE!9_YBAq#M-4#}-1&)e?7ScSA9feoGL z5C$QO`o(bxSxE(eu0cc4$q@*8avRnoHA^f;1!$#QIT7tEML4jVv}oxPq5*=SgrEee zL3%?|`9aEhHg!=VMM*$GXiGv{B5i@R8PXIeZBeCinz2S8wL)qM#(5U91Yrc$NQ{+O zqYzqABFKb6D^Vu{=`k42sFm27rCwS|V0<#s2ye)w59F#uq(PvN{!3VIkhBHk=2K%` zPN>UNYQJqO>xi7=MocR&5kZ4iRv?0a@m9wAO=Fz;`nU1T@BWz6&wMLqpYtxZY#sv= z3?YFCkVuN6AZfVuRBBC-^mFa6Z$Tw6Z_zFc&0WA$R!|}^(&s#^GuCcYFPrBV@m`5f zm%4TA4WBc%rbk=4H|&#ji^Xiiusx>67_WFRF+nI5&9H$I0Y#R3K3vaPG=VUj{iZYc$2XnM9!uu1`=TZ{Tz@^szwkx;^cTNiZ5Wi^4ZR767HNoc&wD5R~+eKVCQ1%dZ0-1mSBUHtvIo*>@~yS|#!VAkdG#+i;;3Vpn96wX`#;1RUVj$rH*Q8MCx2;i+%wg)+GUqrJlC%v?(63l z*Z&F`DxUrP=hHVlmw~y%v`b6wX3{5)t2OA?=8QQjQ{S=0RkW<|RS?g0GE#n}3!U1c{5qg`_l27uQ(- zB39Se^;LOCe#v5O>8c$#szlvgWf9I3(o(y;jui+(=Sf(X5Y$$=P)|sgAVfN$G2!VI zb(gm$pki?A2B6ux;?gOTSHw*&x7=aDcPP?M*RMunq(B4#QDcC1q517?YdHTCpXZ!^ z_yET~@5Q|1UGL?XW1q*?krAKAaP1GBejV3SH9Th!7bOd#WPqD*zY7~Ayy#^o@zf)Z zVsPOSZvOq95D!rJyp-_1RR^Wo?KMps6?R2*)^ue+suJ~IGMvY3>Rd=s6a=9IoFz$u z)=;F5nct}l^oA)o8MNv;P>r5!s=_uoBJSq4@b~LJ+scyiSN}Cs7l?kypc>|#o zyX~<%C61wL^VSjeUO0fVnpnAAZF2J?>^*c$^J37%&(!HVoK!OtL{F6GaArgg`<$cegsde&OC* zx9a<&?t9%W1jhagzFLd5#OoLDtvYpTpMCb`YZsiy^Dq7<`%In5Jlxx#EA#I8%?2*8Nq6uSACqmK2Kw=bLEwKtC zZR>h1W!2ae*d(RF1iMIXmMcBHOcwAcc68HU>7}!yi#U!MKem-Pj%jFaB9+U5QV<7V zG(lt;iPcJwtteRcx|CN{?~(~O!d`1DIcTSaBZNIR#<6W&6F$@gGvpwARM;Ka07?;7 z`fKHHDeZ5q{mLppT)n7+h+0y(HAh3&^9U;ezT*?cDq$&7*%;dIxnKY~sT?r9J;g|?1B>@paco;2gHaU2+-UHmM;upe6 z0^=a;>|HZfk#<|s$@Lf73Pr2X0=7mHhY^lokQ7EDAz%hF3(L8BD`R+X{GGv0c!S4# zK8RGu-asfR-2p{348nnymKH{|G*T!OC=^RLehLwni6g5x?nyzpRAA(!No?QM&d+YV zMI3qDiRPETx`x+QzfNc8|M2uvkMn^e4&sc{K1%D@ahNb9C>Ke4KCy^#s%Agc$sk;+ zeF?UQ!_sHd=-_N@B8|mvQ(7t0Q#r}R9 z5FJSnD`Jye_YotQJ$p8XE`p}r8V$UN+4aw z0=bS$7)O?Ij3hMRI6j&BMml!x;`ZO&z#V_SljmPv#bHMr#ZgN>zySv@X5EI3Oq@6| z$-V^AfjCa!Z;@1!w8r%;XTtz~x{l=!JcMyP79V~j2oEDuOrAcQBbJ`X-S}{90r@4srXOM;`?3?mlICjMi+JGq@5%u$`JBN5R<(d^>;`6C z?m%l>&J|U%o;G-1ioU+S#F$QV6MCN*S!4l%WPf0h9{p~ z&hf{ez!_(pL9S^O<^Dc|pCu+D)-irUS(Z`~MG8k)1FWijL{<1jXv;a#Mq3MoLDd_H zlXMJM)!ZenaLD8{JhALyuKm^3G}kpzmr5}#lV#sIbMai4y1F`RjREwIY^A%mhpt^6 zytHL25B~K&dW$7mCr)Jkf(0yCxF1udOrd_lM7xk(X(z4H^zPir?vCwrwzso+;}$wP zI(X^TSLpBUWA~0-)TL77@);T$>PUM&p76*aNP9l{OrBIeOIKenVWGnI?)AL*_;P-8 z&9(gK%AZr;)Qof`N?RnMDzL1DNfgmdt=A(;=-^UHq~|90*9t>9Lg1&;1VM!B_+%Sf zDE9Pm%Wwa{-S_;BM<0EX(PJlY-j^Y3c<-A{GiQvrAH>;#FAr9l3LMjj`B@U}yqTeZYts=fZ;UW(cNW=l8p<_a+%$GN%N96u7QS92i>1i~?YHS0|-n zfo!hMZnjBA-`m@pklqyUHUrw*c+Urs!P=sO2`|;?sg%ZXC9zgG66!K(rcRy4Gk<@a zVzG!2f>3Lu;~-rh9cyGR&2!JZjN`$&b?Z3futQmNz>Zad>vU~CHlPBW&tXWkxALD5=Rt+3Xy?A zsmzY9PIh*7^3<{ix&5Z!QHeqtnwzLZ3hCO$w5SwNDix6khBYd1^6 z&h*2N#Y7SHbvdNbWPOj6ld^!b_D)>V#iv7BPE`6h@uLv=b&^< z1k^VVRX4!ti=hP8t)1s7iq2 zTRFzqClQi(W> zAXoh|*1jZ)qMBM@b?m(;@Xq5sA4IA*e@HOFHg)~=-n-dv{vt+=9%)5gjH0fwiJ5a| z69PNicTp%5sPjC^l``3EmayE9o6hsfE3cAGr}3)o&c=|>c(gV*@WbzXgQp&Ugxmi2 z4z_LFPO(tr*T24&-~H})oORY&eCDh(AlCGEb>KJ-#d3%vB^lo*tXRJqd$u1005qLr zcwJrBg&Q=| zIKtoQ(BL|yYS0vIt` zwJGIH97a|Fh8R;)87QdxL)CJW#3Uu+Fq@Rn`_%ERv1r?XO9#Vbn#NCMDVcw zK&0yd1RN#+UCKH8zE>I4JQR#~zpjkpf|p@i`G7Q~WAoqw(j<<-ZUoI1#GJ%x*S9JgY4 zf0T3=3Z6w&bk-nw^Drc!Cagd zhPXd}!q}{6~e=-U_}u z$WSUZ0PN5oraSyV?8oR%L^y=#S1~nJ}q5buO z(XNHrM0P)T&F40mB)W!elL{`rN~E-KvB?K(rv5nrHUJJoe6WRtf}RBTHLX~sk2&h# zdO`3lg%mMO#Lx|^Oy_$Tis1WS`7~A^4!`GF-Cb>Q#RVpKd=a}mlX5&IL}s@#1WS}h zD^ve6mF(KTnJL z`W*^I8WL5J#rmAAwOVPxFEfkBTz!Rbh$O4l@F{HuLF|l&1o6 zwF(Ar&v*CFn?U&&Sif8sME`Y^3CLeAbe1xA;(Hpa$2K@}7*wW99@=B=qY;⪙w%p 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 diff --git a/static/img/avatar.png b/static/img/avatar.png deleted file mode 100644 index 0356f911c6b01894f0983ecb5f66b01401f84cdc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1323 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(6Oj-S5fuR$!pIEN!@|nR z%E~Fi%grl7GWdUhL6CzXfFXdHQHg;`kdaxC@&6G9d7vj*8Nq-73K*GyZe(NU;N;>4 zD%dK(z{JSR%*4VBay3wOEl{3;MUYiU(a@1iI53f2sZhkIapFP_Wv7h?MT0JWP%%y_ zYU1P)6PJ*bQdLve(9|+9H8Z!cv~qTFb#wRd^a>6M4GWKmj7m;PO-s+n%qlJ^Ei136 ztZHs)ZENr7?3y%r%G7DoXUv?nXz`Mz%a*TLxoXqqEnBy3-?4Mop~FXx9y@;G&P778mFHFAhJO}QuuFG%jI8)?h-XAJ6@h5YR)O`c_i3@nTG!`{*0kPR0$*NuTT_rc4C@4(PRNs(4 z-F|H?^N;W|&CPM=AMnc@UKe>ZwNk;?%W(TM`_~QcZ2!7Hc92~v->NFYu)no}zfV6n z;A7fSlN6E9WlYv@8S9r;<@eVV@-?QbE?v{)>*acjY0giF{|tiPzlc6s^5n@UUj|SJ zfWk!7bncSt-wSR#v_6~Kq}2E10_$1k!{6sA?-RS0x#Mf4bgSbl-)i=DJGsm%rX~Fn zdw0vsTqeozpJCHp_Rrtf%5(oH;^%o;calO0eFJIcG!SE;3UMfn1dD=(y z!*})L!zU(-mG_>X&vDHExA%qr4E9wY|JDO7k=bWrV~Pw}aRuXt+(Bjq$cJdsno z^knN4)(JHiz54=p%P(KcQ1kQ0#UEF$Pn#SOdp6ffWR|+dscL~NDF*EebpjcOo(J!| zk`l9a)0=+fAGcTjVgJ0|ZhhvDzzl^Cvpm?1&%CQ=-u|BTrkM36MTsPB0ch;RW{QLApz2KkK=U3mV(~j!=qxMPgjIeU^SL^z3Ss$|) H{@(-u!z~QS diff --git a/static/img/background-dark.png b/static/img/background-dark.png deleted file mode 100644 index ac9d76791ac0a585910397e84955f302aa6ec1ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23656 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 LNkvXXu0mjfo`NDK diff --git a/static/img/bg-black.gif b/static/img/bg-black.gif deleted file mode 100644 index 11f8f9332893195644769b220671283622123a67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14700 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⋘6x=audZ{_qI>1$;5PlY$}M;m=9m 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').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), -top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= -this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=h.handles||(!a(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", -nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var g=this.handles.split(",");this.handles={};for(var i=0;i');/sw|se|ne|nw/.test(b)&&f.css({zIndex:++h.zIndex});"se"==b&&f.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[b]=".ui-resizable-"+b;this.element.append(f)}}this._renderAxis=function(j){j=j||this.element;for(var l in this.handles){if(this.handles[l].constructor== -String)this.handles[l]=a(this.handles[l],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=a(this.handles[l],this.element),n=0;n=/sw|ne|nw|se|n|s/.test(l)?o.outerHeight():o.outerWidth();o=["padding",/ne|nw|n/.test(l)?"Top":/se|sw|s/.test(l)?"Bottom":/^e$/.test(l)?"Right":"Left"].join("");j.css(o,n);this._proportionallyResize()}a(this.handles[l])}};this._renderAxis(this.element);this._handles=a(".ui-resizable-handle",this.element).disableSelection(); -this._handles.mouseover(function(){if(!e.resizing){if(this.className)var j=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);e.axis=j&&j[1]?j[1]:"se"}});if(h.autoHide){this._handles.hide();a(this.element).addClass("ui-resizable-autohide").hover(function(){if(!h.disabled){a(this).removeClass("ui-resizable-autohide");e._handles.show()}},function(){if(!h.disabled)if(!e.resizing){a(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy(); -var e=function(g){a(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var h=this.element;h.after(this.originalElement.css({position:h.css("position"),width:h.outerWidth(),height:h.outerHeight(),top:h.css("top"),left:h.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(e){var h= -false;for(var g in this.handles)if(a(this.handles[g])[0]==e.target)h=true;return!this.options.disabled&&h},_mouseStart:function(e){var h=this.options,g=this.element.position(),i=this.element;this.resizing=true;this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()};if(i.is(".ui-draggable")||/absolute/.test(i.css("position")))i.css({position:"absolute",top:g.top,left:g.left});a.browser.opera&&/relative/.test(i.css("position"))&&i.css({position:"relative",top:"auto",left:"auto"}); -this._renderProxy();g=d(this.helper.css("left"));var b=d(this.helper.css("top"));if(h.containment){g+=a(h.containment).scrollLeft()||0;b+=a(h.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:g,top:b};this.size=this._helper?{width:i.outerWidth(),height:i.outerHeight()}:{width:i.width(),height:i.height()};this.originalSize=this._helper?{width:i.outerWidth(),height:i.outerHeight()}:{width:i.width(),height:i.height()};this.originalPosition={left:g,top:b};this.sizeDiff= -{width:i.outerWidth()-i.width(),height:i.outerHeight()-i.height()};this.originalMousePosition={left:e.pageX,top:e.pageY};this.aspectRatio=typeof h.aspectRatio=="number"?h.aspectRatio:this.originalSize.width/this.originalSize.height||1;h=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",h=="auto"?this.axis+"-resize":h);i.addClass("ui-resizable-resizing");this._propagate("start",e);return true},_mouseDrag:function(e){var h=this.helper,g=this.originalMousePosition,i=this._change[this.axis]; -if(!i)return false;g=i.apply(this,[e,e.pageX-g.left||0,e.pageY-g.top||0]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)g=this._updateRatio(g,e);g=this._respectSize(g,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(g);this._trigger("resize",e,this.ui());return false}, -_mouseStop:function(e){this.resizing=false;var h=this.options,g=this;if(this._helper){var i=this._proportionallyResizeElements,b=i.length&&/textarea/i.test(i[0].nodeName);i=b&&a.ui.hasScroll(i[0],"left")?0:g.sizeDiff.height;b=b?0:g.sizeDiff.width;b={width:g.helper.width()-b,height:g.helper.height()-i};i=parseInt(g.element.css("left"),10)+(g.position.left-g.originalPosition.left)||null;var f=parseInt(g.element.css("top"),10)+(g.position.top-g.originalPosition.top)||null;h.animate||this.element.css(a.extend(b, -{top:f,left:i}));g.helper.height(g.size.height);g.helper.width(g.size.width);this._helper&&!h.animate&&this._proportionallyResize()}a("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",e);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(e){var h=this.options,g,i,b;h={minWidth:c(h.minWidth)?h.minWidth:0,maxWidth:c(h.maxWidth)?h.maxWidth:Infinity,minHeight:c(h.minHeight)?h.minHeight:0,maxHeight:c(h.maxHeight)?h.maxHeight: -Infinity};if(this._aspectRatio||e){e=h.minHeight*this.aspectRatio;i=h.minWidth/this.aspectRatio;g=h.maxHeight*this.aspectRatio;b=h.maxWidth/this.aspectRatio;if(e>h.minWidth)h.minWidth=e;if(i>h.minHeight)h.minHeight=i;if(ge.width,j=c(e.height)&&h.minHeight&&h.minHeight>e.height;if(f)e.width=h.minWidth;if(j)e.height=h.minHeight;if(i)e.width=h.maxWidth;if(b)e.height=h.maxHeight;var l=this.originalPosition.left+this.originalSize.width,o=this.position.top+this.size.height,n=/sw|nw|w/.test(g);g=/nw|ne|n/.test(g);if(f&&n)e.left=l-h.minWidth;if(i&&n)e.left=l-h.maxWidth;if(j&&g)e.top=o-h.minHeight;if(b&&g)e.top=o-h.maxHeight;if((h=!e.width&&!e.height)&&!e.left&&e.top)e.top=null;else if(h&&!e.top&&e.left)e.left= -null;return e},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var e=this.helper||this.element,h=0;h');var h=a.browser.msie&&a.browser.version<7,g=h?1:0;h=h?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+ -h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++e.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,h){return{width:this.originalSize.width+h}},w:function(e,h){return{left:this.originalPosition.left+h,width:this.originalSize.width-h}},n:function(e,h,g){return{top:this.originalPosition.top+g,height:this.originalSize.height-g}},s:function(e,h,g){return{height:this.originalSize.height+ -g}},se:function(e,h,g){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,h,g]))},sw:function(e,h,g){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,h,g]))},ne:function(e,h,g){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,h,g]))},nw:function(e,h,g){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,h,g]))}},_propagate:function(e,h){a.ui.plugin.call(this,e,[h,this.ui()]); -e!="resize"&&this._trigger(e,h,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});a.extend(a.ui.resizable,{version:"1.8.16"});a.ui.plugin.add("resizable","alsoResize",{start:function(){var e=a(this).data("resizable").options,h=function(g){a(g).each(function(){var i=a(this);i.data("resizable-alsoresize",{width:parseInt(i.width(), -10),height:parseInt(i.height(),10),left:parseInt(i.css("left"),10),top:parseInt(i.css("top"),10),position:i.css("position")})})};if(typeof e.alsoResize=="object"&&!e.alsoResize.parentNode)if(e.alsoResize.length){e.alsoResize=e.alsoResize[0];h(e.alsoResize)}else a.each(e.alsoResize,function(g){h(g)});else h(e.alsoResize)},resize:function(e,h){var g=a(this).data("resizable");e=g.options;var i=g.originalSize,b=g.originalPosition,f={height:g.size.height-i.height||0,width:g.size.width-i.width||0,top:g.position.top- -b.top||0,left:g.position.left-b.left||0},j=function(l,o){a(l).each(function(){var n=a(this),k=a(this).data("resizable-alsoresize"),m={},p=o&&o.length?o:n.parents(h.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(p,function(q,s){if((q=(k[s]||0)+(f[s]||0))&&q>=0)m[s]=q||null});if(a.browser.opera&&/relative/.test(n.css("position"))){g._revertToRelativePosition=true;n.css({position:"absolute",top:"auto",left:"auto"})}n.css(m)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType? -a.each(e.alsoResize,function(l,o){j(l,o)}):j(e.alsoResize)},stop:function(){var e=a(this).data("resizable"),h=e.options,g=function(i){a(i).each(function(){var b=a(this);b.css({position:b.data("resizable-alsoresize").position})})};if(e._revertToRelativePosition){e._revertToRelativePosition=false;typeof h.alsoResize=="object"&&!h.alsoResize.nodeType?a.each(h.alsoResize,function(i){g(i)}):g(h.alsoResize)}a(this).removeData("resizable-alsoresize")}});a.ui.plugin.add("resizable","animate",{stop:function(e){var h= -a(this).data("resizable"),g=h.options,i=h._proportionallyResizeElements,b=i.length&&/textarea/i.test(i[0].nodeName),f=b&&a.ui.hasScroll(i[0],"left")?0:h.sizeDiff.height;b={width:h.size.width-(b?0:h.sizeDiff.width),height:h.size.height-f};f=parseInt(h.element.css("left"),10)+(h.position.left-h.originalPosition.left)||null;var j=parseInt(h.element.css("top"),10)+(h.position.top-h.originalPosition.top)||null;h.element.animate(a.extend(b,j&&f?{top:j,left:f}:{}),{duration:g.animateDuration,easing:g.animateEasing, -step:function(){var l={width:parseInt(h.element.css("width"),10),height:parseInt(h.element.css("height"),10),top:parseInt(h.element.css("top"),10),left:parseInt(h.element.css("left"),10)};i&&i.length&&a(i[0]).css({width:l.width,height:l.height});h._updateCache(l);h._propagate("resize",e)}})}});a.ui.plugin.add("resizable","containment",{start:function(){var e=a(this).data("resizable"),h=e.element,g=e.options.containment;if(h=g instanceof a?g.get(0):/parent/.test(g)?h.parent().get(0):g){e.containerElement= -a(h);if(/document/.test(g)||g==document){e.containerOffset={left:0,top:0};e.containerPosition={left:0,top:0};e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight}}else{var i=a(h),b=[];a(["Top","Right","Left","Bottom"]).each(function(l,o){b[l]=d(i.css("padding"+o))});e.containerOffset=i.offset();e.containerPosition=i.position();e.containerSize={height:i.innerHeight()-b[3],width:i.innerWidth()-b[1]};g=e.containerOffset; -var f=e.containerSize.height,j=e.containerSize.width;j=a.ui.hasScroll(h,"left")?h.scrollWidth:j;f=a.ui.hasScroll(h)?h.scrollHeight:f;e.parentData={element:h,left:g.left,top:g.top,width:j,height:f}}}},resize:function(e){var h=a(this).data("resizable"),g=h.options,i=h.containerOffset,b=h.position;e=h._aspectRatio||e.shiftKey;var f={top:0,left:0},j=h.containerElement;if(j[0]!=document&&/static/.test(j.css("position")))f=i;if(b.left<(h._helper?i.left:0)){h.size.width+=h._helper?h.position.left-i.left: -h.position.left-f.left;if(e)h.size.height=h.size.width/g.aspectRatio;h.position.left=g.helper?i.left:0}if(b.top<(h._helper?i.top:0)){h.size.height+=h._helper?h.position.top-i.top:h.position.top;if(e)h.size.width=h.size.height*g.aspectRatio;h.position.top=h._helper?i.top:0}h.offset.left=h.parentData.left+h.position.left;h.offset.top=h.parentData.top+h.position.top;g=Math.abs((h._helper?h.offset.left-f.left:h.offset.left-f.left)+h.sizeDiff.width);i=Math.abs((h._helper?h.offset.top-f.top:h.offset.top- -i.top)+h.sizeDiff.height);b=h.containerElement.get(0)==h.element.parent().get(0);f=/relative|absolute/.test(h.containerElement.css("position"));if(b&&f)g-=h.parentData.left;if(g+h.size.width>=h.parentData.width){h.size.width=h.parentData.width-g;if(e)h.size.height=h.size.width/h.aspectRatio}if(i+h.size.height>=h.parentData.height){h.size.height=h.parentData.height-i;if(e)h.size.width=h.size.height*h.aspectRatio}},stop:function(){var e=a(this).data("resizable"),h=e.options,g=e.containerOffset,i=e.containerPosition, -b=e.containerElement,f=a(e.helper),j=f.offset(),l=f.outerWidth()-e.sizeDiff.width;f=f.outerHeight()-e.sizeDiff.height;e._helper&&!h.animate&&/relative/.test(b.css("position"))&&a(this).css({left:j.left-i.left-g.left,width:l,height:f});e._helper&&!h.animate&&/static/.test(b.css("position"))&&a(this).css({left:j.left-i.left-g.left,width:l,height:f})}});a.ui.plugin.add("resizable","ghost",{start:function(){var e=a(this).data("resizable"),h=e.options,g=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25, -display:"block",position:"relative",height:g.height,width:g.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");e.ghost.appendTo(e.helper)},resize:function(){var e=a(this).data("resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=a(this).data("resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}});a.ui.plugin.add("resizable","grid",{resize:function(){var e= -a(this).data("resizable"),h=e.options,g=e.size,i=e.originalSize,b=e.originalPosition,f=e.axis;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var j=Math.round((g.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1);h=Math.round((g.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(f)){e.size.width=i.width+j;e.size.height=i.height+h}else if(/^(ne)$/.test(f)){e.size.width=i.width+j;e.size.height=i.height+h;e.position.top=b.top-h}else{if(/^(sw)$/.test(f)){e.size.width=i.width+j;e.size.height= -i.height+h}else{e.size.width=i.width+j;e.size.height=i.height+h;e.position.top=b.top-h}e.position.left=b.left-j}}});var d=function(e){return parseInt(e,10)||0},c=function(e){return!isNaN(parseInt(e,10))}})(jQuery); -(function(a){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var d=this;this.element.addClass("ui-selectable");this.dragged=false;var c;this.refresh=function(){c=a(d.options.filter,d.element[0]);c.each(function(){var e=a(this),h=e.offset();a.data(this,"selectable-item",{element:this,$element:e,left:h.left,top:h.top,right:h.left+e.outerWidth(),bottom:h.top+e.outerHeight(),startselected:false,selected:e.hasClass("ui-selected"), -selecting:e.hasClass("ui-selecting"),unselecting:e.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=a("
    ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(d){var c=this;this.opos=[d.pageX, -d.pageY];if(!this.options.disabled){var e=this.options;this.selectees=a(e.filter,this.element[0]);this._trigger("start",d);a(e.appendTo).append(this.helper);this.helper.css({left:d.clientX,top:d.clientY,width:0,height:0});e.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var h=a.data(this,"selectable-item");h.startselected=true;if(!d.metaKey){h.$element.removeClass("ui-selected");h.selected=false;h.$element.addClass("ui-unselecting");h.unselecting=true;c._trigger("unselecting", -d,{unselecting:h.element})}});a(d.target).parents().andSelf().each(function(){var h=a.data(this,"selectable-item");if(h){var g=!d.metaKey||!h.$element.hasClass("ui-selected");h.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");h.unselecting=!g;h.selecting=g;(h.selected=g)?c._trigger("selecting",d,{selecting:h.element}):c._trigger("unselecting",d,{unselecting:h.element});return false}})}},_mouseDrag:function(d){var c=this;this.dragged=true;if(!this.options.disabled){var e= -this.options,h=this.opos[0],g=this.opos[1],i=d.pageX,b=d.pageY;if(h>i){var f=i;i=h;h=f}if(g>b){f=b;b=g;g=f}this.helper.css({left:h,top:g,width:i-h,height:b-g});this.selectees.each(function(){var j=a.data(this,"selectable-item");if(!(!j||j.element==c.element[0])){var l=false;if(e.tolerance=="touch")l=!(j.left>i||j.rightb||j.bottomh&&j.rightg&&j.bottom *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var d=this.options;this.containerCache={};this.element.addClass("ui-sortable"); -this.refresh();this.floating=this.items.length?d.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var d=this.items.length-1;d>=0;d--)this.items[d].item.removeData("sortable-item");return this},_setOption:function(d,c){if(d=== -"disabled"){this.options[d]=c;this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")}else a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(d,c){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(d);var e=null,h=this;a(d.target).parents().each(function(){if(a.data(this,"sortable-item")==h){e=a(this);return false}});if(a.data(d.target,"sortable-item")==h)e=a(d.target);if(!e)return false;if(this.options.handle&& -!c){var g=false;a(this.options.handle,e).find("*").andSelf().each(function(){if(this==d.target)g=true});if(!g)return false}this.currentItem=e;this._removeCurrentsFromItems();return true},_mouseStart:function(d,c,e){c=this.options;var h=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(d);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top, -left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:d.pageX-this.offset.left,top:d.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(d);this.originalPageX=d.pageX;this.originalPageY=d.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]}; -this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();c.containment&&this._setContainment();if(c.cursor){if(a("body").css("cursor"))this._storedCursor=a("body").css("cursor");a("body").css("cursor",c.cursor)}if(c.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",c.opacity)}if(c.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",c.zIndex)}if(this.scrollParent[0]!= -document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",d,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!e)for(e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("activate",d,h._uiHash(this));if(a.ui.ddmanager)a.ui.ddmanager.current=this;a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,d);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(d); -return true},_mouseDrag:function(d){this.position=this._generatePosition(d);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var c=this.options,e=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-d.pageY=0;c--){e=this.items[c];var h=e.item[0],g=this._intersectsWithPointer(e);if(g)if(h!=this.currentItem[0]&&this.placeholder[g==1?"next":"prev"]()[0]!=h&&!a.ui.contains(this.placeholder[0],h)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0], -h):true)){this.direction=g==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e))this._rearrange(d,e);else break;this._trigger("change",d,this._uiHash());break}}this._contactContainers(d);a.ui.ddmanager&&a.ui.ddmanager.drag(this,d);this._trigger("sort",d,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(d,c){if(d){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,d);if(this.options.revert){var e=this;c=e.placeholder.offset(); -e.reverting=true;a(this.helper).animate({left:c.left-this.offset.parent.left-e.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:c.top-this.offset.parent.top-e.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){e._clear(d)})}else this._clear(d,c);return false}},cancel:function(){var d=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"): -this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,d._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,d._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();a.extend(this,{helper:null, -dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(d){var c=this._getItemsAsjQuery(d&&d.connected),e=[];d=d||{};a(c).each(function(){var h=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||/(.+)[-=_](.+)/);if(h)e.push((d.key||h[1]+"[]")+"="+(d.key&&d.expression?h[1]:h[2]))});!e.length&&d.key&&e.push(d.key+"=");return e.join("&")}, -toArray:function(d){var c=this._getItemsAsjQuery(d&&d.connected),e=[];d=d||{};c.each(function(){e.push(a(d.item||this).attr(d.attribute||"id")||"")});return e},_intersectsWith:function(d){var c=this.positionAbs.left,e=c+this.helperProportions.width,h=this.positionAbs.top,g=h+this.helperProportions.height,i=d.left,b=i+d.width,f=d.top,j=f+d.height,l=this.offset.click.top,o=this.offset.click.left;l=h+l>f&&h+li&&c+od[this.floating?"width":"height"]?l:i0?"down":"up")},_getDragHorizontalDirection:function(){var d=this.positionAbs.left-this.lastPositionAbs.left;return d!=0&&(d>0?"right":"left")},refresh:function(d){this._refreshItems(d);this.refreshPositions();return this},_connectWith:function(){var d=this.options;return d.connectWith.constructor==String?[d.connectWith]:d.connectWith},_getItemsAsjQuery:function(d){var c=[],e=[],h=this._connectWith(); -if(h&&d)for(d=h.length-1;d>=0;d--)for(var g=a(h[d]),i=g.length-1;i>=0;i--){var b=a.data(g[i],"sortable");if(b&&b!=this&&!b.options.disabled)e.push([a.isFunction(b.options.items)?b.options.items.call(b.element):a(b.options.items,b.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),b])}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), -this]);for(d=e.length-1;d>=0;d--)e[d][0].each(function(){c.push(this)});return a(c)},_removeCurrentsFromItems:function(){for(var d=this.currentItem.find(":data(sortable-item)"),c=0;c=0;g--)for(var i=a(h[g]),b=i.length-1;b>=0;b--){var f=a.data(i[b],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element[0],d,{item:this.currentItem}):a(f.options.items,f.element),f]);this.containers.push(f)}}for(g=e.length-1;g>=0;g--){d=e[g][1];h=e[g][0];b=0;for(i=h.length;b=0;c--){var e=this.items[c];if(!(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0])){var h=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!d){e.width=h.outerWidth();e.height=h.outerHeight()}h=h.offset();e.left=h.left;e.top=h.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(c= -this.containers.length-1;c>=0;c--){h=this.containers[c].element.offset();this.containers[c].containerCache.left=h.left;this.containers[c].containerCache.top=h.top;this.containers[c].containerCache.width=this.containers[c].element.outerWidth();this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(d){var c=d||this,e=c.options;if(!e.placeholder||e.placeholder.constructor==String){var h=e.placeholder;e.placeholder={element:function(){var g= -a(document.createElement(c.currentItem[0].nodeName)).addClass(h||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!h)g.style.visibility="hidden";return g},update:function(g,i){if(!(h&&!e.forcePlaceholderSize)){i.height()||i.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10));i.width()||i.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")|| -0,10))}}}}c.placeholder=a(e.placeholder.element.call(c.element,c.currentItem));c.currentItem.after(c.placeholder);e.placeholder.update(c,c.placeholder)},_contactContainers:function(d){for(var c=null,e=null,h=this.containers.length-1;h>=0;h--)if(!a.ui.contains(this.currentItem[0],this.containers[h].element[0]))if(this._intersectsWith(this.containers[h].containerCache)){if(!(c&&a.ui.contains(this.containers[h].element[0],c.element[0]))){c=this.containers[h];e=h}}else if(this.containers[h].containerCache.over){this.containers[h]._trigger("out", -d,this._uiHash(this));this.containers[h].containerCache.over=0}if(c)if(this.containers.length===1){this.containers[e]._trigger("over",d,this._uiHash(this));this.containers[e].containerCache.over=1}else if(this.currentContainer!=this.containers[e]){c=1E4;h=null;for(var g=this.positionAbs[this.containers[e].floating?"left":"top"],i=this.items.length-1;i>=0;i--)if(a.ui.contains(this.containers[e].element[0],this.items[i].item[0])){var b=this.items[i][this.containers[e].floating?"left":"top"];if(Math.abs(b- -g)this.containment[2])g=this.containment[2]+this.offset.click.left;if(d.pageY-this.offset.click.top>this.containment[3])i=this.containment[3]+this.offset.click.top}if(c.grid){i=this.originalPageY+Math.round((i- -this.originalPageY)/c.grid[1])*c.grid[1];i=this.containment?!(i-this.offset.click.topthis.containment[3])?i:!(i-this.offset.click.topthis.containment[2])?g:!(g-this.offset.click.left=0;h--)if(a.ui.contains(this.containers[h].element[0],this.currentItem[0])&&!c){e.push(function(g){return function(i){g._trigger("receive",i,this._uiHash(this))}}.call(this,this.containers[h]));e.push(function(g){return function(i){g._trigger("update",i,this._uiHash(this))}}.call(this,this.containers[h]))}}for(h=this.containers.length-1;h>=0;h--){c||e.push(function(g){return function(i){g._trigger("deactivate",i,this._uiHash(this))}}.call(this, -this.containers[h]));if(this.containers[h].containerCache.over){e.push(function(g){return function(i){g._trigger("out",i,this._uiHash(this))}}.call(this,this.containers[h]));this.containers[h].containerCache.over=0}}this._storedCursor&&a("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop", -d,this._uiHash());for(h=0;h").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}), -p=document.activeElement;n.wrap(m);if(n[0]===p||a.contains(n[0],p))a(p).focus();m=n.parent();if(n.css("position")=="static"){m.css({position:"relative"});n.css({position:"relative"})}else{a.extend(k,{position:n.css("position"),zIndex:n.css("z-index")});a.each(["top","left","bottom","right"],function(q,s){k[s]=n.css(s);if(isNaN(parseInt(k[s],10)))k[s]="auto"});n.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return m.css(k).show()},removeWrapper:function(n){var k,m=document.activeElement; -if(n.parent().is(".ui-effects-wrapper")){k=n.parent().replaceWith(n);if(n[0]===m||a.contains(n[0],m))a(m).focus();return k}return n},setTransition:function(n,k,m,p){p=p||{};a.each(k,function(q,s){unit=n.cssUnit(s);if(unit[0]>0)p[s]=unit[0]*m+unit[1]});return p}});a.fn.extend({effect:function(n){var k=b.apply(this,arguments),m={options:k[1],duration:k[2],callback:k[3]};k=m.options.mode;var p=a.effects[n];if(a.fx.off||!p)return k?this[k](m.duration,m.callback):this.each(function(){m.callback&&m.callback.call(this)}); -return p.call(this,m)},_show:a.fn.show,show:function(n){if(f(n))return this._show.apply(this,arguments);else{var k=b.apply(this,arguments);k[1].mode="show";return this.effect.apply(this,k)}},_hide:a.fn.hide,hide:function(n){if(f(n))return this._hide.apply(this,arguments);else{var k=b.apply(this,arguments);k[1].mode="hide";return this.effect.apply(this,k)}},__toggle:a.fn.toggle,toggle:function(n){if(f(n)||typeof n==="boolean"||a.isFunction(n))return this.__toggle.apply(this,arguments);else{var k=b.apply(this, -arguments);k[1].mode="toggle";return this.effect.apply(this,k)}},cssUnit:function(n){var k=this.css(n),m=[];a.each(["em","px","%","pt"],function(p,q){if(k.indexOf(q)>0)m=[parseFloat(k),q]});return m}});a.easing.jswing=a.easing.swing;a.extend(a.easing,{def:"easeOutQuad",swing:function(n,k,m,p,q){return a.easing[a.easing.def](n,k,m,p,q)},easeInQuad:function(n,k,m,p,q){return p*(k/=q)*k+m},easeOutQuad:function(n,k,m,p,q){return-p*(k/=q)*(k-2)+m},easeInOutQuad:function(n,k,m,p,q){if((k/=q/2)<1)return p/ -2*k*k+m;return-p/2*(--k*(k-2)-1)+m},easeInCubic:function(n,k,m,p,q){return p*(k/=q)*k*k+m},easeOutCubic:function(n,k,m,p,q){return p*((k=k/q-1)*k*k+1)+m},easeInOutCubic:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k+m;return p/2*((k-=2)*k*k+2)+m},easeInQuart:function(n,k,m,p,q){return p*(k/=q)*k*k*k+m},easeOutQuart:function(n,k,m,p,q){return-p*((k=k/q-1)*k*k*k-1)+m},easeInOutQuart:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k*k+m;return-p/2*((k-=2)*k*k*k-2)+m},easeInQuint:function(n,k,m, -p,q){return p*(k/=q)*k*k*k*k+m},easeOutQuint:function(n,k,m,p,q){return p*((k=k/q-1)*k*k*k*k+1)+m},easeInOutQuint:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k*k*k+m;return p/2*((k-=2)*k*k*k*k+2)+m},easeInSine:function(n,k,m,p,q){return-p*Math.cos(k/q*(Math.PI/2))+p+m},easeOutSine:function(n,k,m,p,q){return p*Math.sin(k/q*(Math.PI/2))+m},easeInOutSine:function(n,k,m,p,q){return-p/2*(Math.cos(Math.PI*k/q)-1)+m},easeInExpo:function(n,k,m,p,q){return k==0?m:p*Math.pow(2,10*(k/q-1))+m},easeOutExpo:function(n, -k,m,p,q){return k==q?m+p:p*(-Math.pow(2,-10*k/q)+1)+m},easeInOutExpo:function(n,k,m,p,q){if(k==0)return m;if(k==q)return m+p;if((k/=q/2)<1)return p/2*Math.pow(2,10*(k-1))+m;return p/2*(-Math.pow(2,-10*--k)+2)+m},easeInCirc:function(n,k,m,p,q){return-p*(Math.sqrt(1-(k/=q)*k)-1)+m},easeOutCirc:function(n,k,m,p,q){return p*Math.sqrt(1-(k=k/q-1)*k)+m},easeInOutCirc:function(n,k,m,p,q){if((k/=q/2)<1)return-p/2*(Math.sqrt(1-k*k)-1)+m;return p/2*(Math.sqrt(1-(k-=2)*k)+1)+m},easeInElastic:function(n,k,m, -p,q){n=1.70158;var s=0,r=p;if(k==0)return m;if((k/=q)==1)return m+p;s||(s=q*0.3);if(r").css({position:"absolute",visibility:"visible",left:-j*(i/e),top:-f*(b/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:i/e,height:b/c,left:g.left+j*(i/e)+(d.options.mode=="show"?(j-Math.floor(e/2))*(i/e):0),top:g.top+f*(b/c)+(d.options.mode=="show"?(f-Math.floor(c/2))*(b/c):0),opacity:d.options.mode=="show"?0:1}).animate({left:g.left+j*(i/e)+(d.options.mode=="show"?0:(j-Math.floor(e/2))*(i/e)),top:g.top+ -f*(b/c)+(d.options.mode=="show"?0:(f-Math.floor(c/2))*(b/c)),opacity:d.options.mode=="show"?1:0},d.duration||500);setTimeout(function(){d.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();d.callback&&d.callback.apply(h[0]);h.dequeue();a("div.ui-effects-explode").remove()},d.duration||500)})}})(jQuery); -(function(a){a.effects.fade=function(d){return this.queue(function(){var c=a(this),e=a.effects.setMode(c,d.options.mode||"hide");c.animate({opacity:e},{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); -(function(a){a.effects.fold=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.size||15,i=!!d.options.horizFirst,b=d.duration?d.duration/2:a.fx.speeds._default/2;a.effects.save(c,e);c.show();var f=a.effects.createWrapper(c).css({overflow:"hidden"}),j=h=="show"!=i,l=j?["width","height"]:["height","width"];j=j?[f.width(),f.height()]:[f.height(),f.width()];var o=/([0-9]+)%/.exec(g);if(o)g=parseInt(o[1], -10)/100*j[h=="hide"?0:1];if(h=="show")f.css(i?{height:0,width:g}:{height:g,width:0});i={};o={};i[l[0]]=h=="show"?j[0]:g;o[l[1]]=h=="show"?j[1]:0;f.animate(i,b,d.options.easing).animate(o,b,d.options.easing,function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery); -(function(a){a.effects.highlight=function(d){return this.queue(function(){var c=a(this),e=["backgroundImage","backgroundColor","opacity"],h=a.effects.setMode(c,d.options.mode||"show"),g={backgroundColor:c.css("backgroundColor")};if(h=="hide")g.opacity=0;a.effects.save(c,e);c.show().css({backgroundImage:"none",backgroundColor:d.options.color||"#ffff99"}).animate(g,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);h=="show"&&!a.support.opacity&& -this.style.removeAttribute("filter");d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); -(function(a){a.effects.pulsate=function(d){return this.queue(function(){var c=a(this),e=a.effects.setMode(c,d.options.mode||"show");times=(d.options.times||5)*2-1;duration=d.duration?d.duration/2:a.fx.speeds._default/2;isVisible=c.is(":visible");animateTo=0;if(!isVisible){c.css("opacity",0).show();animateTo=1}if(e=="hide"&&isVisible||e=="show"&&!isVisible)times--;for(e=0;e').appendTo(document.body).addClass(d.options.className).css({top:h.top,left:h.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(e,d.duration,d.options.easing,function(){g.remove();d.callback&&d.callback.apply(c[0],arguments); -c.dequeue()})})}})(jQuery); -(function(a){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var d=this,c=d.options;d.running=0;d.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");d.headers= -d.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||a(this).removeClass("ui-state-focus")});d.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); -if(c.navigation){var e=d.element.find("a").filter(c.navigationFilter).eq(0);if(e.length){var h=e.closest(".ui-accordion-header");d.active=h.length?h:e.closest(".ui-accordion-content").prev()}}d.active=d._findActive(d.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");d.active.next().addClass("ui-accordion-content-active");d._createIcons();d.resize();d.element.attr("role","tablist");d.headers.attr("role","tab").bind("keydown.accordion", -function(g){return d._keydown(g)}).next().attr("role","tabpanel");d.headers.not(d.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();d.active.length?d.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):d.headers.eq(0).attr("tabIndex",0);a.browser.safari||d.headers.find("a").attr("tabIndex",-1);c.event&&d.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(g){d._clickHandler.call(d,g,this);g.preventDefault()})},_createIcons:function(){var d= -this.options;if(d.icons){a("").addClass("ui-icon "+d.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(d.icons.header).toggleClass(d.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var d=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"); -this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(d.autoHeight||d.fillHeight)c.css("height","");return a.Widget.prototype.destroy.call(this)},_setOption:function(d,c){a.Widget.prototype._setOption.apply(this,arguments);d=="active"&&this.activate(c);if(d=="icons"){this._destroyIcons(); -c&&this._createIcons()}if(d=="disabled")this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(d){if(!(this.options.disabled||d.altKey||d.ctrlKey)){var c=a.ui.keyCode,e=this.headers.length,h=this.headers.index(d.target),g=false;switch(d.keyCode){case c.RIGHT:case c.DOWN:g=this.headers[(h+1)%e];break;case c.LEFT:case c.UP:g=this.headers[(h-1+e)%e];break;case c.SPACE:case c.ENTER:this._clickHandler({target:d.target},d.target); -d.preventDefault()}if(g){a(d.target).attr("tabIndex",-1);a(g).attr("tabIndex",0);g.focus();return false}return true}},resize:function(){var d=this.options,c;if(d.fillSpace){if(a.browser.msie){var e=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height();a.browser.msie&&this.element.parent().css("overflow",e);this.headers.each(function(){c-=a(this).outerHeight(true)});this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+ -a(this).height()))}).css("overflow","auto")}else if(d.autoHeight){c=0;this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c)}return this},activate:function(d){this.options.active=d;d=this._findActive(d)[0];this._clickHandler({target:d},d);return this},_findActive:function(d){return d?typeof d==="number"?this.headers.filter(":eq("+d+")"):this.headers.not(this.headers.not(d)):d===false?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(d,c){var e=this.options; -if(!e.disabled)if(d.target){d=a(d.currentTarget||c);c=d[0]===this.active[0];e.active=e.collapsible&&c?false:this.headers.index(d);if(!(this.running||!e.collapsible&&c)){var h=this.active;f=d.next();i=this.active.next();b={options:e,newHeader:c&&e.collapsible?a([]):d,oldHeader:this.active,newContent:c&&e.collapsible?a([]):f,oldContent:i};var g=this.headers.index(this.active[0])>this.headers.index(d[0]);this.active=c?a([]):d;this._toggle(f,i,b,c,g);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(e.icons.headerSelected).addClass(e.icons.header); -if(!c){d.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(e.icons.header).addClass(e.icons.headerSelected);d.next().addClass("ui-accordion-content-active")}}}else if(e.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(e.icons.headerSelected).addClass(e.icons.header);this.active.next().addClass("ui-accordion-content-active");var i=this.active.next(), -b={options:e,newHeader:a([]),oldHeader:e.active,newContent:a([]),oldContent:i},f=this.active=a([]);this._toggle(f,i,b)}},_toggle:function(d,c,e,h,g){var i=this,b=i.options;i.toShow=d;i.toHide=c;i.data=e;var f=function(){if(i)return i._completed.apply(i,arguments)};i._trigger("changestart",null,i.data);i.running=c.size()===0?d.size():c.size();if(b.animated){e={};e=b.collapsible&&h?{toShow:a([]),toHide:c,complete:f,down:g,autoHeight:b.autoHeight||b.fillSpace}:{toShow:d,toHide:c,complete:f,down:g,autoHeight:b.autoHeight|| -b.fillSpace};if(!b.proxied)b.proxied=b.animated;if(!b.proxiedDuration)b.proxiedDuration=b.duration;b.animated=a.isFunction(b.proxied)?b.proxied(e):b.proxied;b.duration=a.isFunction(b.proxiedDuration)?b.proxiedDuration(e):b.proxiedDuration;h=a.ui.accordion.animations;var j=b.duration,l=b.animated;if(l&&!h[l]&&!a.easing[l])l="slide";h[l]||(h[l]=function(o){this.slide(o,{easing:l,duration:j||700})});h[l](e)}else{if(b.collapsible&&h)d.toggle();else{c.hide();d.show()}f(true)}c.prev().attr({"aria-expanded":"false", -"aria-selected":"false",tabIndex:-1}).blur();d.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(d){this.running=d?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});a.extend(a.ui.accordion,{version:"1.8.16", -animations:{slide:function(d,c){d=a.extend({easing:"swing",duration:300},d,c);if(d.toHide.size())if(d.toShow.size()){var e=d.toShow.css("overflow"),h=0,g={},i={},b;c=d.toShow;b=c[0].style.width;c.width(parseInt(c.parent().width(),10)-parseInt(c.css("paddingLeft"),10)-parseInt(c.css("paddingRight"),10)-(parseInt(c.css("borderLeftWidth"),10)||0)-(parseInt(c.css("borderRightWidth"),10)||0));a.each(["height","paddingTop","paddingBottom"],function(f,j){i[j]="hide";f=(""+a.css(d.toShow[0],j)).match(/^([\d+-.]+)(.*)$/); -g[j]={value:f[1],unit:f[2]||"px"}});d.toShow.css({height:0,overflow:"hidden"}).show();d.toHide.filter(":hidden").each(d.complete).end().filter(":visible").animate(i,{step:function(f,j){if(j.prop=="height")h=j.end-j.start===0?0:(j.now-j.start)/(j.end-j.start);d.toShow[0].style[j.prop]=h*g[j.prop].value+g[j.prop].unit},duration:d.duration,easing:d.easing,complete:function(){d.autoHeight||d.toShow.css("height","");d.toShow.css({width:b,overflow:e});d.complete()}})}else d.toHide.animate({height:"hide", -paddingTop:"hide",paddingBottom:"hide"},d);else d.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},d)},bounceslide:function(d){this.slide(d,{easing:d.down?"easeOutBounce":"swing",duration:d.down?1E3:200})}}})})(jQuery); -(function(a){var d=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var c=this,e=this.element[0].ownerDocument,h;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(g){if(!(c.options.disabled||c.element.propAttr("readOnly"))){h= -false;var i=a.ui.keyCode;switch(g.keyCode){case i.PAGE_UP:c._move("previousPage",g);break;case i.PAGE_DOWN:c._move("nextPage",g);break;case i.UP:c._move("previous",g);g.preventDefault();break;case i.DOWN:c._move("next",g);g.preventDefault();break;case i.ENTER:case i.NUMPAD_ENTER:if(c.menu.active){h=true;g.preventDefault()}case i.TAB:if(!c.menu.active)return;c.menu.select(g);break;case i.ESCAPE:c.element.val(c.term);c.close(g);break;default:clearTimeout(c.searching);c.searching=setTimeout(function(){if(c.term!= -c.element.val()){c.selectedItem=null;c.search(null,g)}},c.options.delay);break}}}).bind("keypress.autocomplete",function(g){if(h){h=false;g.preventDefault()}}).bind("focus.autocomplete",function(){if(!c.options.disabled){c.selectedItem=null;c.previous=c.element.val()}}).bind("blur.autocomplete",function(g){if(!c.options.disabled){clearTimeout(c.searching);c.closing=setTimeout(function(){c.close(g);c._change(g)},150)}});this._initSource();this.response=function(){return c._response.apply(c,arguments)}; -this.menu=a("
      ").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",e)[0]).mousedown(function(g){var i=c.menu.element[0];a(g.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(b){b.target!==c.element[0]&&b.target!==i&&!a.ui.contains(i,b.target)&&c.close()})},1);setTimeout(function(){clearTimeout(c.closing)},13)}).menu({focus:function(g,i){i=i.item.data("item.autocomplete");false!==c._trigger("focus",g,{item:i})&&/^key/.test(g.originalEvent.type)&& -c.element.val(i.value)},selected:function(g,i){var b=i.item.data("item.autocomplete"),f=c.previous;if(c.element[0]!==e.activeElement){c.element.focus();c.previous=f;setTimeout(function(){c.previous=f;c.selectedItem=b},1)}false!==c._trigger("select",g,{item:b})&&c.element.val(b.value);c.term=c.element.val();c.close(g);c.selectedItem=b},blur:function(){c.menu.element.is(":visible")&&c.element.val()!==c.term&&c.element.val(c.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"); -a.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();a.Widget.prototype.destroy.call(this)},_setOption:function(c,e){a.Widget.prototype._setOption.apply(this,arguments);c==="source"&&this._initSource();if(c==="appendTo")this.menu.element.appendTo(a(e||"body",this.element[0].ownerDocument)[0]);c==="disabled"&& -e&&this.xhr&&this.xhr.abort()},_initSource:function(){var c=this,e,h;if(a.isArray(this.options.source)){e=this.options.source;this.source=function(g,i){i(a.ui.autocomplete.filter(e,g.term))}}else if(typeof this.options.source==="string"){h=this.options.source;this.source=function(g,i){c.xhr&&c.xhr.abort();c.xhr=a.ajax({url:h,data:g,dataType:"json",autocompleteRequest:++d,success:function(b){this.autocompleteRequest===d&&i(b)},error:function(){this.autocompleteRequest===d&&i([])}})}}else this.source= -this.options.source},search:function(c,e){c=c!=null?c:this.element.val();this.term=this.element.val();if(c.length").data("item.autocomplete",e).append(a("").text(e.label)).appendTo(c)},_move:function(c,e){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(c)||this.menu.last()&&/^next/.test(c)){this.element.val(this.term);this.menu.deactivate()}else this.menu[c](e);else this.search(null,e)},widget:function(){return this.menu.element}});a.extend(a.ui.autocomplete,{escapeRegex:function(c){return c.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, -"\\$&")},filter:function(c,e){var h=new RegExp(a.ui.autocomplete.escapeRegex(e),"i");return a.grep(c,function(g){return h.test(g.label||g.value||g)})}})})(jQuery); -(function(a){a.widget("ui.menu",{_create:function(){var d=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){if(a(c.target).closest(".ui-menu-item a").length){c.preventDefault();d.select(c)}});this.refresh()},refresh:function(){var d=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", --1).mouseenter(function(c){d.activate(c,a(this).parent())}).mouseleave(function(){d.deactivate()})},activate:function(d,c){this.deactivate();if(this.hasScroll()){var e=c.offset().top-this.element.offset().top,h=this.element.scrollTop(),g=this.element.height();if(e<0)this.element.scrollTop(h+e);else e>=g&&this.element.scrollTop(h+e-g+c.height())}this.active=c.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",d,{item:c})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id"); -this._trigger("blur");this.active=null}},next:function(d){this.move("next",".ui-menu-item:first",d)},previous:function(d){this.move("prev",".ui-menu-item:last",d)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(d,c,e){if(this.active){d=this.active[d+"All"](".ui-menu-item").eq(0);d.length?this.activate(e,d):this.activate(e,this.element.children(c))}else this.activate(e, -this.element.children(c))},nextPage:function(d){if(this.hasScroll())if(!this.active||this.last())this.activate(d,this.element.children(".ui-menu-item:first"));else{var c=this.active.offset().top,e=this.element.height(),h=this.element.children(".ui-menu-item").filter(function(){var g=a(this).offset().top-c-e+a(this).height();return g<10&&g>-10});h.length||(h=this.element.children(".ui-menu-item:last"));this.activate(d,h)}else this.activate(d,this.element.children(".ui-menu-item").filter(!this.active|| -this.last()?":first":":last"))},previousPage:function(d){if(this.hasScroll())if(!this.active||this.first())this.activate(d,this.element.children(".ui-menu-item:last"));else{var c=this.active.offset().top,e=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var h=a(this).offset().top-c+e-a(this).height();return h<10&&h>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(d,result)}else this.activate(d,this.element.children(".ui-menu-item").filter(!this.active|| -this.first()?":last":":first"))},hasScroll:function(){return this.element.height()").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),j=this.options.icons,l=j.primary&&j.secondary,o=[];if(j.primary||j.secondary){if(this.options.text)o.push("ui-button-text-icon"+(l?"s":j.primary?"-primary":"-secondary"));j.primary&&b.prepend("");j.secondary&&b.append("");if(!this.options.text){o.push(l?"ui-button-icons-only": -"ui-button-icon-only");this.hasTitle||b.attr("title",f)}}else o.push("ui-button-text-only");b.addClass(o.join(" "))}}});a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,f){b==="disabled"&&this.buttons.button("option",b,f);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")=== -"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(b?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"); -a.Widget.prototype.destroy.call(this)}})})(jQuery); -(function(a,d){function c(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass= -"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su", -"Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10", -minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false,autoSize:false,disabled:false};a.extend(this._defaults,this.regional[""]);this.dpDiv=e(a('
      '))}function e(b){return b.bind("mouseout", -function(f){f=a(f.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");f.length&&f.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(f){f=a(f.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(a.datepicker._isDisabledDatepicker(i.inline?b.parent()[0]:i.input[0])||!f.length)){f.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); -f.addClass("ui-state-hover");f.hasClass("ui-datepicker-prev")&&f.addClass("ui-datepicker-prev-hover");f.hasClass("ui-datepicker-next")&&f.addClass("ui-datepicker-next-hover")}})}function h(b,f){a.extend(b,f);for(var j in f)if(f[j]==null||f[j]==d)b[j]=f[j];return b}a.extend(a.ui,{datepicker:{version:"1.8.16"}});var g=(new Date).getTime(),i;a.extend(c.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv}, -setDefaults:function(b){h(this._defaults,b||{});return this},_attachDatepicker:function(b,f){var j=null;for(var l in this._defaults){var o=b.getAttribute("date:"+l);if(o){j=j||{};try{j[l]=eval(o)}catch(n){j[l]=o}}}l=b.nodeName.toLowerCase();o=l=="div"||l=="span";if(!b.id){this.uuid+=1;b.id="dp"+this.uuid}var k=this._newInst(a(b),o);k.settings=a.extend({},f||{},j||{});if(l=="input")this._connectDatepicker(b,k);else o&&this._inlineDatepicker(b,k)},_newInst:function(b,f){return{id:b[0].id.replace(/([^A-Za-z0-9_-])/g, -"\\\\$1"),input:b,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:f,dpDiv:!f?this.dpDiv:e(a('
      '))}},_connectDatepicker:function(b,f){var j=a(b);f.append=a([]);f.trigger=a([]);if(!j.hasClass(this.markerClassName)){this._attachments(j,f);j.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker", -function(l,o,n){f.settings[o]=n}).bind("getData.datepicker",function(l,o){return this._get(f,o)});this._autoSize(f);a.data(b,"datepicker",f);f.settings.disabled&&this._disableDatepicker(b)}},_attachments:function(b,f){var j=this._get(f,"appendText"),l=this._get(f,"isRTL");f.append&&f.append.remove();if(j){f.append=a(''+j+"");b[l?"before":"after"](f.append)}b.unbind("focus",this._showDatepicker);f.trigger&&f.trigger.remove();j=this._get(f,"showOn");if(j== -"focus"||j=="both")b.focus(this._showDatepicker);if(j=="button"||j=="both"){j=this._get(f,"buttonText");var o=this._get(f,"buttonImage");f.trigger=a(this._get(f,"buttonImageOnly")?a("").addClass(this._triggerClass).attr({src:o,alt:j,title:j}):a('').addClass(this._triggerClass).html(o==""?j:a("").attr({src:o,alt:j,title:j})));b[l?"before":"after"](f.trigger);f.trigger.click(function(){a.datepicker._datepickerShowing&&a.datepicker._lastInput==b[0]?a.datepicker._hideDatepicker(): -a.datepicker._showDatepicker(b[0]);return false})}},_autoSize:function(b){if(this._get(b,"autoSize")&&!b.inline){var f=new Date(2009,11,20),j=this._get(b,"dateFormat");if(j.match(/[DM]/)){var l=function(o){for(var n=0,k=0,m=0;mn){n=o[m].length;k=m}return k};f.setMonth(l(this._get(b,j.match(/MM/)?"monthNames":"monthNamesShort")));f.setDate(l(this._get(b,j.match(/DD/)?"dayNames":"dayNamesShort"))+20-f.getDay())}b.input.attr("size",this._formatDate(b,f).length)}},_inlineDatepicker:function(b, -f){var j=a(b);if(!j.hasClass(this.markerClassName)){j.addClass(this.markerClassName).append(f.dpDiv).bind("setData.datepicker",function(l,o,n){f.settings[o]=n}).bind("getData.datepicker",function(l,o){return this._get(f,o)});a.data(b,"datepicker",f);this._setDate(f,this._getDefaultDate(f),true);this._updateDatepicker(f);this._updateAlternate(f);f.settings.disabled&&this._disableDatepicker(b);f.dpDiv.css("display","block")}},_dialogDatepicker:function(b,f,j,l,o){b=this._dialogInst;if(!b){this.uuid+= -1;this._dialogInput=a('');this._dialogInput.keydown(this._doKeyDown);a("body").append(this._dialogInput);b=this._dialogInst=this._newInst(this._dialogInput,false);b.settings={};a.data(this._dialogInput[0],"datepicker",b)}h(b.settings,l||{});f=f&&f.constructor==Date?this._formatDate(b,f):f;this._dialogInput.val(f);this._pos=o?o.length?o:[o.pageX,o.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/ -2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");b.settings.onSelect=j;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);a.blockUI&&a.blockUI(this.dpDiv);a.data(this._dialogInput[0],"datepicker",b);return this},_destroyDatepicker:function(b){var f= -a(b),j=a.data(b,"datepicker");if(f.hasClass(this.markerClassName)){var l=b.nodeName.toLowerCase();a.removeData(b,"datepicker");if(l=="input"){j.append.remove();j.trigger.remove();f.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(l=="div"||l=="span")f.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(b){var f=a(b),j=a.data(b,"datepicker");if(f.hasClass(this.markerClassName)){var l= -b.nodeName.toLowerCase();if(l=="input"){b.disabled=false;j.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(l=="div"||l=="span"){f=f.children("."+this._inlineClass);f.children().removeClass("ui-state-disabled");f.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=a.map(this._disabledInputs,function(o){return o==b?null:o})}},_disableDatepicker:function(b){var f=a(b),j=a.data(b, -"datepicker");if(f.hasClass(this.markerClassName)){var l=b.nodeName.toLowerCase();if(l=="input"){b.disabled=true;j.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(l=="div"||l=="span"){f=f.children("."+this._inlineClass);f.children().addClass("ui-state-disabled");f.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=a.map(this._disabledInputs,function(o){return o== -b?null:o});this._disabledInputs[this._disabledInputs.length]=b}},_isDisabledDatepicker:function(b){if(!b)return false;for(var f=0;f-1}},_doKeyUp:function(b){b=a.datepicker._getInst(b.target);if(b.input.val()!=b.lastVal)try{if(a.datepicker.parseDate(a.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,a.datepicker._getFormatConfig(b))){a.datepicker._setDateFromField(b);a.datepicker._updateAlternate(b);a.datepicker._updateDatepicker(b)}}catch(f){a.datepicker.log(f)}return true},_showDatepicker:function(b){b=b.target||b;if(b.nodeName.toLowerCase()!="input")b=a("input", -b.parentNode)[0];if(!(a.datepicker._isDisabledDatepicker(b)||a.datepicker._lastInput==b)){var f=a.datepicker._getInst(b);if(a.datepicker._curInst&&a.datepicker._curInst!=f){a.datepicker._datepickerShowing&&a.datepicker._triggerOnClose(a.datepicker._curInst);a.datepicker._curInst.dpDiv.stop(true,true)}var j=a.datepicker._get(f,"beforeShow");j=j?j.apply(b,[b,f]):{};if(j!==false){h(f.settings,j);f.lastVal=null;a.datepicker._lastInput=b;a.datepicker._setDateFromField(f);if(a.datepicker._inDialog)b.value= -"";if(!a.datepicker._pos){a.datepicker._pos=a.datepicker._findPos(b);a.datepicker._pos[1]+=b.offsetHeight}var l=false;a(b).parents().each(function(){l|=a(this).css("position")=="fixed";return!l});if(l&&a.browser.opera){a.datepicker._pos[0]-=document.documentElement.scrollLeft;a.datepicker._pos[1]-=document.documentElement.scrollTop}j={left:a.datepicker._pos[0],top:a.datepicker._pos[1]};a.datepicker._pos=null;f.dpDiv.empty();f.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});a.datepicker._updateDatepicker(f); -j=a.datepicker._checkOffset(f,j,l);f.dpDiv.css({position:a.datepicker._inDialog&&a.blockUI?"static":l?"fixed":"absolute",display:"none",left:j.left+"px",top:j.top+"px"});if(!f.inline){j=a.datepicker._get(f,"showAnim");var o=a.datepicker._get(f,"duration"),n=function(){var k=f.dpDiv.find("iframe.ui-datepicker-cover");if(k.length){var m=a.datepicker._getBorders(f.dpDiv);k.css({left:-m[0],top:-m[1],width:f.dpDiv.outerWidth(),height:f.dpDiv.outerHeight()})}};f.dpDiv.zIndex(a(b).zIndex()+1);a.datepicker._datepickerShowing= -true;a.effects&&a.effects[j]?f.dpDiv.show(j,a.datepicker._get(f,"showOptions"),o,n):f.dpDiv[j||"show"](j?o:null,n);if(!j||!o)n();f.input.is(":visible")&&!f.input.is(":disabled")&&f.input.focus();a.datepicker._curInst=f}}}},_updateDatepicker:function(b){this.maxRows=4;var f=a.datepicker._getBorders(b.dpDiv);i=b;b.dpDiv.empty().append(this._generateHTML(b));var j=b.dpDiv.find("iframe.ui-datepicker-cover");j.length&&j.css({left:-f[0],top:-f[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()}); -b.dpDiv.find("."+this._dayOverClass+" a").mouseover();f=this._getNumberOfMonths(b);j=f[1];b.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");j>1&&b.dpDiv.addClass("ui-datepicker-multi-"+j).css("width",17*j+"em");b.dpDiv[(f[0]!=1||f[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");b.dpDiv[(this._get(b,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");b==a.datepicker._curInst&&a.datepicker._datepickerShowing&&b.input&&b.input.is(":visible")&& -!b.input.is(":disabled")&&b.input[0]!=document.activeElement&&b.input.focus();if(b.yearshtml){var l=b.yearshtml;setTimeout(function(){l===b.yearshtml&&b.yearshtml&&b.dpDiv.find("select.ui-datepicker-year:first").replaceWith(b.yearshtml);l=b.yearshtml=null},0)}},_getBorders:function(b){var f=function(j){return{thin:1,medium:2,thick:3}[j]||j};return[parseFloat(f(b.css("border-left-width"))),parseFloat(f(b.css("border-top-width")))]},_checkOffset:function(b,f,j){var l=b.dpDiv.outerWidth(),o=b.dpDiv.outerHeight(), -n=b.input?b.input.outerWidth():0,k=b.input?b.input.outerHeight():0,m=document.documentElement.clientWidth+a(document).scrollLeft(),p=document.documentElement.clientHeight+a(document).scrollTop();f.left-=this._get(b,"isRTL")?l-n:0;f.left-=j&&f.left==b.input.offset().left?a(document).scrollLeft():0;f.top-=j&&f.top==b.input.offset().top+k?a(document).scrollTop():0;f.left-=Math.min(f.left,f.left+l>m&&m>l?Math.abs(f.left+l-m):0);f.top-=Math.min(f.top,f.top+o>p&&p>o?Math.abs(o+k):0);return f},_findPos:function(b){for(var f= -this._get(this._getInst(b),"isRTL");b&&(b.type=="hidden"||b.nodeType!=1||a.expr.filters.hidden(b));)b=b[f?"previousSibling":"nextSibling"];b=a(b).offset();return[b.left,b.top]},_triggerOnClose:function(b){var f=this._get(b,"onClose");if(f)f.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b])},_hideDatepicker:function(b){var f=this._curInst;if(!(!f||b&&f!=a.data(b,"datepicker")))if(this._datepickerShowing){b=this._get(f,"showAnim");var j=this._get(f,"duration"),l=function(){a.datepicker._tidyDialog(f); -this._curInst=null};a.effects&&a.effects[b]?f.dpDiv.hide(b,a.datepicker._get(f,"showOptions"),j,l):f.dpDiv[b=="slideDown"?"slideUp":b=="fadeIn"?"fadeOut":"hide"](b?j:null,l);b||l();a.datepicker._triggerOnClose(f);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(a.blockUI){a.unblockUI();a("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(b){b.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")}, -_checkExternalClick:function(b){if(a.datepicker._curInst){b=a(b.target);b[0].id!=a.datepicker._mainDivId&&b.parents("#"+a.datepicker._mainDivId).length==0&&!b.hasClass(a.datepicker.markerClassName)&&!b.hasClass(a.datepicker._triggerClass)&&a.datepicker._datepickerShowing&&!(a.datepicker._inDialog&&a.blockUI)&&a.datepicker._hideDatepicker()}},_adjustDate:function(b,f,j){b=a(b);var l=this._getInst(b[0]);if(!this._isDisabledDatepicker(b[0])){this._adjustInstDate(l,f+(j=="M"?this._get(l,"showCurrentAtPos"): -0),j);this._updateDatepicker(l)}},_gotoToday:function(b){b=a(b);var f=this._getInst(b[0]);if(this._get(f,"gotoCurrent")&&f.currentDay){f.selectedDay=f.currentDay;f.drawMonth=f.selectedMonth=f.currentMonth;f.drawYear=f.selectedYear=f.currentYear}else{var j=new Date;f.selectedDay=j.getDate();f.drawMonth=f.selectedMonth=j.getMonth();f.drawYear=f.selectedYear=j.getFullYear()}this._notifyChange(f);this._adjustDate(b)},_selectMonthYear:function(b,f,j){b=a(b);var l=this._getInst(b[0]);l["selected"+(j=="M"? -"Month":"Year")]=l["draw"+(j=="M"?"Month":"Year")]=parseInt(f.options[f.selectedIndex].value,10);this._notifyChange(l);this._adjustDate(b)},_selectDay:function(b,f,j,l){var o=a(b);if(!(a(l).hasClass(this._unselectableClass)||this._isDisabledDatepicker(o[0]))){o=this._getInst(o[0]);o.selectedDay=o.currentDay=a("a",l).html();o.selectedMonth=o.currentMonth=f;o.selectedYear=o.currentYear=j;this._selectDate(b,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear))}},_clearDate:function(b){b=a(b); -this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(b,f){b=this._getInst(a(b)[0]);f=f!=null?f:this._formatDate(b);b.input&&b.input.val(f);this._updateAlternate(b);var j=this._get(b,"onSelect");if(j)j.apply(b.input?b.input[0]:null,[f,b]);else b.input&&b.input.trigger("change");if(b.inline)this._updateDatepicker(b);else{this._hideDatepicker();this._lastInput=b.input[0];typeof b.input[0]!="object"&&b.input.focus();this._lastInput=null}},_updateAlternate:function(b){var f=this._get(b,"altField"); -if(f){var j=this._get(b,"altFormat")||this._get(b,"dateFormat"),l=this._getDate(b),o=this.formatDate(j,l,this._getFormatConfig(b));a(f).each(function(){a(this).val(o)})}},noWeekends:function(b){b=b.getDay();return[b>0&&b<6,""]},iso8601Week:function(b){b=new Date(b.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var f=b.getTime();b.setMonth(0);b.setDate(1);return Math.floor(Math.round((f-b)/864E5)/7)+1},parseDate:function(b,f,j){if(b==null||f==null)throw"Invalid arguments";f=typeof f=="object"? -f.toString():f+"";if(f=="")return null;var l=(j?j.shortYearCutoff:null)||this._defaults.shortYearCutoff;l=typeof l!="string"?l:(new Date).getFullYear()%100+parseInt(l,10);for(var o=(j?j.dayNamesShort:null)||this._defaults.dayNamesShort,n=(j?j.dayNames:null)||this._defaults.dayNames,k=(j?j.monthNamesShort:null)||this._defaults.monthNamesShort,m=(j?j.monthNames:null)||this._defaults.monthNames,p=j=-1,q=-1,s=-1,r=false,u=function(z){(z=H+1-1){p=1;q=s;do{l=this._getDaysInMonth(j,p-1);if(q<=l)break;p++;q-=l}while(1)}C=this._daylightSavingAdjust(new Date(j,p-1,q));if(C.getFullYear()!=j||C.getMonth()+1!=p||C.getDate()!=q)throw"Invalid date";return C},ATOM:"yy-mm-dd", -COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(b,f,j){if(!f)return"";var l=(j?j.dayNamesShort:null)||this._defaults.dayNamesShort,o=(j?j.dayNames:null)||this._defaults.dayNames,n=(j?j.monthNamesShort:null)||this._defaults.monthNamesShort;j=(j?j.monthNames: -null)||this._defaults.monthNames;var k=function(u){(u=r+1 -12?b.getHours()+2:0);return b},_setDate:function(b,f,j){var l=!f,o=b.selectedMonth,n=b.selectedYear;f=this._restrictMinMax(b,this._determineDate(b,f,new Date));b.selectedDay=b.currentDay=f.getDate();b.drawMonth=b.selectedMonth=b.currentMonth=f.getMonth();b.drawYear=b.selectedYear=b.currentYear=f.getFullYear();if((o!=b.selectedMonth||n!=b.selectedYear)&&!j)this._notifyChange(b);this._adjustInstDate(b);if(b.input)b.input.val(l?"":this._formatDate(b))},_getDate:function(b){return!b.currentYear||b.input&& -b.input.val()==""?null:this._daylightSavingAdjust(new Date(b.currentYear,b.currentMonth,b.currentDay))},_generateHTML:function(b){var f=new Date;f=this._daylightSavingAdjust(new Date(f.getFullYear(),f.getMonth(),f.getDate()));var j=this._get(b,"isRTL"),l=this._get(b,"showButtonPanel"),o=this._get(b,"hideIfNoPrevNext"),n=this._get(b,"navigationAsDateFormat"),k=this._getNumberOfMonths(b),m=this._get(b,"showCurrentAtPos"),p=this._get(b,"stepMonths"),q=k[0]!=1||k[1]!=1,s=this._daylightSavingAdjust(!b.currentDay? -new Date(9999,9,9):new Date(b.currentYear,b.currentMonth,b.currentDay)),r=this._getMinMaxDate(b,"min"),u=this._getMinMaxDate(b,"max");m=b.drawMonth-m;var v=b.drawYear;if(m<0){m+=12;v--}if(u){var w=this._daylightSavingAdjust(new Date(u.getFullYear(),u.getMonth()-k[0]*k[1]+1,u.getDate()));for(w=r&&ww;){m--;if(m<0){m=11;v--}}}b.drawMonth=m;b.drawYear=v;w=this._get(b,"prevText");w=!n?w:this.formatDate(w,this._daylightSavingAdjust(new Date(v,m-p,1)),this._getFormatConfig(b)); -w=this._canAdjustMonth(b,-1,v,m)?''+w+"":o?"":''+w+"";var x=this._get(b,"nextText");x=!n?x:this.formatDate(x,this._daylightSavingAdjust(new Date(v, -m+p,1)),this._getFormatConfig(b));o=this._canAdjustMonth(b,+1,v,m)?''+x+"":o?"":''+x+"";p=this._get(b,"currentText");x=this._get(b,"gotoCurrent")&& -b.currentDay?s:f;p=!n?p:this.formatDate(p,x,this._getFormatConfig(b));n=!b.inline?'":"";l=l?'
      '+(j?n:"")+(this._isInRange(b,x)?'":"")+(j?"":n)+"
      ":"";n=parseInt(this._get(b,"firstDay"),10);n=isNaN(n)?0:n;p=this._get(b,"showWeek");x=this._get(b,"dayNames");this._get(b,"dayNamesShort");var y=this._get(b,"dayNamesMin"),H=this._get(b,"monthNames"),C=this._get(b,"monthNamesShort"),z=this._get(b,"beforeShowDay"),I=this._get(b,"showOtherMonths"),N=this._get(b,"selectOtherMonths");this._get(b,"calculateWeek");for(var J=this._getDefaultDate(b),D="",E=0;E1)switch(L){case 0:F+=" ui-datepicker-group-first";B=" ui-corner-"+(j?"right":"left");break;case k[1]-1:F+=" ui-datepicker-group-last";B=" ui-corner-"+(j?"left":"right");break;default:F+=" ui-datepicker-group-middle";B="";break}F+='">'}F+='
      '+(/all|left/.test(B)&& -E==0?j?o:w:"")+(/all|right/.test(B)&&E==0?j?w:o:"")+this._generateMonthYearHeader(b,m,v,r,u,E>0||L>0,H,C)+'
      ';var G=p?'":"";for(B=0;B<7;B++){var A=(B+n)%7;G+="=5?' class="ui-datepicker-week-end"':"")+'>'+y[A]+""}F+=G+"";G=this._getDaysInMonth(v,m);if(v==b.selectedYear&&m==b.selectedMonth)b.selectedDay=Math.min(b.selectedDay, -G);B=(this._getFirstDayOfMonth(v,m)-n+7)%7;G=Math.ceil((B+G)/7);this.maxRows=G=q?this.maxRows>G?this.maxRows:G:G;A=this._daylightSavingAdjust(new Date(v,m,1-B));for(var R=0;R";var S=!p?"":'";for(B=0;B<7;B++){var M=z?z.apply(b.input?b.input[0]:null,[A]):[true,""],K=A.getMonth()!=m,O=K&&!N||!M[0]||r&&Au;S+='";A.setDate(A.getDate()+1);A=this._daylightSavingAdjust(A)}F+=S+""}m++;if(m>11){m=0;v++}F+="
      '+this._get(b,"weekHeader")+"
      '+this._get(b,"calculateWeek")(A)+""+(K&&!I?" ":O?''+ -A.getDate()+"":''+A.getDate()+"")+"
      "+(q?""+(k[0]>0&&L==k[1]-1?'
      ':""):"");P+=F}D+=P}D+=l+(a.browser.msie&&parseInt(a.browser.version,10)<7&&!b.inline?'': -"");b._keyEvent=false;return D},_generateMonthYearHeader:function(b,f,j,l,o,n,k,m){var p=this._get(b,"changeMonth"),q=this._get(b,"changeYear"),s=this._get(b,"showMonthAfterYear"),r='
      ',u="";if(n||!p)u+=''+k[f]+"";else{k=l&&l.getFullYear()==j;var v=o&&o.getFullYear()==j;u+='"}s||(r+=u+(n||!(p&&q)?" ":""));if(!b.yearshtml){b.yearshtml="";if(n||!q)r+=''+j+"";else{m=this._get(b,"yearRange").split(":");var x=(new Date).getFullYear();k=function(y){y=y.match(/c[+-].*/)?j+parseInt(y.substring(1),10):y.match(/[+-].*/)?x+parseInt(y,10):parseInt(y,10);return isNaN(y)?x:y};f=k(m[0]);m=Math.max(f,k(m[1]||""));f=l?Math.max(f, -l.getFullYear()):f;m=o?Math.min(m,o.getFullYear()):m;for(b.yearshtml+='";r+=b.yearshtml;b.yearshtml=null}}r+=this._get(b,"yearSuffix");if(s)r+=(n||!(p&&q)?" ":"")+u;r+="
      ";return r},_adjustInstDate:function(b,f,j){var l=b.drawYear+(j=="Y"?f:0),o=b.drawMonth+ -(j=="M"?f:0);f=Math.min(b.selectedDay,this._getDaysInMonth(l,o))+(j=="D"?f:0);l=this._restrictMinMax(b,this._daylightSavingAdjust(new Date(l,o,f)));b.selectedDay=l.getDate();b.drawMonth=b.selectedMonth=l.getMonth();b.drawYear=b.selectedYear=l.getFullYear();if(j=="M"||j=="Y")this._notifyChange(b)},_restrictMinMax:function(b,f){var j=this._getMinMaxDate(b,"min");b=this._getMinMaxDate(b,"max");f=j&&fb?b:f},_notifyChange:function(b){var f=this._get(b,"onChangeMonthYear");if(f)f.apply(b.input? -b.input[0]:null,[b.selectedYear,b.selectedMonth+1,b])},_getNumberOfMonths:function(b){b=this._get(b,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(b,f){return this._determineDate(b,this._get(b,f+"Date"),null)},_getDaysInMonth:function(b,f){return 32-this._daylightSavingAdjust(new Date(b,f,32)).getDate()},_getFirstDayOfMonth:function(b,f){return(new Date(b,f,1)).getDay()},_canAdjustMonth:function(b,f,j,l){var o=this._getNumberOfMonths(b);j=this._daylightSavingAdjust(new Date(j, -l+(f<0?f:o[0]*o[1]),1));f<0&&j.setDate(this._getDaysInMonth(j.getFullYear(),j.getMonth()));return this._isInRange(b,j)},_isInRange:function(b,f){var j=this._getMinMaxDate(b,"min");b=this._getMinMaxDate(b,"max");return(!j||f.getTime()>=j.getTime())&&(!b||f.getTime()<=b.getTime())},_getFormatConfig:function(b){var f=this._get(b,"shortYearCutoff");f=typeof f!="string"?f:(new Date).getFullYear()%100+parseInt(f,10);return{shortYearCutoff:f,dayNamesShort:this._get(b,"dayNamesShort"),dayNames:this._get(b, -"dayNames"),monthNamesShort:this._get(b,"monthNamesShort"),monthNames:this._get(b,"monthNames")}},_formatDate:function(b,f,j,l){if(!f){b.currentDay=b.selectedDay;b.currentMonth=b.selectedMonth;b.currentYear=b.selectedYear}f=f?typeof f=="object"?f:this._daylightSavingAdjust(new Date(l,j,f)):this._daylightSavingAdjust(new Date(b.currentYear,b.currentMonth,b.currentDay));return this.formatDate(this._get(b,"dateFormat"),f,this._getFormatConfig(b))}});a.fn.datepicker=function(b){if(!this.length)return this; -if(!a.datepicker.initialized){a(document).mousedown(a.datepicker._checkExternalClick).find("body").append(a.datepicker.dpDiv);a.datepicker.initialized=true}var f=Array.prototype.slice.call(arguments,1);if(typeof b=="string"&&(b=="isDisabled"||b=="getDate"||b=="widget"))return a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(f));if(b=="option"&&arguments.length==2&&typeof arguments[1]=="string")return a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(f));return this.each(function(){typeof b== -"string"?a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this].concat(f)):a.datepicker._attachDatepicker(this,b)})};a.datepicker=new c;a.datepicker.initialized=false;a.datepicker.uuid=(new Date).getTime();a.datepicker.version="1.8.16";window["DP_jQuery_"+g]=a})(jQuery); -(function(a,d){var c={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},e={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},h=a.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};a.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false, -position:{my:"center",at:"center",collision:"fit",using:function(g){var i=a(this).css(g).offset().top;i<0&&a(this).css("top",g.top-i)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var g=this,i=g.options,b=i.title||" ",f=a.ui.dialog.getTitleId(g.element),j=(g.uiDialog=a("
      ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ -i.dialogClass).css({zIndex:i.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(n){if(i.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===a.ui.keyCode.ESCAPE){g.close(n);n.preventDefault()}}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(n){g.moveToTop(false,n)});g.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(j);var l=(g.uiDialogTitlebar=a("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(j), -o=a('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){o.addClass("ui-state-hover")},function(){o.removeClass("ui-state-hover")}).focus(function(){o.addClass("ui-state-focus")}).blur(function(){o.removeClass("ui-state-focus")}).click(function(n){g.close(n);return false}).appendTo(l);(g.uiDialogTitlebarCloseText=a("")).addClass("ui-icon ui-icon-closethick").text(i.closeText).appendTo(o);a("").addClass("ui-dialog-title").attr("id", -f).html(b).prependTo(l);if(a.isFunction(i.beforeclose)&&!a.isFunction(i.beforeClose))i.beforeClose=i.beforeclose;l.find("*").add(l).disableSelection();i.draggable&&a.fn.draggable&&g._makeDraggable();i.resizable&&a.fn.resizable&&g._makeResizable();g._createButtons(i.buttons);g._isOpen=false;a.fn.bgiframe&&j.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var g=this;g.overlay&&g.overlay.destroy();g.uiDialog.hide();g.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); -g.uiDialog.remove();g.originalTitle&&g.element.attr("title",g.originalTitle);return g},widget:function(){return this.uiDialog},close:function(g){var i=this,b,f;if(false!==i._trigger("beforeClose",g)){i.overlay&&i.overlay.destroy();i.uiDialog.unbind("keypress.ui-dialog");i._isOpen=false;if(i.options.hide)i.uiDialog.hide(i.options.hide,function(){i._trigger("close",g)});else{i.uiDialog.hide();i._trigger("close",g)}a.ui.dialog.overlay.resize();if(i.options.modal){b=0;a(".ui-dialog").each(function(){if(this!== -i.uiDialog[0]){f=a(this).css("z-index");isNaN(f)||(b=Math.max(b,f))}});a.ui.dialog.maxZ=b}return i}},isOpen:function(){return this._isOpen},moveToTop:function(g,i){var b=this,f=b.options;if(f.modal&&!g||!f.stack&&!f.modal)return b._trigger("focus",i);if(f.zIndex>a.ui.dialog.maxZ)a.ui.dialog.maxZ=f.zIndex;if(b.overlay){a.ui.dialog.maxZ+=1;b.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)}g={scrollTop:b.element.scrollTop(),scrollLeft:b.element.scrollLeft()};a.ui.dialog.maxZ+=1; -b.uiDialog.css("z-index",a.ui.dialog.maxZ);b.element.attr(g);b._trigger("focus",i);return b},open:function(){if(!this._isOpen){var g=this,i=g.options,b=g.uiDialog;g.overlay=i.modal?new a.ui.dialog.overlay(g):null;g._size();g._position(i.position);b.show(i.show);g.moveToTop(true);i.modal&&b.bind("keypress.ui-dialog",function(f){if(f.keyCode===a.ui.keyCode.TAB){var j=a(":tabbable",this),l=j.filter(":first");j=j.filter(":last");if(f.target===j[0]&&!f.shiftKey){l.focus(1);return false}else if(f.target=== -l[0]&&f.shiftKey){j.focus(1);return false}}});a(g.element.find(":tabbable").get().concat(b.find(".ui-dialog-buttonpane :tabbable").get().concat(b.get()))).eq(0).focus();g._isOpen=true;g._trigger("open");return g}},_createButtons:function(g){var i=this,b=false,f=a("
      ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),j=a("
      ").addClass("ui-dialog-buttonset").appendTo(f);i.uiDialog.find(".ui-dialog-buttonpane").remove();typeof g==="object"&&g!==null&&a.each(g, -function(){return!(b=true)});if(b){a.each(g,function(l,o){o=a.isFunction(o)?{click:o,text:l}:o;var n=a('').click(function(){o.click.apply(i.element[0],arguments)}).appendTo(j);a.each(o,function(k,m){if(k!=="click")k in h?n[k](m):n.attr(k,m)});a.fn.button&&n.button()});f.appendTo(i.uiDialog)}},_makeDraggable:function(){function g(l){return{position:l.position,offset:l.offset}}var i=this,b=i.options,f=a(document),j;i.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", -handle:".ui-dialog-titlebar",containment:"document",start:function(l,o){j=b.height==="auto"?"auto":a(this).height();a(this).height(a(this).height()).addClass("ui-dialog-dragging");i._trigger("dragStart",l,g(o))},drag:function(l,o){i._trigger("drag",l,g(o))},stop:function(l,o){b.position=[o.position.left-f.scrollLeft(),o.position.top-f.scrollTop()];a(this).removeClass("ui-dialog-dragging").height(j);i._trigger("dragStop",l,g(o));a.ui.dialog.overlay.resize()}})},_makeResizable:function(g){function i(l){return{originalPosition:l.originalPosition, -originalSize:l.originalSize,position:l.position,size:l.size}}g=g===d?this.options.resizable:g;var b=this,f=b.options,j=b.uiDialog.css("position");g=typeof g==="string"?g:"n,e,s,w,se,sw,ne,nw";b.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:b.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:b._minHeight(),handles:g,start:function(l,o){a(this).addClass("ui-dialog-resizing");b._trigger("resizeStart",l,i(o))},resize:function(l,o){b._trigger("resize", -l,i(o))},stop:function(l,o){a(this).removeClass("ui-dialog-resizing");f.height=a(this).height();f.width=a(this).width();b._trigger("resizeStop",l,i(o));a.ui.dialog.overlay.resize()}}).css("position",j).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var g=this.options;return g.height==="auto"?g.minHeight:Math.min(g.minHeight,g.height)},_position:function(g){var i=[],b=[0,0],f;if(g){if(typeof g==="string"||typeof g==="object"&&"0"in g){i=g.split?g.split(" "): -[g[0],g[1]];if(i.length===1)i[1]=i[0];a.each(["left","top"],function(j,l){if(+i[j]===i[j]){b[j]=i[j];i[j]=l}});g={my:i.join(" "),at:i.join(" "),offset:b.join(" ")}}g=a.extend({},a.ui.dialog.prototype.options.position,g)}else g=a.ui.dialog.prototype.options.position;(f=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},g));f||this.uiDialog.hide()},_setOptions:function(g){var i=this,b={},f=false;a.each(g,function(j,l){i._setOption(j,l); -if(j in c)f=true;if(j in e)b[j]=l});f&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",b)},_setOption:function(g,i){var b=this,f=b.uiDialog;switch(g){case "beforeclose":g="beforeClose";break;case "buttons":b._createButtons(i);break;case "closeText":b.uiDialogTitlebarCloseText.text(""+i);break;case "dialogClass":f.removeClass(b.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+i);break;case "disabled":i?f.addClass("ui-dialog-disabled"): -f.removeClass("ui-dialog-disabled");break;case "draggable":var j=f.is(":data(draggable)");j&&!i&&f.draggable("destroy");!j&&i&&b._makeDraggable();break;case "position":b._position(i);break;case "resizable":(j=f.is(":data(resizable)"))&&!i&&f.resizable("destroy");j&&typeof i==="string"&&f.resizable("option","handles",i);!j&&i!==false&&b._makeResizable(i);break;case "title":a(".ui-dialog-title",b.uiDialogTitlebar).html(""+(i||" "));break}a.Widget.prototype._setOption.apply(b,arguments)},_size:function(){var g= -this.options,i,b,f=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(g.minWidth>g.width)g.width=g.minWidth;i=this.uiDialog.css({height:"auto",width:g.width}).height();b=Math.max(0,g.minHeight-i);if(g.height==="auto")if(a.support.minHeight)this.element.css({minHeight:b,height:"auto"});else{this.uiDialog.show();g=this.element.css("height","auto").height();f||this.uiDialog.hide();this.element.height(Math.max(g,b))}else this.element.height(Math.max(g.height- -i,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});a.extend(a.ui.dialog,{version:"1.8.16",uuid:0,maxZ:0,getTitleId:function(g){g=g.attr("id");if(!g){this.uuid+=1;g=this.uuid}return"ui-dialog-title-"+g},overlay:function(g){this.$el=a.ui.dialog.overlay.create(g)}});a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(g){return g+".dialog-overlay"}).join(" "), -create:function(g){if(this.instances.length===0){setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&i.bgiframe();this.instances.push(i);return i},destroy:function(g){var i=a.inArray(g,this.instances);i!=-1&&this.oldInstances.push(this.instances.splice(i,1)[0]);this.instances.length===0&&a([document,window]).unbind(".dialog-overlay");g.remove();var b=0;a.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var g,i;if(a.browser.msie&& -a.browser.version<7){g=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);i=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return g0?g.left-b:Math.max(g.left-i.collisionPosition.left,g.left)},top:function(g,i){var b=a(window);b=i.collisionPosition.top+i.collisionHeight-b.height()-b.scrollTop();g.top=b>0?g.top-b:Math.max(g.top-i.collisionPosition.top,g.top)}},flip:{left:function(g,i){if(i.at[0]!=="center"){var b=a(window);b=i.collisionPosition.left+i.collisionWidth-b.width()-b.scrollLeft();var f=i.my[0]==="left"?-i.elemWidth:i.my[0]==="right"?i.elemWidth:0,j=i.at[0]==="left"?i.targetWidth:-i.targetWidth,l=-2*i.offset[0];g.left+= -i.collisionPosition.left<0?f+j+l:b>0?f+j+l:0}},top:function(g,i){if(i.at[1]!=="center"){var b=a(window);b=i.collisionPosition.top+i.collisionHeight-b.height()-b.scrollTop();var f=i.my[1]==="top"?-i.elemHeight:i.my[1]==="bottom"?i.elemHeight:0,j=i.at[1]==="top"?i.targetHeight:-i.targetHeight,l=-2*i.offset[1];g.top+=i.collisionPosition.top<0?f+j+l:b>0?f+j+l:0}}}};if(!a.offset.setOffset){a.offset.setOffset=function(g,i){if(/static/.test(a.curCSS(g,"position")))g.style.position="relative";var b=a(g), -f=b.offset(),j=parseInt(a.curCSS(g,"top",true),10)||0,l=parseInt(a.curCSS(g,"left",true),10)||0;f={top:i.top-f.top+j,left:i.left-f.left+l};"using"in i?i.using.call(g,f):b.css(f)};a.fn.offset=function(g){var i=this[0];if(!i||!i.ownerDocument)return null;if(g)return this.each(function(){a.offset.setOffset(this,g)});return h.call(this)}}})(jQuery); -(function(a,d){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=a("
      ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); -this.valueDiv.remove();a.Widget.prototype.destroy.apply(this,arguments)},value:function(c){if(c===d)return this._value();this._setOption("value",c);return this},_setOption:function(c,e){if(c==="value"){this.options.value=e;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var c=this.options.value;if(typeof c!=="number")c=0;return Math.min(this.options.max,Math.max(this.min,c))},_percentage:function(){return 100* -this._value()/this.options.max},_refreshValue:function(){var c=this.value(),e=this._percentage();if(this.oldValue!==c){this.oldValue=c;this._trigger("change")}this.valueDiv.toggle(c>this.min).toggleClass("ui-corner-right",c===this.options.max).width(e.toFixed(0)+"%");this.element.attr("aria-valuenow",c)}});a.extend(a.ui.progressbar,{version:"1.8.16"})})(jQuery); -(function(a){a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var d=this,c=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),h=c.values&&c.values.length||1,g=[];this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+ -this.orientation+" ui-widget ui-widget-content ui-corner-all"+(c.disabled?" ui-slider-disabled ui-disabled":""));this.range=a([]);if(c.range){if(c.range===true){if(!c.values)c.values=[this._valueMin(),this._valueMin()];if(c.values.length&&c.values.length!==2)c.values=[c.values[0],c.values[0]]}this.range=a("
      ").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(c.range==="min"||c.range==="max"?" ui-slider-range-"+c.range:""))}for(var i=e.length;i"); -this.handles=e.add(a(g.join("")).appendTo(d.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(b){b.preventDefault()}).hover(function(){c.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){if(c.disabled)a(this).blur();else{a(".ui-slider .ui-state-focus").removeClass("ui-state-focus");a(this).addClass("ui-state-focus")}}).blur(function(){a(this).removeClass("ui-state-focus")});this.handles.each(function(b){a(this).data("index.ui-slider-handle", -b)});this.handles.keydown(function(b){var f=true,j=a(this).data("index.ui-slider-handle"),l,o,n;if(!d.options.disabled){switch(b.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:f=false;if(!d._keySliding){d._keySliding=true;a(this).addClass("ui-state-active");l=d._start(b,j);if(l===false)return}break}n=d.options.step;l=d.options.values&&d.options.values.length? -(o=d.values(j)):(o=d.value());switch(b.keyCode){case a.ui.keyCode.HOME:o=d._valueMin();break;case a.ui.keyCode.END:o=d._valueMax();break;case a.ui.keyCode.PAGE_UP:o=d._trimAlignValue(l+(d._valueMax()-d._valueMin())/5);break;case a.ui.keyCode.PAGE_DOWN:o=d._trimAlignValue(l-(d._valueMax()-d._valueMin())/5);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(l===d._valueMax())return;o=d._trimAlignValue(l+n);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(l===d._valueMin())return;o=d._trimAlignValue(l- -n);break}d._slide(b,j,o);return f}}).keyup(function(b){var f=a(this).data("index.ui-slider-handle");if(d._keySliding){d._keySliding=false;d._stop(b,f);d._change(b,f);a(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy(); -return this},_mouseCapture:function(d){var c=this.options,e,h,g,i,b;if(c.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();e=this._normValueFromMouse({x:d.pageX,y:d.pageY});h=this._valueMax()-this._valueMin()+1;i=this;this.handles.each(function(f){var j=Math.abs(e-i.values(f));if(h>j){h=j;g=a(this);b=f}});if(c.range===true&&this.values(1)===c.min){b+=1;g=a(this.handles[b])}if(this._start(d,b)===false)return false; -this._mouseSliding=true;i._handleIndex=b;g.addClass("ui-state-active").focus();c=g.offset();this._clickOffset=!a(d.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:d.pageX-c.left-g.width()/2,top:d.pageY-c.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(d,b,e);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(d){var c= -this._normValueFromMouse({x:d.pageX,y:d.pageY});this._slide(d,this._handleIndex,c);return false},_mouseStop:function(d){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(d,this._handleIndex);this._change(d,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(d){var c;if(this.orientation==="horizontal"){c= -this.elementSize.width;d=d.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{c=this.elementSize.height;d=d.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}c=d/c;if(c>1)c=1;if(c<0)c=0;if(this.orientation==="vertical")c=1-c;d=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+c*d)},_start:function(d,c){var e={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){e.value=this.values(c); -e.values=this.values()}return this._trigger("start",d,e)},_slide:function(d,c,e){var h;if(this.options.values&&this.options.values.length){h=this.values(c?0:1);if(this.options.values.length===2&&this.options.range===true&&(c===0&&e>h||c===1&&e1){this.options.values[d]=this._trimAlignValue(c);this._refreshValue();this._change(null,d)}else if(arguments.length)if(a.isArray(arguments[0])){e=this.options.values;h=arguments[0];for(g=0;g=this._valueMax())return this._valueMax();var c=this.options.step>0?this.options.step:1,e=(d-this._valueMin())%c;d=d-e;if(Math.abs(e)*2>=c)d+=e>0?c:-c;return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var d= -this.options.range,c=this.options,e=this,h=!this._animateOff?c.animate:false,g,i={},b,f,j,l;if(this.options.values&&this.options.values.length)this.handles.each(function(o){g=(e.values(o)-e._valueMin())/(e._valueMax()-e._valueMin())*100;i[e.orientation==="horizontal"?"left":"bottom"]=g+"%";a(this).stop(1,1)[h?"animate":"css"](i,c.animate);if(e.options.range===true)if(e.orientation==="horizontal"){if(o===0)e.range.stop(1,1)[h?"animate":"css"]({left:g+"%"},c.animate);if(o===1)e.range[h?"animate":"css"]({width:g- -b+"%"},{queue:false,duration:c.animate})}else{if(o===0)e.range.stop(1,1)[h?"animate":"css"]({bottom:g+"%"},c.animate);if(o===1)e.range[h?"animate":"css"]({height:g-b+"%"},{queue:false,duration:c.animate})}b=g});else{f=this.value();j=this._valueMin();l=this._valueMax();g=l!==j?(f-j)/(l-j)*100:0;i[e.orientation==="horizontal"?"left":"bottom"]=g+"%";this.handle.stop(1,1)[h?"animate":"css"](i,c.animate);if(d==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[h?"animate":"css"]({width:g+"%"}, -c.animate);if(d==="max"&&this.orientation==="horizontal")this.range[h?"animate":"css"]({width:100-g+"%"},{queue:false,duration:c.animate});if(d==="min"&&this.orientation==="vertical")this.range.stop(1,1)[h?"animate":"css"]({height:g+"%"},c.animate);if(d==="max"&&this.orientation==="vertical")this.range[h?"animate":"css"]({height:100-g+"%"},{queue:false,duration:c.animate})}}});a.extend(a.ui.slider,{version:"1.8.16"})})(jQuery); -(function(a,d){function c(){return++h}function e(){return++g}var h=0,g=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
      ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
    • #{label}
    • "},_create:function(){this._tabify(true)},_setOption:function(i,b){if(i=="selected")this.options.collapsible&& -b==this.options.selected||this.select(b);else{this.options[i]=b;this._tabify()}},_tabId:function(i){return i.title&&i.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+c()},_sanitizeSelector:function(i){return i.replace(/:/g,"\\:")},_cookie:function(){var i=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+e());return a.cookie.apply(null,[i].concat(a.makeArray(arguments)))},_ui:function(i,b){return{tab:i,panel:b,index:this.anchors.index(i)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var i= -a(this);i.html(i.data("label.tabs")).removeData("label.tabs")})},_tabify:function(i){function b(r,u){r.css("display","");!a.support.opacity&&u.opacity&&r[0].style.removeAttribute("filter")}var f=this,j=this.options,l=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=a(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);this.anchors.each(function(r,u){var v=a(u).attr("href"),w=v.split("#")[0],x;if(w&&(w===location.toString().split("#")[0]|| -(x=a("base")[0])&&w===x.href)){v=u.hash;u.href=v}if(l.test(v))f.panels=f.panels.add(f.element.find(f._sanitizeSelector(v)));else if(v&&v!=="#"){a.data(u,"href.tabs",v);a.data(u,"load.tabs",v.replace(/#.*$/,""));v=f._tabId(u);u.href="#"+v;u=f.element.find("#"+v);if(!u.length){u=a(j.panelTemplate).attr("id",v).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(f.panels[r-1]||f.list);u.data("destroy.tabs",true)}f.panels=f.panels.add(u)}else j.disabled.push(r)});if(i){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); -this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(j.selected===d){location.hash&&this.anchors.each(function(r,u){if(u.hash==location.hash){j.selected=r;return false}});if(typeof j.selected!=="number"&&j.cookie)j.selected=parseInt(f._cookie(),10);if(typeof j.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)j.selected= -this.lis.index(this.lis.filter(".ui-tabs-selected"));j.selected=j.selected||(this.lis.length?0:-1)}else if(j.selected===null)j.selected=-1;j.selected=j.selected>=0&&this.anchors[j.selected]||j.selected<0?j.selected:0;j.disabled=a.unique(j.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(r){return f.lis.index(r)}))).sort();a.inArray(j.selected,j.disabled)!=-1&&j.disabled.splice(a.inArray(j.selected,j.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); -if(j.selected>=0&&this.anchors.length){f.element.find(f._sanitizeSelector(f.anchors[j.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(j.selected).addClass("ui-tabs-selected ui-state-active");f.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[j.selected],f.element.find(f._sanitizeSelector(f.anchors[j.selected].hash))[0]))});this.load(j.selected)}a(window).bind("unload",function(){f.lis.add(f.anchors).unbind(".tabs");f.lis=f.anchors=f.panels=null})}else j.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); -this.element[j.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");j.cookie&&this._cookie(j.selected,j.cookie);i=0;for(var o;o=this.lis[i];i++)a(o)[a.inArray(i,j.disabled)!=-1&&!a(o).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");j.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(j.event!=="mouseover"){var n=function(r,u){u.is(":not(.ui-state-disabled)")&&u.addClass("ui-state-"+r)},k=function(r,u){u.removeClass("ui-state-"+ -r)};this.lis.bind("mouseover.tabs",function(){n("hover",a(this))});this.lis.bind("mouseout.tabs",function(){k("hover",a(this))});this.anchors.bind("focus.tabs",function(){n("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){k("focus",a(this).closest("li"))})}var m,p;if(j.fx)if(a.isArray(j.fx)){m=j.fx[0];p=j.fx[1]}else m=p=j.fx;var q=p?function(r,u){a(r).closest("li").addClass("ui-tabs-selected ui-state-active");u.hide().removeClass("ui-tabs-hide").animate(p,p.duration||"normal", -function(){b(u,p);f._trigger("show",null,f._ui(r,u[0]))})}:function(r,u){a(r).closest("li").addClass("ui-tabs-selected ui-state-active");u.removeClass("ui-tabs-hide");f._trigger("show",null,f._ui(r,u[0]))},s=m?function(r,u){u.animate(m,m.duration||"normal",function(){f.lis.removeClass("ui-tabs-selected ui-state-active");u.addClass("ui-tabs-hide");b(u,m);f.element.dequeue("tabs")})}:function(r,u){f.lis.removeClass("ui-tabs-selected ui-state-active");u.addClass("ui-tabs-hide");f.element.dequeue("tabs")}; -this.anchors.bind(j.event+".tabs",function(){var r=this,u=a(r).closest("li"),v=f.panels.filter(":not(.ui-tabs-hide)"),w=f.element.find(f._sanitizeSelector(r.hash));if(u.hasClass("ui-tabs-selected")&&!j.collapsible||u.hasClass("ui-state-disabled")||u.hasClass("ui-state-processing")||f.panels.filter(":animated").length||f._trigger("select",null,f._ui(this,w[0]))===false){this.blur();return false}j.selected=f.anchors.index(this);f.abort();if(j.collapsible)if(u.hasClass("ui-tabs-selected")){j.selected= --1;j.cookie&&f._cookie(j.selected,j.cookie);f.element.queue("tabs",function(){s(r,v)}).dequeue("tabs");this.blur();return false}else if(!v.length){j.cookie&&f._cookie(j.selected,j.cookie);f.element.queue("tabs",function(){q(r,w)});f.load(f.anchors.index(this));this.blur();return false}j.cookie&&f._cookie(j.selected,j.cookie);if(w.length){v.length&&f.element.queue("tabs",function(){s(r,v)});f.element.queue("tabs",function(){q(r,w)});f.load(f.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; -a.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(i){if(typeof i=="string")i=this.anchors.index(this.anchors.filter("[href$="+i+"]"));return i},destroy:function(){var i=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var b= -a.data(this,"href.tabs");if(b)this.href=b;var f=a(this).unbind(".tabs");a.each(["href","load","cache"],function(j,l){f.removeData(l+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});i.cookie&&this._cookie(null,i.cookie);return this},add:function(i, -b,f){if(f===d)f=this.anchors.length;var j=this,l=this.options;b=a(l.tabTemplate.replace(/#\{href\}/g,i).replace(/#\{label\}/g,b));i=!i.indexOf("#")?i.replace("#",""):this._tabId(a("a",b)[0]);b.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var o=j.element.find("#"+i);o.length||(o=a(l.panelTemplate).attr("id",i).data("destroy.tabs",true));o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(f>=this.lis.length){b.appendTo(this.list);o.appendTo(this.list[0].parentNode)}else{b.insertBefore(this.lis[f]); -o.insertBefore(this.panels[f])}l.disabled=a.map(l.disabled,function(n){return n>=f?++n:n});this._tabify();if(this.anchors.length==1){l.selected=0;b.addClass("ui-tabs-selected ui-state-active");o.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){j._trigger("show",null,j._ui(j.anchors[0],j.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[f],this.panels[f]));return this},remove:function(i){i=this._getIndex(i);var b=this.options,f=this.lis.eq(i).remove(),j=this.panels.eq(i).remove(); -if(f.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(i+(i+1=i?--l:l});this._tabify();this._trigger("remove",null,this._ui(f.find("a")[0],j[0]));return this},enable:function(i){i=this._getIndex(i);var b=this.options;if(a.inArray(i,b.disabled)!=-1){this.lis.eq(i).removeClass("ui-state-disabled");b.disabled=a.grep(b.disabled,function(f){return f!=i});this._trigger("enable",null, -this._ui(this.anchors[i],this.panels[i]));return this}},disable:function(i){i=this._getIndex(i);var b=this.options;if(i!=b.selected){this.lis.eq(i).addClass("ui-state-disabled");b.disabled.push(i);b.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[i],this.panels[i]))}return this},select:function(i){i=this._getIndex(i);if(i==-1)if(this.options.collapsible&&this.options.selected!=-1)i=this.options.selected;else return this;this.anchors.eq(i).trigger(this.options.event+".tabs");return this}, -load:function(i){i=this._getIndex(i);var b=this,f=this.options,j=this.anchors.eq(i)[0],l=a.data(j,"load.tabs");this.abort();if(!l||this.element.queue("tabs").length!==0&&a.data(j,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(i).addClass("ui-state-processing");if(f.spinner){var o=a("span",j);o.data("label.tabs",o.html()).html(f.spinner)}this.xhr=a.ajax(a.extend({},f.ajaxOptions,{url:l,success:function(n,k){b.element.find(b._sanitizeSelector(j.hash)).html(n);b._cleanup();f.cache&&a.data(j, -"cache.tabs",true);b._trigger("load",null,b._ui(b.anchors[i],b.panels[i]));try{f.ajaxOptions.success(n,k)}catch(m){}},error:function(n,k){b._cleanup();b._trigger("load",null,b._ui(b.anchors[i],b.panels[i]));try{f.ajaxOptions.error(n,k,i,j)}catch(m){}}}));b.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, -url:function(i,b){this.anchors.eq(i).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.8.16"});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(i,b){var f=this,j=this.options,l=f._rotate||(f._rotate=function(o){clearTimeout(f.rotation);f.rotation=setTimeout(function(){var n=j.selected;f.select(++n' + text + ''); - $('form.form-horizontal').append(''); - related_list.push(val); - $('#related_problem').val(''); - $('#related_problem').prop('disabled', false); - $('#related_problem_submit').removeClass('disabled'); - $('.related .close').click(function () { - var pid = $(this).attr('value'); - var index = related_list.indexOf(val); - related_list.splice(index, 1); - $('#related_' + pid).remove(); - }); - }); - $('#related_problem_submit').addClass('disabled'); - $('#related_problem').prop('disabled', true); - } - } - $('form').ajaxError(function() { - $('#related_problem_submit').removeClass('disabled'); - $('#related_problem').prop('disabled', false); - }); - $('.disabled').click(function() { - return false; - }); - $('#related_problem').keypress(function (e) { - var code = (e.keyCode ? e.keyCode : e.which); - if(code == 13) { - add_related_problem(); - return false; - } - }); - $("#related_problem_submit").click(function () { - add_related_problem(); - return false; - }); -}); diff --git a/static/js/problem.js b/static/js/problem.js deleted file mode 100644 index 13aec06..0000000 --- a/static/js/problem.js +++ /dev/null @@ -1,9 +0,0 @@ -$(document).ready(function () { - $('#lang_select > a.btn').click(function () { - var lang = $(this).prop('id'); - $("#lang_select > a.btn").removeClass('btn-success'); - $(this).addClass('btn-success'); - $("input[name='lang']").val(lang); - return false; - }); -}); diff --git a/static/js/timepicker.js b/static/js/timepicker.js deleted file mode 100644 index 0e64e64..0000000 --- a/static/js/timepicker.js +++ /dev/null @@ -1,38 +0,0 @@ -$(document).ready(function() { -$('#start_time').datetimepicker({ - onClose: function(dateText, inst) { - var endDateTextBox = $('#end_time'); - if (endDateTextBox.val() != '') { - var testStartDate = new Date(dateText); - var testEndDate = new Date(endDateTextBox.val()); - if (testStartDate > testEndDate) - endDateTextBox.val(dateText); - } - else { - endDateTextBox.val(dateText); - } - }, - onSelect: function (selectedDateTime){ - var start = $(this).datetimepicker('getDate'); - $('#end_time').datetimepicker('option', 'minDate', new Date(start.getTime())); - } -}); -$('#end_time').datetimepicker({ - onClose: function(dateText, inst) { - var startDateTextBox = $('#start_time'); - if (startDateTextBox.val() != '') { - var testStartDate = new Date(startDateTextBox.val()); - var testEndDate = new Date(dateText); - if (testStartDate > testEndDate) - startDateTextBox.val(dateText); - } - else { - startDateTextBox.val(dateText); - } - }, - onSelect: function (selectedDateTime){ - var end = $(this).datetimepicker('getDate'); - $('#start_time').datetimepicker('option', 'maxDate', new Date(end.getTime()) ); - } -}); -}); diff --git a/tpl/404.html b/tpl/404.html deleted file mode 100644 index 363f33a..0000000 --- a/tpl/404.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - Error 404(Not Found)!!1 - - - -
      -
      -
      -

      404 Not Found...

      -

      The page you want was not found on this server.

      -
      -
      - - diff --git a/tpl/500.html b/tpl/500.html deleted file mode 100644 index c58f44b..0000000 --- a/tpl/500.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - Error 500(Internal Server Error)!!1 - - - -
      -
      -

      500 Internal Server Error...

      -
      {{ error }}
      -
      -
      -
      - - - diff --git a/tpl/backstage/contest_create.html b/tpl/backstage/contest_create.html deleted file mode 100644 index cff496b..0000000 --- a/tpl/backstage/contest_create.html +++ /dev/null @@ -1,73 +0,0 @@ -{% include 'header.html' %} -{%- if error -%} -
      -
        -{% for err in error %} -
      • {{ err }}
      • -{% endfor %} -
      -
      -{% endif %} -
      -
      - {{ title }} - {{ page.xsrf_form_html() }} - -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - - {{ _('Add') }} - -
      -
      -{% if related_problem %} -{% for problem in related_problem %} - -{% endfor %} -{% endif %} -
      - -
      - -{% include 'footer.html' %} diff --git a/tpl/backstage/index.html b/tpl/backstage/index.html deleted file mode 100644 index 4b33445..0000000 --- a/tpl/backstage/index.html +++ /dev/null @@ -1,5 +0,0 @@ -{% include 'header.html' %} - -{% include 'footer.html' %} diff --git a/tpl/backstage/node_create.html b/tpl/backstage/node_create.html deleted file mode 100644 index 47d5ab6..0000000 --- a/tpl/backstage/node_create.html +++ /dev/null @@ -1,41 +0,0 @@ -{% include 'header.html' %} -{%- if error -%} -
      -
        -{% for err in error %} -
      • {{ err }}
      • -{% endfor %} -
      -
      -{% endif %} -
      -
      - {{ _('Add Node') }} - {{ page.xsrf_form_html() }} - -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      -
      - -
      -
      -
      -
      - -
      - -{% include 'footer.html' %} diff --git a/tpl/backstage/problem_add.html b/tpl/backstage/problem_add.html deleted file mode 100644 index 579f176..0000000 --- a/tpl/backstage/problem_add.html +++ /dev/null @@ -1,136 +0,0 @@ -{% include 'header.html' %} -{%- if error -%} -
      -
        -{% for err in error %} -
      • {{ err }}
      • -{% endfor %} -
      -
      -{% endif %} -
      -
      - {{ _('Add Problem') }} - {{ page.xsrf_form_html() }} - -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      -
      - - ms -
      -
      -
      -
      - -
      -
      - - MB -
      -
      -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - - {{ _('Add') }} -
        - {% if tags %} - {% for tag in tags %} -
      • - {{ tag }} - -
      • - {% endfor%} - {% endif %} -
      -
      -
      -
      - -
      -
      -{% if tags %} -{% for tag in tags %} - -{% endfor %} -{% endif %} -
      - -{% include 'footer.html' %} diff --git a/tpl/contest.html b/tpl/contest.html deleted file mode 100644 index 0fab040..0000000 --- a/tpl/contest.html +++ /dev/null @@ -1,95 +0,0 @@ -{% include 'header.html' %} -{% if now < contest.start_time %} -
      - {{ _('This contest have not started.') }} -
      -{% elif contest.start_time <= now <= contest.end_time %} -
      - {{ _('This contest is running.') }} -
      -{% else %} -
      - {{ _('This contest have finished.') }} -
      -{% endif %} -
      - - - - - - - - - - - - - - - - - - {% if user.admin %} - - - - {% endif %} -
      {{ _('Title') }}{{ contest.title }}
      {{ _('Start Time') }}{{ contest.start_time }}
      {{ _('End Time') }}{{ contest.end_time }}
      {{ _('Status') }}{{ contest | get_contest_status }}
      {{ _('Edit Contest') }}
      - {% if contest.description -%} -
      {{ contest.description }}
      -
      - {%- endif %} -
      -{% if not now < contest.start_time %} -
      - - - - - - - - - - - - {% for problem in related_problem %} - - - - - - - - {% endfor %} - -
      #{{ _('Title') }}{{ _('Submit Time') }}{{ _('Short Name') }}{{ _('Score') }}
      {{ problem.pid }}{{ problem.title }}{{ problem.submit.create }}{{ problem.shortname }}{{ problem.submit.score }}
      -{% endif %} -{% if contest.start_time <= now <= contest.end_time %} -
      -
      - {{ _('Submit Problem') }} -
      -
      - -
      - -
      -
      -
      - - -
      - Pascal - C - C++ -
      -
      -
      - -
      -
      -
      -{% endif %} -{% include 'footer.html' %} diff --git a/tpl/contest_list.html b/tpl/contest_list.html deleted file mode 100644 index 07703bc..0000000 --- a/tpl/contest_list.html +++ /dev/null @@ -1,31 +0,0 @@ -{% include 'header.html' %} -
      - {% if contests %} - {% for contest in contests %} -
      - - - - - - - - - - - - - - - - - - - - -
      {{ _('Title') }}{{ contest.title }}
      {{ _('Start Time') }}{{ contest.start_time }}
      {{ _('End Time') }}{{ contest.end_time }}
      {{ _('Status') }}{{ contest | get_contest_status }}
      {{ _('Enter Contest') }}{% if user.admin %} • Edit Contest{% endif %}
      -
      - {% endfor %} - {% endif %} -
      -{% include 'footer.html' %} diff --git a/tpl/count.html b/tpl/count.html deleted file mode 100644 index 94d8ac3..0000000 --- a/tpl/count.html +++ /dev/null @@ -1,15 +0,0 @@ -{% if count %} - -{% endif %} diff --git a/tpl/error.html b/tpl/error.html deleted file mode 100644 index 264e446..0000000 --- a/tpl/error.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Error {{ status_code }}({{ msg }})!!1 - - - -
      -
      -
      -

      {{ status_code }} {{ msg }}...

      -

      If you see this message. Please contact this website administrator.

      -
      -
      - - - - diff --git a/tpl/footer.html b/tpl/footer.html deleted file mode 100644 index 9943ff0..0000000 --- a/tpl/footer.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/tpl/forget.html b/tpl/forget.html deleted file mode 100644 index e0e35a8..0000000 --- a/tpl/forget.html +++ /dev/null @@ -1,15 +0,0 @@ -{% include 'header.html' %} -{%- if error -%} -
        -{% for err in error %} -
      • {{ err }}
      • -{% endfor %} -
      -{% endif %} -
      -{{ page.xsrf_form_html() }} -{{ _('Username') }}: -{{ _('Email') }}: - -
      -{% include 'footer.html' %} diff --git a/tpl/forum.html b/tpl/forum.html deleted file mode 100644 index 1f67d85..0000000 --- a/tpl/forum.html +++ /dev/null @@ -1,47 +0,0 @@ -{% include 'header.html' %} -{% if topics %} -
      - -
      -{% else %} -
      - {{ _('oooops. There have no more topic.') }} -
      -{% endif %} - -
      -
      -
      - {{ _('Nodes') }} -
      -
      - {% for node in nodes %} - {{ node.name }} - {%- if not loop.last -%} -  •  - {%- endif -%} - {% endfor %} -
      -
      -{% include 'footer.html' %} diff --git a/tpl/header.html b/tpl/header.html deleted file mode 100644 index e45e716..0000000 --- a/tpl/header.html +++ /dev/null @@ -1,165 +0,0 @@ - - - - - {{ page.settings['site_title'] }}{% if title %} › {{ title }}{% endif %} - - - - - - - {% if problem %}{% endif %} - {% if related_js %}{% endif %} - {% if timepicker_js %} - - {% endif %} - - - - -
      -{% if breadcrumb %} - -{% endif %} diff --git a/tpl/home.html b/tpl/home.html deleted file mode 100644 index a251a0a..0000000 --- a/tpl/home.html +++ /dev/null @@ -1,79 +0,0 @@ -{% include 'header.html' %} - -{% if newest_problem %} -
      -
      {{ _('Latest Problem') }}
      - - - - - - - - - - {% for problem in newest_problem %} - {% if problem.invisible == 0 or user.admin == 1%} - - - - - - {% endif %} - {% endfor %} - -
      #{{ _('Title') }}{{ _('Short Name') }}
      {{ problem.id }}{{ problem.title }}{{ problem.shortname }}
      -
      -
      -{% endif %} -
      -
      {{ _('Latest Discuss') }}
      - -
      -{% include 'footer.html' %} diff --git a/tpl/index.html b/tpl/index.html deleted file mode 100644 index 1bbecfb..0000000 --- a/tpl/index.html +++ /dev/null @@ -1 +0,0 @@ -{% include 'home.html' %} diff --git a/tpl/member.html b/tpl/member.html deleted file mode 100644 index 45b7031..0000000 --- a/tpl/member.html +++ /dev/null @@ -1,45 +0,0 @@ -{% include 'header.html' %} -
      -
      - -
      -
      -
      -

      {{ member.username }}

      -
      -
      -{{ member.tagline }} -
      -
      -{{ _('ID:') }}{{ member.id }}. {{ _('Joined at') }} {{ member.create }} -
      - -
      -
      -
      -{% if notes %} - -{% endif %} -
      -
      -Bio -
      -
      -{{ member.bio.replace("\n", "
      ") }} -
      -
      -{% include 'footer.html' %} diff --git a/tpl/member_note.html b/tpl/member_note.html deleted file mode 100644 index 6cef56f..0000000 --- a/tpl/member_note.html +++ /dev/null @@ -1,24 +0,0 @@ -{% include 'header.html' %} -{% if member.id == user.id %} - -{% endif %} -{% if not notes %} -
      - {{ _('There are empty now. Add something here.') }} -
      -{% endif %} -
        - {% for note in notes %} -
      • -

        {{ note.title }}

        -
        {{ note.create }}
        -
        - {{ note.content.replace('\n', ' ').replace('<pre>', '').replace('</pre>', '')[:200] }} -
        - -
      • - {% endfor %} -
      -{% include 'footer.html' %} diff --git a/tpl/node.html b/tpl/node.html deleted file mode 100644 index 77dd45f..0000000 --- a/tpl/node.html +++ /dev/null @@ -1,62 +0,0 @@ -{% include 'header.html' %} -
      -
      - {% if user %} - {{ _('Create New Topic') }} - {% endif %} -
      - {% if topics %} - - {% else %} -
      - {{ _('oooops. There have no more topic.') }}{{ _('Create') }} One? -
      - {% endif %} -
      -
      -{% if user %} -
      -
      - {{ _('Create New Topic') }} - {{ page.xsrf_form_html() }} -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      -
      -
      -{% endif %} -{% include 'footer.html' %} diff --git a/tpl/note.html b/tpl/note.html deleted file mode 100644 index 667ab8e..0000000 --- a/tpl/note.html +++ /dev/null @@ -1,19 +0,0 @@ -{% include 'header.html' %} -{% if related_problem %} - -{% endif %} -
      -

      {{ note.title }}

      -
      {{ note.create }} {% if note.member_id == user.id %} | {{ _('Edit') }} | {{ _('Delete') }}{% endif %}
      -
      - {{ note.content | autolink | nl_to_br | pre_to_code }} -
      -
      -{% include 'footer.html' %} diff --git a/tpl/note_create.html b/tpl/note_create.html deleted file mode 100644 index b141315..0000000 --- a/tpl/note_create.html +++ /dev/null @@ -1,57 +0,0 @@ -{% include 'header.html' %} -{%- if error -%} -
      - × -
        - {% for err in error %} -
      • {{ err }}
      • - {% endfor %} -
      -
      -{% endif %} -
      -
      - {% if note.nid %}{{ _('Edit Note') }}{% else %}{{ _('Write Note') }}{% endif %} -
      - {{ page.xsrf_form_html() }} -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - - {{ _('Add') }} - -
      -
      - -
      - -
      -{% if related_problem %} -{% for problem in related_problem %} - -{% endfor %} -{% endif %} -
      -
      -{% include 'footer.html' %} diff --git a/tpl/problem.html b/tpl/problem.html deleted file mode 100644 index 3815c5d..0000000 --- a/tpl/problem.html +++ /dev/null @@ -1,95 +0,0 @@ -{% include 'header.html' %} -{% if problem.invisible %} -
      - {{ _('This Problem is Invisible!') }} -
      -{% endif %} - -
      -
      - {{ _('Content') }} -
      -
      - {{ problem.content | autolink | replace('\n', '
      ')}} -
      -
      -{% if user %} -
      -
      - {{ _('Submit Problem') }} -
      -
      - -
      - -
      -
      -
      - - -
      - Pascal - C - C++ -
      -
      -
      - -
      -
      -
      -{% endif %} -{% include 'footer.html' %} diff --git a/tpl/problem_list.html b/tpl/problem_list.html deleted file mode 100644 index c917fcc..0000000 --- a/tpl/problem_list.html +++ /dev/null @@ -1,23 +0,0 @@ -{% include 'header.html' %} - - - - - - - - - - {% for problem in problems %} - {% if problem.invisible == 0 or user.admin == 1%} - - - - - - {% endif %} - {% endfor %} - -
      #{{ _('Title') }}{{ _('Short Name') }}
      {{ problem.id }}{{ problem.title }}{{ problem.shortname }}
      -{% include 'count.html' %} -{% include 'footer.html' %} diff --git a/tpl/reset.html b/tpl/reset.html deleted file mode 100644 index d1d59dd..0000000 --- a/tpl/reset.html +++ /dev/null @@ -1,21 +0,0 @@ -{% include 'header.html' %} -{% if success %} -{{ _('You have reseted your password successfully.')}} -{{ _('Sign in Now') }} -{% else %} -{%- if error -%} -
        -{% for err in error %} -
      • {{ err }}
      • -{% endfor %} -
      -{% endif %} -
      -

      {{ _('Reset Password') }} - {{ reset_user['username'] }}

      -{{ page.xsrf_form_html() }} -{{ _('New Password') }}:
      -{{ _('Repeat Password') }}:
      - -
      -{% endif %} -{% include 'footer.html' %} diff --git a/tpl/settings.html b/tpl/settings.html deleted file mode 100644 index e19c0da..0000000 --- a/tpl/settings.html +++ /dev/null @@ -1,91 +0,0 @@ -{% include 'header.html' %} -{%- if error -%} -
      -
        - {% for err in error %} -
      • {{ err }}
      • - {% endfor %} -
      -
      -{% endif %} -{% if msg %} -
      - × - {{ msg }} -
      -{% endif %} -
      -
      -{{ _('Basic Settings') }} -
      -{{ page.xsrf_form_html() }} -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - {% if lang %} - - {% else %} - - {% endif %} -
      -
      -
      - -
      - -
      -
      -
      - -
      -
      -
      -
      -
      - {{ _('Change Password') }} - {{ page.xsrf_form_html() }} -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      -
      -
      -{% include 'footer.html' %} diff --git a/tpl/settings_changepass.html b/tpl/settings_changepass.html deleted file mode 100644 index b2f44a3..0000000 --- a/tpl/settings_changepass.html +++ /dev/null @@ -1,32 +0,0 @@ -{% include 'header.html' %} -{%- if error -%} -
      -
        - {% for err in error %} -
      • {{ err }}
      • - {% endfor %} -
      -
      -{% endif %} -
      -
      - {{ _('Change Password') }} - {{ page.xsrf_form_html() }} -
      -
      - -
      - -
      -
      -
      - -
      - -
      -
      -
      - -
      - -{% include 'footer.html' %} diff --git a/tpl/signin.html b/tpl/signin.html deleted file mode 100644 index c18637a..0000000 --- a/tpl/signin.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - {{ page.settings['site_title'] }} - - - - - - - -
      - -
      -{% if error %} -
      - × -
        - {% for err in error %} -
      • {{ err }}
      • - {% endfor %} -
      -
      -{% endif %} -
      -{{ page.xsrf_form_html() }} -
      - - -
      -
      - - -
      -
      - -
      - -
      -
      - -
      - - diff --git a/tpl/signup.html b/tpl/signup.html deleted file mode 100644 index 4814e9e..0000000 --- a/tpl/signup.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - {{ page.settings['site_title'] }} - - - - - - - -
      - -
      -{% if error %} -
      - × -
        - {% for err in error %} -
      • {{ err }}
      • - {% endfor %} -
      -
      -{% endif %} -
      -{{ page.xsrf_form_html() }} -
      - - -
      -
      - - -
      -
      - - -
      -
      - -
      - -
      -
      - -
      - - diff --git a/tpl/submit.html b/tpl/submit.html deleted file mode 100644 index 65d5165..0000000 --- a/tpl/submit.html +++ /dev/null @@ -1,32 +0,0 @@ -{% include 'header.html' %} - - - - - - - - - - - - - - - {% if submits %} - {% for submit in submits %} - - - - - - - - - - - {% endfor %} - {% endif %} - -
      #{{ _('Status') }}{{ _('Test Point') }}{{ _('Problem') }}{{ _('User') }}{{ _('Score') }}{{ _('Time') }}{{ _('Memory') }}
      {{ submit.id }}{{ submit.status | submitstatus }}{{ submit.testpoint }}{{ submit.title }}{{ submit.username }}{{ submit.score }}{{ submit.costtime }}{{ submit.costmemory }}
      -{% include 'footer.html' %} diff --git a/tpl/test.html b/tpl/test.html deleted file mode 100644 index 88c606a..0000000 --- a/tpl/test.html +++ /dev/null @@ -1 +0,0 @@ -{{ msg | nl2br }} diff --git a/tpl/topic.html b/tpl/topic.html deleted file mode 100644 index 4f6353a..0000000 --- a/tpl/topic.html +++ /dev/null @@ -1,87 +0,0 @@ -{% include 'header.html' %} - -
      -
      -
      -
      {{ topic.title }}
      -
      By {{ topic.username }} at {{ topic.create }}
      -
      -
      - {{ topic.content | autolink | replace('\n', '
      ') }} -
      -
      - -
      -{% if replies %} -
      -
      - {{ reply_count }} Replies -
      -
        - {% for reply in replies %} -
      • - - - - - - -
        - - -
        - {{ reply.username }} -
        {{ reply.create }}
        -
        -
        - {{ reply.content | autolink | replace('\n', '
        ') }} -
        -
        -
      • - {% endfor %} -
      -
      -{% else %} -
      - {{ _('No Reply Yet') }} -
      -{% endif %} - -
      - -{% if error %} -
      -
        - {% for err in error %} -
      • {{ err }}
      • - {% endfor %} -
      -
      -{% endif %} - -
      -
      - {{ _('Add Reply') }} - {{ page.xsrf_form_html() }} -
      -
      -
      - -
      -
      -
      - -
      -
      -
      -{% include 'footer.html' %} diff --git a/tpl/topic_create.html b/tpl/topic_create.html deleted file mode 100644 index 49f0b28..0000000 --- a/tpl/topic_create.html +++ /dev/null @@ -1,35 +0,0 @@ -{% include 'header.html' %} -{%- if error -%} -
      - × -
        - {% for err in error %} -
      • {{ err }}
      • - {% endfor %} -
      -
      -{% endif %} -
      -
      - {% if topic.nid %}{{ _('Edit Topic') }}{% else %}{{ _('Create Topic') }}{% endif %} -
      - {{ page.xsrf_form_html() }} -
      - -
      - -
      -
      -
      - -
      - -
      -
      - -
      - -
      -
      -
      -{% include 'footer.html' %} From 229f1c875c55115241fff9e158897d57019a78a1 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 8 Mar 2012 02:30:21 +0800 Subject: [PATCH 02/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=A1=A8=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/base/__init__.py | 21 ++++- judge/db/__init__.py | 199 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 judge/db/__init__.py diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 9d51e7f..14bba7f 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 01:54:14 08/03/2012 +# MODIFIED: 02:10:52 08/03/2012 # DESCRIPTION: Base handler import tornado.web @@ -32,3 +32,22 @@ def render(self): def write_error(self): '''Rewrite write_error for custom error page''' pass + +class BaseDBObject(object): + ''' Base Table Object ''' + def __repr__(self): + ''' for debug ''' + result = ", \n".join(["'%s': '%s'" % (attr, getattr(self, attr)) for attr in dir(self) if attr[0] != '_' and not callable(getattr(self, attr)) ]) + return "<{%s}>" % result + def _init_row(self, row): + keys = row.keys() + for key in keys: + setattr(self, key, row[key]) + +class BaseDBMixin(object): + ''' Base Database Mixin ''' + def _new_object_by_row(self, Obj, row): + obj = Obj() + obj._init_row(row) + return obj + diff --git a/judge/db/__init__.py b/judge/db/__init__.py new file mode 100644 index 0000000..8e85ab0 --- /dev/null +++ b/judge/db/__init__.py @@ -0,0 +1,199 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: judge/db/__init__.py +# CREATED: 02:01:23 08/03/2012 +# MODIFIED: 02:29:52 08/03/2012 +# DESCRIPTION: Database Table Object + +from judge.base import BaseDBMixin +from judge.base import BaseDBObject + +''' +'' =================================== +'' Member Table +'' =================================== +''' + +class Member(BaseDBObject): + '''User data table''' + __tablename__ = "member" + id = 0 + username = "" + username_lower = "" + passowrd = "" + email = "" + website = "" + tagline = "" + bio = "" + gravatar_link = "" + create = None + admin = 0 + lang = 1 + +class Auth(BaseDBObject): + '''User auth table''' + __tablename__ = "auth" + member_id = 0 + secret = "" + create = None + +class ResetMail(BaseDBObject): + '''User reset mail table''' + __tablename__ = "reset_mail" + member_id = 0 + secret = "" + create = None + +class MemberDBMixin(BaseDBMixin): + pass + +''' +'' =================================== +'' Forum Table +'' =================================== +''' + +class Node(BaseDBObject): + '''Forum node table''' + __tablename__ = "node" + id = 0 + name = "" + description = "" + link = "" + +class Topic(BaseDBObject): + '''Forum topic table''' + __tablename__ = "topic" + id = 0 + title = "" + content = "" + node_id = 0 + member_id = 0 + create = None + last_reply = None + +class Reply(BaseDBObject): + '''Forum topic reply table''' + __tablename__ = "reply" + id = 0 + content = "" + member_id = 0 + topic_id = 0 + create = None + +class ForumDBMixin(BaseDBMixin): + pass + +''' +'' =================================== +'' Note Table +'' =================================== +''' + +class Note(BaseDBObject): + '''Note data table''' + __tablename__ = "note" + id = 0 + title = "" + content = "" + member_id = 0 + create = None + +class RelatedProblem(BaseDBObject): + '''Note related problem table''' + __tablename__ = "related_problem" + problem_id = 0 + note_id = 0 + +class NoteDBMixin(BaseDBMixin): + pass + +''' +'' =================================== +'' Problem Table +'' =================================== +''' + +class Problem(BaseDBObject): + '''Problem table''' + __tablename__ = "problem" + id = 0 + title = "" + shortname = "" + content = "" + timelimit = 0 + memlimit = 0 + testpoint = 0 + invisible = 0 + create = None + +class ProblemTag(BaseDBObject): + '''Problem tag table''' + __tablename__ = "problem_tag" + problem_id = 0 + tagname = "" + +class Submit(BaseDBObject): + '''Submit table''' + __tablename__ = "submit" + id = 0 + problem_id = 0 + member_id = 0 + status = 0 + testpoint = "" + score = 0 + costtime = 0 + costmemory = 0 + timestamp = "" + lang = 0 + msg = "" + user_agent = 0 + ip = 0 + create = 0 + +class ProblemDBMixin(BaseDBMixin): + pass + +''' +'' =================================== +'' Contest Table +'' =================================== +''' + +class Contest(BaseDBObject): + '''Contest data table''' + __tablename__ = "contest" + id = 0 + title = "" + description = "" + start_time = None + end_time = None + invisible = 0 + create = None + +class ContestProblem(BaseDBObject): + '''Contest problem table''' + __tablename__ = "contest_problem" + contest_id = 0 + problem_id = 0 + +class ContestSubmit(BaseDBObject): + '''Contest submit table''' + __tablename__ = "contest_submit" + contest_id = 0 + problem_id = 0 + member_id = 0 + status = 0 + testpoint = "" + score = 0 + costtime = 0 + costmemory = 0 + timestamp = "" + lang = 0 + msg = "" + user_agent = 0 + ip = 0 + create = 0 + +class ContestDBMixin(BaseDBMixin): + pass From 36d4a44339601604d5804e778a823b351f0b3d05 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 8 Mar 2012 02:36:26 +0800 Subject: [PATCH 03/56] config file --- config.example.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 config.example.py diff --git a/config.example.py b/config.example.py new file mode 100644 index 0000000..1953914 --- /dev/null +++ b/config.example.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: config.example.py +# CREATED: 02:35:50 08/03/2012 +# MODIFIED: 02:36:05 08/03/2012 +# DESCRIPTION: site config + +import os + +mysql_config = { + 'mysql_host' : '', + 'mysql_user' : '', + 'mysql_password' : '', + 'mysql_database' : '' +} + +accept_lang = { + 'zh_cn' : 'zh_CN', + 'en' : 'en_US', +} + +site_config = { + 'site_title' : u'Online Judge', + 'base_domain' : '', + 'login_url' : '/signin', + 'template_path' : os.path.join(os.path.dirname(__file__), 'tpl'), + 'static_path' : os.path.join(os.path.dirname(__file__), "static"), + 'i18n_path' : os.path.join(os.path.dirname(__file__), 'i18n'), + 'xsrf_cookies' : True, + 'cookie_secret' : '', # + 'bcrypt_salt' : '', # import bcrypt; bcrypt.gensalt(log_rounds=4) + 'default_mail' : 'no-reply@fanhe.org', + 'mail_server' : '127.0.0.1', +} + From a22fc07680793a0d02032211f744037e9ba23d8a Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 8 Mar 2012 02:57:47 +0800 Subject: [PATCH 04/56] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20property?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/base/__init__.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 14bba7f..cedffd2 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 02:10:52 08/03/2012 +# MODIFIED: 02:57:32 08/03/2012 # DESCRIPTION: Base handler import tornado.web @@ -32,6 +32,12 @@ def render(self): def write_error(self): '''Rewrite write_error for custom error page''' pass + @property + def db(self): + return self.application.db + @property + def jinja2: + return self.application.jinja2 class BaseDBObject(object): ''' Base Table Object ''' From 6298db8daaa81995cb5c8ac36305679e9ab1f086 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 8 Mar 2012 02:58:51 +0800 Subject: [PATCH 05/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers.py | 16 ++++++++++++++++ lang.py | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 handlers.py create mode 100644 lang.py diff --git a/handlers.py b/handlers.py new file mode 100644 index 0000000..bc4a505 --- /dev/null +++ b/handlers.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: handlers.py +# CREATED: 01:41:06 08/03/2012 +# MODIFIED: 02:55:14 08/03/2012 +# DESCRIPTION: URL Route + +from lang import * + +''' +'' Handler 命名规范: [动宾结构 / 名词] + Handler +''' + +handlers = [ + (r'/lang/(.*)', SetLanguageHandler), +] diff --git a/lang.py b/lang.py new file mode 100644 index 0000000..ace14fe --- /dev/null +++ b/lang.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: lang.py +# CREATED: 02:44:51 08/03/2012 +# MODIFIED: 02:54:55 08/03/2012 +# DESCRIPTION: Set language handler + +from tornado.web import HTTPError + +from config import accept_lang + +from judge.base import BaseHandler + +class SetLanguageHandler(BaseHandler): + ''' `/lang/(.*)` - set language. ''' + def get(self, lang): + if lang not in accept_lang.keys(): + raise HTTPError(404) + self.set_cookie('LANG', accept_lang[lang]) + if self.request.headers.has_key('Referer'): + self.redirect(self.request.headers['Referer']) + return + self.redirect('/') + +__all__ = ["SetLanguageHandler"] From 5e2092a9ac773fc5226de50fe60a933b7f64a3d5 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 8 Mar 2012 03:16:29 +0800 Subject: [PATCH 06/56] add home handler --- handlers.py | 4 +++- home.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 home.py diff --git a/handlers.py b/handlers.py index bc4a505..6db7cce 100644 --- a/handlers.py +++ b/handlers.py @@ -2,9 +2,10 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 02:55:14 08/03/2012 +# MODIFIED: 03:09:36 08/03/2012 # DESCRIPTION: URL Route +from home import * from lang import * ''' @@ -12,5 +13,6 @@ ''' handlers = [ + (r'/', HomeHandler), (r'/lang/(.*)', SetLanguageHandler), ] diff --git a/home.py b/home.py new file mode 100644 index 0000000..6dc41b2 --- /dev/null +++ b/home.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: home.py +# CREATED: 02:00:16 08/03/2012 +# MODIFIED: 03:06:43 08/03/2012 +# DESCRIPTION: Home handler + +from judge.base import BaseHandler + +class HomeHandler(BaseHandler): + def get(self): + title = self._("Home") + breadcrumb = [] + breadcrumb.append((self._("Home"), "/")) + self.render("home.html", locals()) + +__all__ = ["HomeHandler"] From cac39d6fbb7c159fd3f12c181f0a7c29da12b5d7 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 8 Mar 2012 03:16:37 +0800 Subject: [PATCH 07/56] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=8B=E8=AF=AF?= =?UTF-8?q?=E2=80=A6=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/base/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/judge/base/__init__.py b/judge/base/__init__.py index cedffd2..7df7dd2 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 02:57:32 08/03/2012 +# MODIFIED: 03:15:48 08/03/2012 # DESCRIPTION: Base handler import tornado.web @@ -36,7 +36,7 @@ def write_error(self): def db(self): return self.application.db @property - def jinja2: + def jinja2(self): return self.application.jinja2 class BaseDBObject(object): From a278f34d437abd72a48e2c989e9ec50e4c420dd3 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 8 Mar 2012 03:41:58 +0800 Subject: [PATCH 08/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=20write=5Ferror=20rend?= =?UTF-8?q?er=20=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完成 write_error render 函数 完成 error.html 404.html 500.html 模板 --- judge/base/__init__.py | 29 ++++++++++++++++++++++----- static/img/404.png | Bin 0 -> 88597 bytes static/img/500.png | Bin 0 -> 117959 bytes static/img/error.jpg | Bin 0 -> 110832 bytes tpl/404.html | 35 ++++++++++++++++++++++++++++++++ tpl/500.html | 38 +++++++++++++++++++++++++++++++++++ tpl/error.html | 44 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 static/img/404.png create mode 100644 static/img/500.png create mode 100644 static/img/error.jpg create mode 100644 tpl/404.html create mode 100644 tpl/500.html create mode 100644 tpl/error.html diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 7df7dd2..fa43838 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,9 +2,12 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 03:15:48 08/03/2012 +# MODIFIED: 03:31:08 08/03/2012 # DESCRIPTION: Base handler +import httplib +import traceback + import tornado.web import tornado.escape @@ -26,12 +29,28 @@ def get_user_locale(self): def sendmail(self): '''Send mail func, send mail to someone''' pass - def render(self): + def render(self, tplname, args = {}): '''Rewrite render func for use jinja2''' - pass - def write_error(self): + if "self" in args.keys(): + args.pop("self") + tpl = self.jinja2.get_template(tplname) + ren = tpl.render(page = self, _ = self._, user = self.current_user, **args) + self.write(ren) + self.finish() + def write_error(self, status_code, **kwargs): '''Rewrite write_error for custom error page''' - pass + if status_code == 404: + self.render("404.html") + return + elif status_code == 500: + error = [] + for line in traceback.format_exception(*kwargs['exc_info']): + error.append(line) + error = "\n".join(error) + self.render("500.html", locals()) + return + msg = httplib.responses[status_code] + self.render("error.html", locals()) @property def db(self): return self.application.db diff --git a/static/img/404.png b/static/img/404.png new file mode 100644 index 0000000000000000000000000000000000000000..2f2f47e3009a6e7270e4040e66f9fd1d2c1674ed GIT binary patch literal 88597 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 {k(#8^ZIymw@LvW>L}UF;43BU;Srp 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 *ZluS1Y^L)>(%u|v;uAXCVE~zw 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 Ms@f{WO3#D;2Zty6J^%m! literal 0 HcmV?d00001 diff --git a/static/img/500.png b/static/img/500.png new file mode 100644 index 0000000000000000000000000000000000000000..4c96a17c9d42628f220fc2c604bd56346f6e5727 GIT binary patch literal 117959 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≶qikq5~64aGSD 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⪙w%p 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 literal 0 HcmV?d00001 diff --git a/static/img/error.jpg b/static/img/error.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f45d3f51edeb159587847caf6745b2527089e808 GIT binary patch literal 110832 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⋘6x=audZ{_qI>1$;5PlY$}M;m=9m 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 + + diff --git a/tpl/500.html b/tpl/500.html new file mode 100644 index 0000000..c58f44b --- /dev/null +++ b/tpl/500.html @@ -0,0 +1,38 @@ + + + + + Error 500(Internal Server Error)!!1 + + + +
      +
      +

      500 Internal Server Error...

      +
      {{ error }}
      +
      +
      +
      + + + diff --git a/tpl/error.html b/tpl/error.html new file mode 100644 index 0000000..264e446 --- /dev/null +++ b/tpl/error.html @@ -0,0 +1,44 @@ + + + + + Error {{ status_code }}({{ msg }})!!1 + + + +
      +
      +
      +

      {{ status_code }} {{ msg }}...

      +

      If you see this message. Please contact this website administrator.

      +
      +
      + + + + From 8dfd1e81c17d38795f917271f5a1fcd5b95c84d1 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Fri, 9 Mar 2012 04:30:00 +0800 Subject: [PATCH 09/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=EF=BC=8C=E6=A8=A1=E6=9D=BF=E6=9E=84=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完成 base.html 等 完成 signin/signup.html 样式及页面 半完成 tpl/base/sidebar.html --- Makefile | 5 + handlers.py | 5 +- judge/base/__init__.py | 15 +- judge/filters/__init__.py | 9 +- less/bootstrap/accordion.less | 28 + less/bootstrap/alerts.less | 70 + less/bootstrap/bootstrap.less | 62 + less/bootstrap/breadcrumbs.less | 22 + less/bootstrap/button-groups.less | 148 + less/bootstrap/buttons.less | 183 + less/bootstrap/carousel.less | 121 + less/bootstrap/close.less | 18 + less/bootstrap/code.less | 57 + less/bootstrap/component-animations.less | 18 + less/bootstrap/dropdowns.less | 130 + less/bootstrap/forms.less | 522 +++ less/bootstrap/grid.less | 8 + less/bootstrap/hero-unit.less | 20 + less/bootstrap/labels.less | 32 + less/bootstrap/layouts.less | 17 + less/bootstrap/mixins.less | 590 ++++ less/bootstrap/modals.less | 83 + less/bootstrap/navbar.less | 299 ++ less/bootstrap/navs.less | 353 ++ less/bootstrap/pager.less | 30 + less/bootstrap/pagination.less | 55 + less/bootstrap/popovers.less | 49 + less/bootstrap/progress-bars.less | 95 + less/bootstrap/reset.less | 126 + less/bootstrap/responsive.less | 327 ++ less/bootstrap/scaffolding.less | 29 + less/bootstrap/sprites.less | 158 + less/bootstrap/tables.less | 150 + less/bootstrap/thumbnails.less | 35 + less/bootstrap/tooltip.less | 35 + less/bootstrap/type.less | 218 ++ less/bootstrap/utilities.less | 23 + less/bootstrap/variables.less | 107 + less/bootstrap/wells.less | 17 + less/style.less | 124 + member.py | 24 + signup.html | 55 + static/css/style.css | 3811 +++++++++++++++++++++ static/img/avatar.png | Bin 0 -> 1323 bytes static/img/background-dark.png | Bin 0 -> 23656 bytes static/img/bg-black.gif | Bin 0 -> 14700 bytes static/img/bg-noise.jpg | Bin 0 -> 3438 bytes static/img/glyphicons-halflings-white.png | Bin 0 -> 4352 bytes static/img/glyphicons-halflings.png | Bin 0 -> 4352 bytes static/img/lines.jpg | Bin 0 -> 19856 bytes tpl/base.html | 9 + tpl/base/breadcrumb.html | 16 + tpl/base/head.html | 9 + tpl/base/sidebar.html | 129 + tpl/home.html | 5 + tpl/signin.html | 49 + tpl/signup.html | 53 + vars.less | 22 + 58 files changed, 8571 insertions(+), 4 deletions(-) create mode 100644 Makefile create mode 100644 less/bootstrap/accordion.less create mode 100644 less/bootstrap/alerts.less create mode 100644 less/bootstrap/bootstrap.less create mode 100644 less/bootstrap/breadcrumbs.less create mode 100644 less/bootstrap/button-groups.less create mode 100644 less/bootstrap/buttons.less create mode 100644 less/bootstrap/carousel.less create mode 100644 less/bootstrap/close.less create mode 100644 less/bootstrap/code.less create mode 100644 less/bootstrap/component-animations.less create mode 100644 less/bootstrap/dropdowns.less create mode 100644 less/bootstrap/forms.less create mode 100644 less/bootstrap/grid.less create mode 100644 less/bootstrap/hero-unit.less create mode 100644 less/bootstrap/labels.less create mode 100644 less/bootstrap/layouts.less create mode 100644 less/bootstrap/mixins.less create mode 100644 less/bootstrap/modals.less create mode 100644 less/bootstrap/navbar.less create mode 100644 less/bootstrap/navs.less create mode 100644 less/bootstrap/pager.less create mode 100644 less/bootstrap/pagination.less create mode 100644 less/bootstrap/popovers.less create mode 100644 less/bootstrap/progress-bars.less create mode 100644 less/bootstrap/reset.less create mode 100644 less/bootstrap/responsive.less create mode 100644 less/bootstrap/scaffolding.less create mode 100644 less/bootstrap/sprites.less create mode 100644 less/bootstrap/tables.less create mode 100644 less/bootstrap/thumbnails.less create mode 100644 less/bootstrap/tooltip.less create mode 100644 less/bootstrap/type.less create mode 100644 less/bootstrap/utilities.less create mode 100644 less/bootstrap/variables.less create mode 100644 less/bootstrap/wells.less create mode 100644 less/style.less create mode 100644 member.py create mode 100644 signup.html create mode 100644 static/css/style.css create mode 100644 static/img/avatar.png create mode 100644 static/img/background-dark.png create mode 100644 static/img/bg-black.gif create mode 100644 static/img/bg-noise.jpg create mode 100644 static/img/glyphicons-halflings-white.png create mode 100644 static/img/glyphicons-halflings.png create mode 100644 static/img/lines.jpg create mode 100644 tpl/base.html create mode 100644 tpl/base/breadcrumb.html create mode 100644 tpl/base/head.html create mode 100644 tpl/base/sidebar.html create mode 100644 tpl/home.html create mode 100644 tpl/signin.html create mode 100644 tpl/signup.html create mode 100644 vars.less diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..51dc407 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +# Makefile console for config Vulpix +# Author: Zeray Rice + +less: + lessc less/style.less > static/css/style.css diff --git a/handlers.py b/handlers.py index 6db7cce..46893fa 100644 --- a/handlers.py +++ b/handlers.py @@ -2,11 +2,12 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 03:09:36 08/03/2012 +# MODIFIED: 03:10:54 09/03/2012 # DESCRIPTION: URL Route from home import * from lang import * +from member import * ''' '' Handler 命名规范: [动宾结构 / 名词] + Handler @@ -14,5 +15,7 @@ handlers = [ (r'/', HomeHandler), + (r'/signin', SigninHandler), + (r'/signup', SignupHandler), (r'/lang/(.*)', SetLanguageHandler), ] diff --git a/judge/base/__init__.py b/judge/base/__init__.py index fa43838..7767aa8 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,15 +2,28 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 03:31:08 08/03/2012 +# MODIFIED: 02:44:38 09/03/2012 # DESCRIPTION: Base handler import httplib +import functools import traceback import tornado.web import tornado.escape +def unauthenticated(method): + """Decorate methods with this to require that user be NOT logged in""" + @functools.wraps(method) + def wrapper(self, *args, **kwargs): + if self.current_user: + if self.request.method in ("GET", "HEAD"): + self.redirect("/") + return + raise HTTPError(403) + return method(self, *args, **kwargs) + return wrapper + class BaseHandler(tornado.web.RequestHandler): _ = lambda self, text: self.locale.translate(text) # i18n func xhtml_escape = lambda self, text: tornado.escape.xhtml_escape(text) if text else text # xhtml escape diff --git a/judge/filters/__init__.py b/judge/filters/__init__.py index 50811dd..3c75492 100644 --- a/judge/filters/__init__.py +++ b/judge/filters/__init__.py @@ -2,7 +2,12 @@ # AUTHOR: Zeray Rice # FILE: judge/filters/__init__.py # CREATED: 01:48:10 08/03/2012 -# MODIFIED: 01:48:22 08/03/2012 +# MODIFIED: 04:06:44 09/03/2012 # DESCRIPTION: jinja2 filters -filters = {} +def avatar_img(link, size = 45): + return "" % (link, size, size) + +filters = { + 'avatar_img' : avatar_img, +} diff --git a/less/bootstrap/accordion.less b/less/bootstrap/accordion.less new file mode 100644 index 0000000..11a36b5 --- /dev/null +++ b/less/bootstrap/accordion.less @@ -0,0 +1,28 @@ +// ACCORDION +// --------- + + +// Parent container +.accordion { + margin-bottom: @baseLineHeight; +} + +// Group == heading + body +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + .border-radius(4px); +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} + +// Inner needs the styles because you can't animate properly with any styles on the element +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} diff --git a/less/bootstrap/alerts.less b/less/bootstrap/alerts.less new file mode 100644 index 0000000..562826f --- /dev/null +++ b/less/bootstrap/alerts.less @@ -0,0 +1,70 @@ +// ALERT STYLES +// ------------ + +// Base alert styles +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: @baseLineHeight; + text-shadow: 0 1px 0 rgba(255,255,255,.5); + background-color: @warningBackground; + border: 1px solid @warningBorder; + .border-radius(4px); +} +.alert, +.alert-heading { + color: @warningText; +} + +// Adjust close link position +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; +} + +// Alternate styles +// ---------------- + +.alert-success { + background-color: @successBackground; + border-color: @successBorder; +} +.alert-success, +.alert-success .alert-heading { + color: @successText; +} +.alert-danger, +.alert-error { + background-color: @errorBackground; + border-color: @errorBorder; +} +.alert-danger, +.alert-error, +.alert-danger .alert-heading, +.alert-error .alert-heading { + color: @errorText; +} +.alert-info { + background-color: @infoBackground; + border-color: @infoBorder; +} +.alert-info, +.alert-info .alert-heading { + color: @infoText; +} + + +// Block alerts +// ------------------------ +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} diff --git a/less/bootstrap/bootstrap.less b/less/bootstrap/bootstrap.less new file mode 100644 index 0000000..4b09b7a --- /dev/null +++ b/less/bootstrap/bootstrap.less @@ -0,0 +1,62 @@ +/*! + * Bootstrap v2.0.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +// CSS Reset +@import "reset.less"; + +// Core variables and mixins +@import "variables.less"; // Modify this for custom colors, font-sizes, etc +@import "mixins.less"; + +// Grid system and page structure +@import "scaffolding.less"; +@import "grid.less"; +@import "layouts.less"; + +// Base CSS +@import "type.less"; +@import "code.less"; +@import "forms.less"; +@import "tables.less"; + +// Components: common +@import "sprites.less"; +@import "dropdowns.less"; +@import "wells.less"; +@import "component-animations.less"; +@import "close.less"; + +// Components: Buttons & Alerts +@import "buttons.less"; +@import "button-groups.less"; +@import "alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less + +// Components: Nav +@import "navs.less"; +@import "navbar.less"; +@import "breadcrumbs.less"; +@import "pagination.less"; +@import "pager.less"; + +// Components: Popovers +@import "modals.less"; +@import "tooltip.less"; +@import "popovers.less"; + +// Components: Misc +@import "thumbnails.less"; +@import "labels.less"; +@import "progress-bars.less"; +@import "accordion.less"; +@import "carousel.less"; +@import "hero-unit.less"; + +// Utility classes +@import "utilities.less"; // Has to be last to override when necessary diff --git a/less/bootstrap/breadcrumbs.less b/less/bootstrap/breadcrumbs.less new file mode 100644 index 0000000..39060ba --- /dev/null +++ b/less/bootstrap/breadcrumbs.less @@ -0,0 +1,22 @@ +// BREADCRUMBS +// ----------- + +.breadcrumb { + padding: 7px 14px; + margin: 0 0 @baseLineHeight; + #gradient > .vertical(@white, #f5f5f5); + border: 1px solid #ddd; + .border-radius(3px); + .box-shadow(inset 0 1px 0 @white); + li { + display: inline-block; + text-shadow: 0 1px 0 @white; + } + .divider { + padding: 0 5px; + color: @grayLight; + } + .active a { + color: @grayDark; + } +} diff --git a/less/bootstrap/button-groups.less b/less/bootstrap/button-groups.less new file mode 100644 index 0000000..a04220a --- /dev/null +++ b/less/bootstrap/button-groups.less @@ -0,0 +1,148 @@ +// BUTTON GROUPS +// ------------- + + +// Make the div behave like a button +.btn-group { + position: relative; + .clearfix(); // clears the floated buttons + .ie7-restore-left-whitespace(); +} + +// Space out series of button groups +.btn-group + .btn-group { + margin-left: 5px; +} + +// Optional: Group multiple button groups together for a toolbar +.btn-toolbar { + margin-top: @baseLineHeight / 2; + margin-bottom: @baseLineHeight / 2; + .btn-group { + display: inline-block; + .ie7-inline-block(); + } +} + +// Float them, remove border radius, then re-add to first and last elements +.btn-group .btn { + position: relative; + float: left; + margin-left: -1px; + .border-radius(0); +} +// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match +.btn-group .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group .btn:last-child, +.btn-group .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +// Reset corners for large buttons +.btn-group .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group .btn.large:last-child, +.btn-group .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} + +// On hover/focus/active, bring the proper btn to front +.btn-group .btn:hover, +.btn-group .btn:focus, +.btn-group .btn:active, +.btn-group .btn.active { + z-index: 2; +} + +// On active and open, don't show outline +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + + + +// Split button dropdowns +// ---------------------- + +// Give the line between buttons some depth +.btn-group .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + @shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + .box-shadow(@shadow); + *padding-top: 5px; + *padding-bottom: 5px; +} + +.btn-group.open { + // IE7's z-index only goes to the nearest positioned ancestor, which would + // make the menu appear below buttons that appeared later on the page + *z-index: @zindexDropdown; + + // Reposition menu on open and round all corners + .dropdown-menu { + display: block; + margin-top: 1px; + .border-radius(5px); + } + + .dropdown-toggle { + background-image: none; + @shadow: inset 0 1px 6px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + .box-shadow(@shadow); + } +} + +// Reposition the caret +.btn .caret { + margin-top: 7px; + margin-left: 0; +} +.btn:hover .caret, +.open.btn-group .caret { + .opacity(100); +} + + +// Account for other colors +.btn-primary, +.btn-danger, +.btn-info, +.btn-success, +.btn-inverse { + .caret { + border-top-color: @white; + .opacity(75); + } +} + +// Small button dropdowns +.btn-small .caret { + margin-top: 4px; +} + diff --git a/less/bootstrap/buttons.less b/less/bootstrap/buttons.less new file mode 100644 index 0000000..55e9fbf --- /dev/null +++ b/less/bootstrap/buttons.less @@ -0,0 +1,183 @@ +// BUTTON STYLES +// ------------- + + +// Base styles +// -------------------------------------------------- + +// Core +.btn { + display: inline-block; + padding: 4px 10px 4px; + margin-bottom: 0; // For input.btn + font-size: @baseFontSize; + line-height: @baseLineHeight; + color: @grayDark; + text-align: center; + text-shadow: 0 1px 1px rgba(255,255,255,.75); + vertical-align: middle; + .buttonBackground(@white, darken(@white, 10%)); + border: 1px solid #ccc; + border-bottom-color: #bbb; + .border-radius(4px); + @shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05); + .box-shadow(@shadow); + cursor: pointer; + + // Give IE7 some love + .reset-filter(); + .ie7-restore-left-whitespace(); +} + +// Hover state +.btn:hover { + color: @grayDark; + text-decoration: none; + background-color: darken(@white, 10%); + background-position: 0 -15px; + + // transition is only when going to hover, otherwise the background + // behind the gradient (there for IE<=9 fallback) gets mismatched + .transition(background-position .1s linear); +} + +// Focus state for keyboard and accessibility +.btn:focus { + .tab-focus(); +} + +// Active state +.btn.active, +.btn:active { + background-image: none; + @shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + .box-shadow(@shadow); + background-color: darken(@white, 10%); + background-color: darken(@white, 15%) e("\9"); + outline: 0; +} + +// Disabled state +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + background-color: darken(@white, 10%); + .opacity(65); + .box-shadow(none); +} + + +// Button Sizes +// -------------------------------------------------- + +// Large +.btn-large { + padding: 9px 14px; + font-size: @baseFontSize + 2px; + line-height: normal; + .border-radius(5px); +} +.btn-large [class^="icon-"] { + margin-top: 1px; +} + +// Small +.btn-small { + padding: 5px 9px; + font-size: @baseFontSize - 2px; + line-height: @baseLineHeight - 2px; +} +.btn-small [class^="icon-"] { + margin-top: -1px; +} + +// Mini +.btn-mini { + padding: 2px 6px; + font-size: @baseFontSize - 2px; + line-height: @baseLineHeight - 4px; +} + + +// Alternate buttons +// -------------------------------------------------- + +// Set text color +// ------------------------- +.btn-primary, +.btn-primary:hover, +.btn-warning, +.btn-warning:hover, +.btn-danger, +.btn-danger:hover, +.btn-success, +.btn-success:hover, +.btn-info, +.btn-info:hover, +.btn-inverse, +.btn-inverse:hover { + text-shadow: 0 -1px 0 rgba(0,0,0,.25); + color: @white; +} +// Provide *some* extra contrast for those who can get it +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-dark.active { + color: rgba(255,255,255,.75); +} + +// Set the backgrounds +// ------------------------- +.btn-primary { + .buttonBackground(@primaryButtonBackground, spin(@primaryButtonBackground, 20)); +} +// Warning appears are orange +.btn-warning { + .buttonBackground(lighten(@orange, 15%), @orange); +} +// Danger and error appear as red +.btn-danger { + .buttonBackground(#ee5f5b, #bd362f); +} +// Success appears as green +.btn-success { + .buttonBackground(#62c462, #51a351); +} +// Info appears as a neutral blue +.btn-info { + .buttonBackground(#5bc0de, #2f96b4); +} +// Inverse appears as dark gray +.btn-inverse { + .buttonBackground(#454545, #262626); +} + + +// Cross-browser Jank +// -------------------------------------------------- + +button.btn, +input[type="submit"].btn { + + // Firefox 3.6 only I believe + &::-moz-focus-inner { + padding: 0; + border: 0; + } + + // IE7 has some default padding on button controls + *padding-top: 2px; + *padding-bottom: 2px; + &.large { + *padding-top: 7px; + *padding-bottom: 7px; + } + &.small { + *padding-top: 3px; + *padding-bottom: 3px; + } +} diff --git a/less/bootstrap/carousel.less b/less/bootstrap/carousel.less new file mode 100644 index 0000000..8fbd303 --- /dev/null +++ b/less/bootstrap/carousel.less @@ -0,0 +1,121 @@ +// CAROUSEL +// -------- + +.carousel { + position: relative; + margin-bottom: @baseLineHeight; + line-height: 1; +} + +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} + +.carousel { + + .item { + display: none; + position: relative; + .transition(.6s ease-in-out left); + } + + // Account for jankitude on images + .item > img { + display: block; + line-height: 1; + } + + .active, + .next, + .prev { display: block; } + + .active { + left: 0; + } + + .next, + .prev { + position: absolute; + top: 0; + width: 100%; + } + + .next { + left: 100%; + } + .prev { + left: -100%; + } + .next.left, + .prev.right { + left: 0; + } + + .active.left { + left: -100%; + } + .active.right { + left: 100%; + } + +} + +// Left/right controls for nav +// --------------------------- + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: @white; + text-align: center; + background: @grayDarker; + border: 3px solid @white; + .border-radius(23px); + .opacity(50); + + // we can't have this transition here + // because webkit cancels the carousel + // animation if you trip this while + // in the middle of another animation + // ;_; + // .transition(opacity .2s linear); + + // Reposition the right one + &.right { + left: auto; + right: 15px; + } + + // Hover state + &:hover { + color: @white; + text-decoration: none; + .opacity(90); + } +} + +// Caption for text below images +// ----------------------------- + +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 10px 15px 5px; + background: @grayDark; + background: rgba(0,0,0,.75); +} +.carousel-caption h4, +.carousel-caption p { + color: @white; +} diff --git a/less/bootstrap/close.less b/less/bootstrap/close.less new file mode 100644 index 0000000..a0e5edb --- /dev/null +++ b/less/bootstrap/close.less @@ -0,0 +1,18 @@ +// CLOSE ICONS +// ----------- + +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: @baseLineHeight; + color: @black; + text-shadow: 0 1px 0 rgba(255,255,255,1); + .opacity(20); + &:hover { + color: @black; + text-decoration: none; + .opacity(40); + cursor: pointer; + } +} diff --git a/less/bootstrap/code.less b/less/bootstrap/code.less new file mode 100644 index 0000000..e2157d8 --- /dev/null +++ b/less/bootstrap/code.less @@ -0,0 +1,57 @@ +// Code.less +// Code typography styles for the and
       elements
      +// --------------------------------------------------------
      +
      +// Inline and block code styles
      +code,
      +pre {
      +  padding: 0 3px 2px;
      +  #font > #family > .monospace;
      +  font-size: @baseFontSize - 1;
      +  color: @grayDark;
      +  .border-radius(3px);
      +}
      +
      +// Inline code
      +code {
      +  padding: 3px 4px;
      +  color: #d14;
      +  background-color: #f7f7f9;
      +  border: 1px solid #e1e1e8;
      +}
      +
      +// Blocks of code
      +pre {
      +  display: block;
      +  padding: (@baseLineHeight - 1) / 2;
      +  margin: 0 0 @baseLineHeight / 2;
      +  font-size: 12px;
      +  line-height: @baseLineHeight;
      +  background-color: #f5f5f5;
      +  border: 1px solid #ccc; // fallback for IE7-8
      +  border: 1px solid rgba(0,0,0,.15);
      +  .border-radius(4px);
      +  white-space: pre;
      +  white-space: pre-wrap;
      +  word-break: break-all;
      +  word-wrap: break-word;
      +
      +  // Make prettyprint styles more spaced out for readability
      +  &.prettyprint {
      +    margin-bottom: @baseLineHeight;
      +  }
      +
      +  // Account for some code outputs that place code tags in pre tags
      +  code {
      +    padding: 0;
      +    color: inherit;
      +    background-color: transparent;
      +    border: 0;
      +  }
      +}
      +
      +// Enable scrollable blocks of code
      +.pre-scrollable {
      +  max-height: 340px;
      +  overflow-y: scroll;
      +}
      \ No newline at end of file
      diff --git a/less/bootstrap/component-animations.less b/less/bootstrap/component-animations.less
      new file mode 100644
      index 0000000..4f2a4fd
      --- /dev/null
      +++ b/less/bootstrap/component-animations.less
      @@ -0,0 +1,18 @@
      +// COMPONENT ANIMATIONS
      +// --------------------
      +
      +.fade {
      +  .transition(opacity .15s linear);
      +  opacity: 0;
      +  &.in {
      +    opacity: 1;
      +  }
      +}
      +
      +.collapse {
      +  .transition(height .35s ease);
      +  position:relative;
      +  overflow:hidden;
      +  height: 0;
      +  &.in { height: auto; }
      +}
      diff --git a/less/bootstrap/dropdowns.less b/less/bootstrap/dropdowns.less
      new file mode 100644
      index 0000000..1ec06b0
      --- /dev/null
      +++ b/less/bootstrap/dropdowns.less
      @@ -0,0 +1,130 @@
      +// DROPDOWN MENUS
      +// --------------
      +
      +// Use the .menu class on any 
    • element within the topbar or ul.tabs and you'll get some superfancy dropdowns +.dropdown { + position: relative; +} +.dropdown-toggle { + // The caret makes the toggle a bit too tall in IE7 + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +// Dropdown arrow/caret +.caret { + display: inline-block; + width: 0; + height: 0; + text-indent: -99999px; + // IE7 won't do the border trick if there's a text indent, but it doesn't + // do the content that text-indent is hiding, either, so we're ok. + *text-indent: 0; + vertical-align: top; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid @black; + .opacity(30); + content: "\2193"; +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown:hover .caret, +.open.dropdown .caret { + .opacity(100); +} +// The dropdown menu (ul) +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: @zindexDropdown; + float: left; + display: none; // none by default, but block on "open" of the menu + min-width: 160px; + _width: 160px; + padding: 4px 0; + margin: 0; // override default ul + list-style: none; + background-color: @white; + border-color: #ccc; + border-color: rgba(0,0,0,.2); + border-style: solid; + border-width: 1px; + .border-radius(0 0 5px 5px); + .box-shadow(0 5px 10px rgba(0,0,0,.2)); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + *border-right-width: 2px; + *border-bottom-width: 2px; + + // Allow for dropdowns to go bottom up (aka, dropup-menu) + &.bottom-up { + top: auto; + bottom: 100%; + margin-bottom: 2px; + } + + // Dividers (basically an hr) within the dropdown + .divider { + height: 1px; + margin: 5px 1px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid @white; + + // IE7 needs a set width since we gave a height. Restricting just + // to IE7 to keep the 1px left/right space in other browsers. + // It is unclear where IE is getting the extra space that we need + // to negative-margin away, but so it goes. + *width: 100%; + *margin: -5px 0 5px; + } + + // Links within the dropdown menu + a { + display: block; + padding: 3px 15px; + clear: both; + font-weight: normal; + line-height: @baseLineHeight; + color: @gray; + white-space: nowrap; + } +} + +// Hover state +.dropdown-menu li > a:hover, +.dropdown-menu .active > a, +.dropdown-menu .active > a:hover { + color: @white; + text-decoration: none; + background-color: @linkColor; +} + +// Open state for the dropdown +.dropdown.open { + // IE7's z-index only goes to the nearest positioned ancestor, which would + // make the menu appear below buttons that appeared later on the page + *z-index: @zindexDropdown; + + .dropdown-toggle { + color: @white; + background: #ccc; + background: rgba(0,0,0,.3); + } + .dropdown-menu { + display: block; + } +} + +// Typeahead +.typeahead { + margin-top: 2px; // give it some space to breathe + .border-radius(4px); +} diff --git a/less/bootstrap/forms.less b/less/bootstrap/forms.less new file mode 100644 index 0000000..0a5fa2b --- /dev/null +++ b/less/bootstrap/forms.less @@ -0,0 +1,522 @@ +// Forms.less +// Base styles for various input types, form layouts, and states +// ------------------------------------------------------------- + + +// GENERAL STYLES +// -------------- + +// Make all forms have space below them +form { + margin: 0 0 @baseLineHeight; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +// Groups of fields with labels on top (legends) +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: @baseLineHeight * 1.5; + font-size: @baseFontSize * 1.5; + line-height: @baseLineHeight * 2; + color: @grayDark; + border: 0; + border-bottom: 1px solid #eee; + + // Small + small { + font-size: @baseLineHeight * .75; + color: @grayLight; + } +} + +// Set font for forms +label, +input, +button, +select, +textarea { + #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here +} +input, +button, +select, +textarea { + #font > #family > .sans-serif(); // And only set font-family here for those that need it (note the missing label element) +} + +// Identify controls by their labels +label { + display: block; + margin-bottom: 5px; + color: @grayDark; +} + +// Inputs, Textareas, Selects +input, +textarea, +select, +.uneditable-input { + display: inline-block; + width: 210px; + height: @baseLineHeight; + padding: 4px; + margin-bottom: 9px; + font-size: @baseFontSize; + line-height: @baseLineHeight; + color: @gray; + border: 1px solid #ccc; + .border-radius(3px); +} +.uneditable-textarea { + width: auto; + height: auto; +} + +// Inputs within a label +label input, +label textarea, +label select { + display: block; +} + +// Mini reset for unique input types +input[type="image"], +input[type="checkbox"], +input[type="radio"] { + width: auto; + height: auto; + padding: 0; + margin: 3px 0; + *margin-top: 0; /* IE7 */ + line-height: normal; + cursor: pointer; + .border-radius(0); + border: 0 \9; /* IE9 and down */ +} +input[type="image"] { + border: 0; +} + +// Reset the file input to browser defaults +input[type="file"] { + width: auto; + padding: initial; + line-height: initial; + border: initial; + background-color: @white; + background-color: initial; + .box-shadow(none); +} + +// Help out input buttons +input[type="button"], +input[type="reset"], +input[type="submit"] { + width: auto; + height: auto; +} + +// Set the height of select and file controls to match text inputs +select, +input[type="file"] { + height: 28px; /* In IE7, the height of the select element cannot be changed by height, only font-size */ + *margin-top: 4px; /* For IE7, add top margin to align select with labels */ + line-height: 28px; +} + +// Reset line-height for IE +input[type="file"] { + line-height: 18px \9; +} + +// Chrome on Linux and Mobile Safari need background-color +select { + width: 220px; // default input width + 10px of padding that doesn't get applied + background-color: @white; +} + +// Make multiple select elements height not fixed +select[multiple], +select[size] { + height: auto; +} + +// Remove shadow from image inputs +input[type="image"] { + .box-shadow(none); +} + +// Make textarea height behave +textarea { + height: auto; +} + +// Hidden inputs +input[type="hidden"] { + display: none; +} + + + +// CHECKBOXES & RADIOS +// ------------------- + +// Indent the labels to position radios/checkboxes as hanging +.radio, +.checkbox { + padding-left: 18px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -18px; +} + +// Move the options list down to align with labels +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; // has to be padding because margin collaspes +} + +// Radios and checkboxes on same line +// TODO v3: Convert .inline to .control-inline +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; // space out consecutive inline controls +} + + + +// FOCUS STATE +// ----------- + +input, +textarea { + .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); + @transition: border linear .2s, box-shadow linear .2s; + .transition(@transition); +} +input:focus, +textarea:focus { + border-color: rgba(82,168,236,.8); + @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6); + .box-shadow(@shadow); + outline: 0; + outline: thin dotted \9; /* IE6-9 */ +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus, +select:focus { + .box-shadow(none); // override for file inputs + .tab-focus(); +} + + + +// INPUT SIZES +// ----------- + +// General classes for quick sizes +.input-mini { width: 60px; } +.input-small { width: 90px; } +.input-medium { width: 150px; } +.input-large { width: 210px; } +.input-xlarge { width: 270px; } +.input-xxlarge { width: 530px; } + +// Grid style input sizes +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input { + float: none; + margin-left: 0; +} + + + +// GRID SIZING FOR INPUTS +// ---------------------- + +#inputGridSystem > .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth); + + + + +// DISABLED STATE +// -------------- + +// Disabled and read-only inputs +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + background-color: #f5f5f5; + border-color: #ddd; + cursor: not-allowed; +} + + + + +// FORM FIELD FEEDBACK STATES +// -------------------------- + +// Warning +.control-group.warning { + .formFieldState(@warningText, @warningText, @warningBackground); +} +// Error +.control-group.error { + .formFieldState(@errorText, @errorText, @errorBackground); +} +// Success +.control-group.success { + .formFieldState(@successText, @successText, @successBackground); +} + +// HTML5 invalid states +// Shares styles with the .control-group.error above +input:focus:required:invalid, +textarea:focus:required:invalid, +select:focus:required:invalid { + color: #b94a48; + border-color: #ee5f5b; + &:focus { + border-color: darken(#ee5f5b, 10%); + .box-shadow(0 0 6px lighten(#ee5f5b, 20%)); + } +} + + + +// FORM ACTIONS +// ------------ + +.form-actions { + padding: (@baseLineHeight - 1) 20px @baseLineHeight; + margin-top: @baseLineHeight; + margin-bottom: @baseLineHeight; + background-color: #f5f5f5; + border-top: 1px solid #ddd; +} + +// For text that needs to appear as an input but should not be an input +.uneditable-input { + display: block; + background-color: @white; + border-color: #eee; + .box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); + cursor: not-allowed; +} + +// Placeholder text gets special styles; can't be bundled together though for some reason +.placeholder(@grayLight); + + + +// HELP TEXT +// --------- + +.help-block { + display: block; // account for any element using help-block + margin-top: 5px; + margin-bottom: 0; + color: @grayLight; +} + +.help-inline { + display: inline-block; + .ie7-inline-block(); + margin-bottom: 9px; + vertical-align: middle; + padding-left: 5px; +} + + + +// INPUT GROUPS +// ------------ + +// Allow us to put symbols and text within the input field for a cleaner look +.input-prepend, +.input-append { + margin-bottom: 5px; + .clearfix(); // Clear the float to prevent wrapping + input, + .uneditable-input { + .border-radius(0 3px 3px 0); + &:focus { + position: relative; + z-index: 2; + } + } + .uneditable-input { + border-left-color: #ccc; + } + .add-on { + float: left; + display: block; + width: auto; + min-width: 16px; + height: @baseLineHeight; + margin-right: -1px; + padding: 4px 5px; + font-weight: normal; + line-height: @baseLineHeight; + color: @grayLight; + text-align: center; + text-shadow: 0 1px 0 @white; + background-color: #f5f5f5; + border: 1px solid #ccc; + .border-radius(3px 0 0 3px); + } + .active { + background-color: lighten(@green, 30); + border-color: @green; + } +} +.input-prepend { + .add-on { + *margin-top: 1px; /* IE6-7 */ + } +} +.input-append { + input, + .uneditable-input { + float: left; + .border-radius(3px 0 0 3px); + } + .uneditable-input { + border-left-color: #eee; + border-right-color: #ccc; + } + .add-on { + margin-right: 0; + margin-left: -1px; + .border-radius(0 3px 3px 0); + } + input:first-child { + // In IE7, having a hasLayout container (from clearfix's zoom:1) can make the first input + // inherit the sum of its ancestors' margins. + *margin-left: -160px; + + &+.add-on { + *margin-left: -21px; + } + } +} + + + +// SEARCH FORM +// ----------- + +.search-query { + padding-left: 14px; + padding-right: 14px; + margin-bottom: 0; // remove the default margin on all inputs + .border-radius(14px); +} + + + +// HORIZONTAL & VERTICAL FORMS +// --------------------------- + +// Common properties +// ----------------- + +.form-search, +.form-inline, +.form-horizontal { + input, + textarea, + select, + .help-inline, + .uneditable-input { + display: inline-block; + margin-bottom: 0; + } + // Re-hide hidden elements due to specifity + .hide { + display: none; + } +} +.form-search label, +.form-inline label, +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + display: inline-block; +} +// Make the prepend and append add-on vertical-align: middle; +.form-search .input-append .add-on, +.form-inline .input-prepend .add-on, +.form-search .input-append .add-on, +.form-inline .input-prepend .add-on { + vertical-align: middle; +} +// Inline checkbox/radio labels +.form-search .radio, +.form-inline .radio, +.form-search .checkbox, +.form-inline .checkbox { + margin-bottom: 0; + vertical-align: middle; +} + +// Margin to space out fieldsets +.control-group { + margin-bottom: @baseLineHeight / 2; +} + +// Legend collapses margin, so next element is responsible for spacing +legend + .control-group { + margin-top: @baseLineHeight; + -webkit-margin-top-collapse: separate; +} + +// Horizontal-specific styles +// -------------------------- + +.form-horizontal { + // Increase spacing between groups + .control-group { + margin-bottom: @baseLineHeight; + .clearfix(); + } + // Float the labels left + .control-label { + float: left; + width: 140px; + padding-top: 5px; + text-align: right; + } + // Move over all input controls and content + .controls { + margin-left: 160px; + } + // Move over buttons in .form-actions to align with .controls + .form-actions { + padding-left: 160px; + } +} diff --git a/less/bootstrap/grid.less b/less/bootstrap/grid.less new file mode 100644 index 0000000..4acb0a4 --- /dev/null +++ b/less/bootstrap/grid.less @@ -0,0 +1,8 @@ +// GRID SYSTEM +// ----------- + +// Fixed (940px) +#gridSystem > .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth); + +// Fluid (940px) +#fluidGridSystem > .generate(@gridColumns, @fluidGridColumnWidth, @fluidGridGutterWidth); diff --git a/less/bootstrap/hero-unit.less b/less/bootstrap/hero-unit.less new file mode 100644 index 0000000..cba1cc4 --- /dev/null +++ b/less/bootstrap/hero-unit.less @@ -0,0 +1,20 @@ +// HERO UNIT +// --------- + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + background-color: #f5f5f5; + .border-radius(6px); + h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + } + p { + font-size: 18px; + font-weight: 200; + line-height: @baseLineHeight * 1.5; + } +} diff --git a/less/bootstrap/labels.less b/less/bootstrap/labels.less new file mode 100644 index 0000000..268435a --- /dev/null +++ b/less/bootstrap/labels.less @@ -0,0 +1,32 @@ +// LABELS +// ------ + +// Base +.label { + padding: 2px 4px 3px; + font-size: @baseFontSize * .85; + font-weight: bold; + color: @white; + text-shadow: 0 -1px 0 rgba(0,0,0,.25); + background-color: @grayLight; + .border-radius(3px); +} + +// Hover state +.label:hover { + color: @white; + text-decoration: none; +} + +// Colors +.label-important { background-color: @errorText; } +.label-important:hover { background-color: darken(@errorText, 10%); } + +.label-warning { background-color: @orange; } +.label-warning:hover { background-color: darken(@orange, 10%); } + +.label-success { background-color: @successText; } +.label-success:hover { background-color: darken(@successText, 10%); } + +.label-info { background-color: @infoText; } +.label-info:hover { background-color: darken(@infoText, 10%); } diff --git a/less/bootstrap/layouts.less b/less/bootstrap/layouts.less new file mode 100644 index 0000000..c8d358b --- /dev/null +++ b/less/bootstrap/layouts.less @@ -0,0 +1,17 @@ +// +// Layouts +// Fixed-width and fluid (with sidebar) layouts +// -------------------------------------------- + + +// Container (centered, fixed-width layouts) +.container { + .container-fixed(); +} + +// Fluid layouts (left aligned, with sidebar, min- & max-width content) +.container-fluid { + padding-left: @gridGutterWidth; + padding-right: @gridGutterWidth; + .clearfix(); +} \ No newline at end of file diff --git a/less/bootstrap/mixins.less b/less/bootstrap/mixins.less new file mode 100644 index 0000000..3cf1a37 --- /dev/null +++ b/less/bootstrap/mixins.less @@ -0,0 +1,590 @@ +// Mixins.less +// Snippets of reusable CSS to develop faster and keep code readable +// ----------------------------------------------------------------- + + +// UTILITY MIXINS +// -------------------------------------------------- + +// Clearfix +// -------- +// For clearing floats like a boss h5bp.com/q +.clearfix { + *zoom: 1; + &:before, + &:after { + display: table; + content: ""; + } + &:after { + clear: both; + } +} + +// Webkit-style focus +// ------------------ +.tab-focus() { + // Default + outline: thin dotted #333; + // Webkit + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +// Center-align a block level element +// ---------------------------------- +.center-block() { + display: block; + margin-left: auto; + margin-right: auto; +} + +// IE7 inline-block +// ---------------- +.ie7-inline-block() { + *display: inline; /* IE7 inline-block hack */ + *zoom: 1; +} + +// IE7 likes to collapse whitespace on either side of the inline-block elements. +// Ems because we're attempting to match the width of a space character. Left +// version is for form buttons, which typically come after other elements, and +// right version is for icons, which come before. Applying both is ok, but it will +// mean that space between those elements will be .6em (~2 space characters) in IE7, +// instead of the 1 space in other browsers. +.ie7-restore-left-whitespace() { + *margin-left: .3em; + + &:first-child { + *margin-left: 0; + } +} + +.ie7-restore-right-whitespace() { + *margin-right: .3em; + + &:last-child { + *margin-left: 0; + } +} + +// Sizing shortcuts +// ------------------------- +.size(@height: 5px, @width: 5px) { + width: @width; + height: @height; +} +.square(@size: 5px) { + .size(@size, @size); +} + +// Placeholder text +// ------------------------- +.placeholder(@color: @placeholderText) { + :-moz-placeholder { + color: @color; + } + ::-webkit-input-placeholder { + color: @color; + } +} + +// Text overflow +// ------------------------- +// Requires inline-block or block for proper styling +.text-overflow() { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + + + +// FONTS +// -------------------------------------------------- + +#font { + #family { + .serif() { + font-family: Georgia, "Times New Roman", Times, serif; + } + .sans-serif() { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + } + .monospace() { + font-family: Menlo, Monaco, "Courier New", monospace; + } + } + .shorthand(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { + font-size: @size; + font-weight: @weight; + line-height: @lineHeight; + } + .serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { + #font > #family > .serif; + #font > .shorthand(@size, @weight, @lineHeight); + } + .sans-serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { + #font > #family > .sans-serif; + #font > .shorthand(@size, @weight, @lineHeight); + } + .monospace(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { + #font > #family > .monospace; + #font > .shorthand(@size, @weight, @lineHeight); + } +} + + + +// GRID SYSTEM +// -------------------------------------------------- + +// Site container +// ------------------------- +.container-fixed() { + width: @gridRowWidth; + margin-left: auto; + margin-right: auto; + .clearfix(); +} + +// Le grid system +// ------------------------- +#gridSystem { + // Setup the mixins to be used + .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, @columns) { + width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)); + } + .offset(@gridColumnWidth, @gridGutterWidth, @columns) { + margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)) + (@gridGutterWidth * 2); + } + .gridColumn(@gridGutterWidth) { + float: left; + margin-left: @gridGutterWidth; + } + // Take these values and mixins, and make 'em do their thang + .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth) { + // Row surrounds the columns + .row { + margin-left: @gridGutterWidth * -1; + .clearfix(); + } + // Find all .span# classes within .row and give them the necessary properties for grid columns (supported by all browsers back to IE7, thanks @dhg) + [class*="span"] { + #gridSystem > .gridColumn(@gridGutterWidth); + } + // Default columns + .span1 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 1); } + .span2 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 2); } + .span3 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 3); } + .span4 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 4); } + .span5 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 5); } + .span6 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 6); } + .span7 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 7); } + .span8 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 8); } + .span9 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 9); } + .span10 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 10); } + .span11 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 11); } + .span12, + .container { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 12); } + // Offset column options + .offset1 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 1); } + .offset2 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 2); } + .offset3 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 3); } + .offset4 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 4); } + .offset5 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 5); } + .offset6 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 6); } + .offset7 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 7); } + .offset8 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 8); } + .offset9 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 9); } + .offset10 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 10); } + .offset11 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 11); } + } +} + +// Fluid grid system +// ------------------------- +#fluidGridSystem { + // Setup the mixins to be used + .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, @columns) { + width: 1% * (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)); + } + .gridColumn(@fluidGridGutterWidth) { + float: left; + margin-left: @fluidGridGutterWidth; + } + // Take these values and mixins, and make 'em do their thang + .generate(@gridColumns, @fluidGridColumnWidth, @fluidGridGutterWidth) { + // Row surrounds the columns + .row-fluid { + width: 100%; + .clearfix(); + + // Find all .span# classes within .row and give them the necessary properties for grid columns (supported by all browsers back to IE7, thanks @dhg) + > [class*="span"] { + #fluidGridSystem > .gridColumn(@fluidGridGutterWidth); + } + > [class*="span"]:first-child { + margin-left: 0; + } + // Default columns + > .span1 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 1); } + > .span2 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 2); } + > .span3 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 3); } + > .span4 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 4); } + > .span5 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 5); } + > .span6 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 6); } + > .span7 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 7); } + > .span8 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 8); } + > .span9 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 9); } + > .span10 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 10); } + > .span11 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 11); } + > .span12 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 12); } + } + } +} + +// Input grid system +// ------------------------- +#inputGridSystem { + .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, @columns) { + width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 10; + } + .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth) { + input, + textarea, + .uneditable-input { + &.span1 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 1); } + &.span2 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 2); } + &.span3 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 3); } + &.span4 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 4); } + &.span5 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 5); } + &.span6 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 6); } + &.span7 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 7); } + &.span8 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 8); } + &.span9 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 9); } + &.span10 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 10); } + &.span11 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 11); } + &.span12 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 12); } + } + } +} + +// Make a Grid +// ------------------------- +// Use .makeRow and .makeColumn to assign semantic layouts grid system behavior +.makeRow() { + margin-left: @gridGutterWidth * -1; + .clearfix(); +} +.makeColumn(@columns: 1) { + float: left; + margin-left: @gridGutterWidth; + width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)); +} + + + +// Form field states (used in forms.less) +// -------------------------------------------------- + +// Mixin for form field states +.formFieldState(@textColor: #555, @borderColor: #ccc, @backgroundColor: #f5f5f5) { + // Set the text color + > label, + .help-block, + .help-inline { + color: @textColor; + } + // Style inputs accordingly + input, + select, + textarea { + color: @textColor; + border-color: @borderColor; + &:focus { + border-color: darken(@borderColor, 10%); + .box-shadow(0 0 6px lighten(@borderColor, 20%)); + } + } + // Give a small background color for input-prepend/-append + .input-prepend .add-on, + .input-append .add-on { + color: @textColor; + background-color: @backgroundColor; + border-color: @textColor; + } +} + + + +// CSS3 PROPERTIES +// -------------------------------------------------- + +// Border Radius +.border-radius(@radius: 5px) { + -webkit-border-radius: @radius; + -moz-border-radius: @radius; + border-radius: @radius; +} + +// Drop shadows +.box-shadow(@shadow: 0 1px 3px rgba(0,0,0,.25)) { + -webkit-box-shadow: @shadow; + -moz-box-shadow: @shadow; + box-shadow: @shadow; +} + +// Transitions +.transition(@transition) { + -webkit-transition: @transition; + -moz-transition: @transition; + -ms-transition: @transition; + -o-transition: @transition; + transition: @transition; +} + +// Transformations +.rotate(@degrees) { + -webkit-transform: rotate(@degrees); + -moz-transform: rotate(@degrees); + -ms-transform: rotate(@degrees); + -o-transform: rotate(@degrees); + transform: rotate(@degrees); +} +.scale(@ratio) { + -webkit-transform: scale(@ratio); + -moz-transform: scale(@ratio); + -ms-transform: scale(@ratio); + -o-transform: scale(@ratio); + transform: scale(@ratio); +} +.translate(@x: 0, @y: 0) { + -webkit-transform: translate(@x, @y); + -moz-transform: translate(@x, @y); + -ms-transform: translate(@x, @y); + -o-transform: translate(@x, @y); + transform: translate(@x, @y); +} +.skew(@x: 0, @y: 0) { + -webkit-transform: skew(@x, @y); + -moz-transform: skew(@x, @y); + -ms-transform: skew(@x, @y); + -o-transform: skew(@x, @y); + transform: skew(@x, @y); +} +.translate3d(@x: 0, @y: 0, @z: 0) { + -webkit-transform: translate(@x, @y, @z); + -moz-transform: translate(@x, @y, @z); + -ms-transform: translate(@x, @y, @z); + -o-transform: translate(@x, @y, @z); + transform: translate(@x, @y, @z); +} + +// Background clipping +// Heads up: FF 3.6 and under need "padding" instead of "padding-box" +.background-clip(@clip) { + -webkit-background-clip: @clip; + -moz-background-clip: @clip; + background-clip: @clip; +} + +// Background sizing +.background-size(@size){ + -webkit-background-size: @size; + -moz-background-size: @size; + -o-background-size: @size; + background-size: @size; +} + + +// Box sizing +.box-sizing(@boxmodel) { + -webkit-box-sizing: @boxmodel; + -moz-box-sizing: @boxmodel; + box-sizing: @boxmodel; +} + +// User select +// For selecting text on the page +.user-select(@select) { + -webkit-user-select: @select; + -moz-user-select: @select; + -o-user-select: @select; + user-select: @select; +} + +// Resize anything +.resizable(@direction: both) { + resize: @direction; // Options: horizontal, vertical, both + overflow: auto; // Safari fix +} + +// CSS3 Content Columns +.content-columns(@columnCount, @columnGap: @gridColumnGutter) { + -webkit-column-count: @columnCount; + -moz-column-count: @columnCount; + column-count: @columnCount; + -webkit-column-gap: @columnGap; + -moz-column-gap: @columnGap; + column-gap: @columnGap; +} + +// Opacity +.opacity(@opacity: 100) { + opacity: @opacity / 100; + filter: e(%("alpha(opacity=%d)", @opacity)); +} + + + +// BACKGROUNDS +// -------------------------------------------------- + +// Add an alphatransparency value to any background or border color (via Elyse Holladay) +#translucent { + .background(@color: @white, @alpha: 1) { + background-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha); + } + .border(@color: @white, @alpha: 1) { + border-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha); + .background-clip(padding-box); + } +} + +// Gradient Bar Colors for buttons and alerts +.gradientBar(@primaryColor, @secondaryColor) { + #gradient > .vertical(@primaryColor, @secondaryColor); + border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%); + border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%); +} + +// Gradients +#gradient { + .horizontal(@startColor: #555, @endColor: #333) { + background-color: @endColor; + background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+ + background-image: -ms-linear-gradient(left, @startColor, @endColor); // IE10 + background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(left, @startColor, @endColor); // Le standard + background-repeat: repeat-x; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",@startColor,@endColor)); // IE9 and down + } + .vertical(@startColor: #555, @endColor: #333) { + background-color: mix(@startColor, @endColor, 60%); + background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+ + background-image: -ms-linear-gradient(top, @startColor, @endColor); // IE10 + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(top, @startColor, @endColor); // The standard + background-repeat: repeat-x; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down + } + .directional(@startColor: #555, @endColor: #333, @deg: 45deg) { + background-color: @endColor; + background-repeat: repeat-x; + background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+ + background-image: -ms-linear-gradient(@deg, @startColor, @endColor); // IE10 + background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(@deg, @startColor, @endColor); // The standard + } + .vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) { + background-color: mix(@midColor, @endColor, 80%); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor)); + background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor); + background-image: -ms-linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-repeat: no-repeat; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down, gets no color-stop at all for proper fallback + } + .radial(@innerColor: #555, @outerColor: #333) { + background-color: @outerColor; + background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor)); + background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor); + background-image: -moz-radial-gradient(circle, @innerColor, @outerColor); + background-image: -ms-radial-gradient(circle, @innerColor, @outerColor); + background-repeat: no-repeat; + // Opera cannot do radial gradients yet + } + .striped(@color, @angle: -45deg) { + background-color: @color; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + } +} +// Reset filters for IE +.reset-filter() { + filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)")); +} + + +// Mixin for generating button backgrounds +// --------------------------------------- +.buttonBackground(@startColor, @endColor) { + // gradientBar will set the background to a pleasing blend of these, to support IE<=9 + .gradientBar(@startColor, @endColor); + .reset-filter(); + + // in these cases the gradient won't cover the background, so we override + &:hover, &:active, &.active, &.disabled, &[disabled] { + background-color: @endColor; + } + + // IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves + &:active, + &.active { + background-color: darken(@endColor, 10%) e("\9"); + } +} + + +// COMPONENT MIXINS +// -------------------------------------------------- + +// POPOVER ARROWS +// ------------------------- +// For tipsies and popovers +#popoverArrow { + .top(@arrowWidth: 5px) { + bottom: 0; + left: 50%; + margin-left: -@arrowWidth; + border-left: @arrowWidth solid transparent; + border-right: @arrowWidth solid transparent; + border-top: @arrowWidth solid @black; + } + .left(@arrowWidth: 5px) { + top: 50%; + right: 0; + margin-top: -@arrowWidth; + border-top: @arrowWidth solid transparent; + border-bottom: @arrowWidth solid transparent; + border-left: @arrowWidth solid @black; + } + .bottom(@arrowWidth: 5px) { + top: 0; + left: 50%; + margin-left: -@arrowWidth; + border-left: @arrowWidth solid transparent; + border-right: @arrowWidth solid transparent; + border-bottom: @arrowWidth solid @black; + } + .right(@arrowWidth: 5px) { + top: 50%; + left: 0; + margin-top: -@arrowWidth; + border-top: @arrowWidth solid transparent; + border-bottom: @arrowWidth solid transparent; + border-right: @arrowWidth solid @black; + } +} diff --git a/less/bootstrap/modals.less b/less/bootstrap/modals.less new file mode 100644 index 0000000..d1e06dc --- /dev/null +++ b/less/bootstrap/modals.less @@ -0,0 +1,83 @@ +// MODALS +// ------ + +// Recalculate z-index where appropriate +.modal-open { + .dropdown-menu { z-index: @zindexDropdown + @zindexModal; } + .dropdown.open { *z-index: @zindexDropdown + @zindexModal; } + .popover { z-index: @zindexPopover + @zindexModal; } + .tooltip { z-index: @zindexTooltip + @zindexModal; } +} + +// Background +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: @zindexModalBackdrop; + background-color: @black; + // Fade for backdrop + &.fade { opacity: 0; } +} + +.modal-backdrop, +.modal-backdrop.fade.in { + .opacity(80); +} + +// Base modal +.modal { + position: fixed; + top: 50%; + left: 50%; + z-index: @zindexModal; + max-height: 500px; + overflow: auto; + width: 560px; + margin: -250px 0 0 -280px; + background-color: @white; + border: 1px solid #999; + border: 1px solid rgba(0,0,0,.3); + *border: 1px solid #999; /* IE6-7 */ + .border-radius(6px); + .box-shadow(0 3px 7px rgba(0,0,0,0.3)); + .background-clip(padding-box); + &.fade { + .transition(e('opacity .3s linear, top .3s ease-out')); + top: -25%; + } + &.fade.in { top: 50%; } +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; + // Close icon + .close { margin-top: 2px; } +} + +// Body (where all modal content resises) +.modal-body { + padding: 15px; +} +// Remove bottom margin if need be +.modal-body .modal-form { + margin-bottom: 0; +} + +// Footer (for actions) +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + .border-radius(0 0 6px 6px); + .box-shadow(inset 0 1px 0 @white); + .clearfix(); + .btn { + float: right; + margin-left: 5px; + margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs + } +} diff --git a/less/bootstrap/navbar.less b/less/bootstrap/navbar.less new file mode 100644 index 0000000..16553c1 --- /dev/null +++ b/less/bootstrap/navbar.less @@ -0,0 +1,299 @@ +// NAVBAR (FIXED AND STATIC) +// ------------------------- + + +// COMMON STYLES +// ------------- + +.navbar { + overflow: visible; + margin-bottom: @baseLineHeight; +} + +// Gradient is applied to it's own element because overflow visible is not honored by IE when filter is present +.navbar-inner { + padding-left: 20px; + padding-right: 20px; + #gradient > .vertical(@navbarBackgroundHighlight, @navbarBackground); + .border-radius(4px); + @shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1); + .box-shadow(@shadow); +} + +// Navbar button for toggling navbar items in responsive layouts +.btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + .buttonBackground(@navbarBackgroundHighlight, @navbarBackground); + @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075); + .box-shadow(@shadow); +} +.btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + .border-radius(1px); + .box-shadow(0 1px 0 rgba(0,0,0,.25)); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +// Override the default collapsed state +.nav-collapse.collapse { + height: auto; +} + + +// Brand, links, text, and buttons +.navbar { + // Hover and active states + .brand:hover { + text-decoration: none; + } + // Website or project name + .brand { + float: left; + display: block; + padding: 8px 20px 12px; + margin-left: -20px; // negative indent to left-align the text down the page + font-size: 20px; + font-weight: 200; + line-height: 1; + color: @white; + } + // Plain text in topbar + .navbar-text { + margin-bottom: 0; + line-height: 40px; + color: @navbarText; + a:hover { + color: @white; + background-color: transparent; + } + } + // Buttons in navbar + .btn, + .btn-group { + margin-top: 5px; // make buttons vertically centered in navbar + } + .btn-group .btn { + margin-top: 0; // then undo the margin here so we don't accidentally double it + } +} + +// Navbar forms +.navbar-form { + margin-bottom: 0; // remove default bottom margin + .clearfix(); + input, + select { + display: inline-block; + margin-top: 5px; + margin-bottom: 0; + } + .radio, + .checkbox { + margin-top: 5px; + } + input[type="image"], + input[type="checkbox"], + input[type="radio"] { + margin-top: 3px; + } + .input-append, + .input-prepend { + margin-top: 6px; + white-space: nowrap; // preven two items from separating within a .navbar-form that has .pull-left + input { + margin-top: 0; // remove the margin on top since it's on the parent + } + } +} + +// Navbar search +.navbar-search { + position: relative; + float: left; + margin-top: 6px; + margin-bottom: 0; + .search-query { + padding: 4px 9px; + #font > .sans-serif(13px, normal, 1); + color: @white; + color: rgba(255,255,255,.75); + background: #666; + background: rgba(255,255,255,.3); + border: 1px solid #111; + @shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0px rgba(255,255,255,.15); + .box-shadow(@shadow); + .transition(none); + + // Placeholder text gets special styles; can't be bundled together though for some reason + .placeholder(@grayLighter); + + // Hover states + &:hover { + color: @white; + background-color: @grayLight; + background-color: rgba(255,255,255,.5); + } + // Focus states (we use .focused since IE7-8 and down doesn't support :focus) + &:focus, + &.focused { + padding: 5px 10px; + color: @grayDark; + text-shadow: 0 1px 0 @white; + background-color: @white; + border: 0; + .box-shadow(0 0 3px rgba(0,0,0,.15)); + outline: 0; + } + } +} + + +// FIXED NAVBAR +// ------------ + +.navbar-fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: @zindexFixedNavbar; +} +.navbar-fixed-top .navbar-inner { + padding-left: 0; + padding-right: 0; + .border-radius(0); +} + + +// NAVIGATION +// ---------- + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; // redeclare due to specificity +} +.navbar .nav > li { + display: block; + float: left; +} + +// Links +.navbar .nav > li > a { + float: none; + padding: 10px 10px 11px; + line-height: 19px; + color: @navbarLinkColor; + text-decoration: none; + text-shadow: 0 -1px 0 rgba(0,0,0,.25); +} +// Hover +.navbar .nav > li > a:hover { + background-color: @navbarLinkBackgroundHover; // "transparent" is default to differentiate :hover from .active + color: @navbarLinkColorHover; + text-decoration: none; +} + +// Active nav items +.navbar .nav .active > a, +.navbar .nav .active > a:hover { + color: @navbarLinkColorHover; + text-decoration: none; + background-color: @navbarBackground; +} + +// Dividers (basically a vertical hr) +.navbar .divider-vertical { + height: @navbarHeight; + width: 1px; + margin: 0 9px; + overflow: hidden; + background-color: @navbarBackground; + border-right: 1px solid @navbarBackgroundHighlight; +} + +// Secondary (floated right) nav in topbar +.navbar .nav.pull-right { + margin-left: 10px; + margin-right: 0; +} + + + +// Dropdown menus +// -------------- + +// Menu position and menu carets +.navbar .dropdown-menu { + margin-top: 1px; + .border-radius(4px); + &:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0,0,0,.2); + position: absolute; + top: -7px; + left: 9px; + } + &:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid @white; + position: absolute; + top: -6px; + left: 10px; + } +} + +// Dropdown toggle caret +.navbar .nav .dropdown-toggle .caret, +.navbar .nav .open.dropdown .caret { + border-top-color: @white; +} +.navbar .nav .active .caret { + .opacity(100); +} + +// Remove background color from open dropdown +.navbar .nav .open > .dropdown-toggle, +.navbar .nav .active > .dropdown-toggle, +.navbar .nav .open.active > .dropdown-toggle { + background-color: transparent; +} + +// Dropdown link on hover +.navbar .nav .active > .dropdown-toggle:hover { + color: @white; +} + +// Right aligned menus need alt position +.navbar .nav.pull-right .dropdown-menu { + left: auto; + right: 0; + &:before { + left: auto; + right: 12px; + } + &:after { + left: auto; + right: 13px; + } +} \ No newline at end of file diff --git a/less/bootstrap/navs.less b/less/bootstrap/navs.less new file mode 100644 index 0000000..06219fa --- /dev/null +++ b/less/bootstrap/navs.less @@ -0,0 +1,353 @@ +// NAVIGATIONS +// ----------- + + + +// BASE CLASS +// ---------- + +.nav { + margin-left: 0; + margin-bottom: @baseLineHeight; + list-style: none; +} + +// Make links block level +.nav > li > a { + display: block; +} +.nav > li > a:hover { + text-decoration: none; + background-color: @grayLighter; +} + +// Nav headers (for dropdowns and lists) +.nav .nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: @baseLineHeight; + color: @grayLight; + text-shadow: 0 1px 0 rgba(255,255,255,.5); + text-transform: uppercase; +} +// Space them out when they follow another list item (link) +.nav li + .nav-header { + margin-top: 9px; +} + + +// NAV LIST +// -------- + +.nav-list { + padding-left: 14px; + padding-right: 14px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255,255,255,.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list .active > a, +.nav-list .active > a:hover { + color: @white; + text-shadow: 0 -1px 0 rgba(0,0,0,.2); + background-color: @linkColor; +} +.nav-list [class^="icon-"] { + margin-right: 2px; +} + + + +// TABS AND PILLS +// ------------- + +// Common styles +.nav-tabs, +.nav-pills { + .clearfix(); +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; // keeps the overall height an even number +} + +// TABS +// ---- + +// Give the tabs something to sit on +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +// Make the list-items overlay the bottom border +.nav-tabs > li { + margin-bottom: -1px; +} + +// Actual tabs (as links) +.nav-tabs > li > a { + padding-top: 9px; + padding-bottom: 9px; + border: 1px solid transparent; + .border-radius(4px 4px 0 0); + &:hover { + border-color: @grayLighter @grayLighter #ddd; + } +} +// Active state, and it's :hover to override normal :hover +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover { + color: @gray; + background-color: @white; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} + +// PILLS +// ----- + +// Links rendered as pills +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + .border-radius(5px); +} + +// Active state +.nav-pills .active > a, +.nav-pills .active > a:hover { + color: @white; + background-color: @linkColor; +} + + + +// STACKED NAV +// ----------- + +// Stacked tabs and pills +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; // no need for the gap between nav items +} + +// Tabs +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + .border-radius(0); +} +.nav-tabs.nav-stacked > li:first-child > a { + .border-radius(4px 4px 0 0); +} +.nav-tabs.nav-stacked > li:last-child > a { + .border-radius(0 0 4px 4px); +} +.nav-tabs.nav-stacked > li > a:hover { + border-color: #ddd; + z-index: 2; +} + +// Pills +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; // decrease margin to match sizing of stacked tabs +} + + + +// DROPDOWNS +// --------- + +// Position the menu +.nav-tabs .dropdown-menu, +.nav-pills .dropdown-menu { + margin-top: 1px; + border-width: 1px; +} +.nav-pills .dropdown-menu { + .border-radius(4px); +} + +// Default dropdown links +// ------------------------- +// Make carets use linkColor to start +.nav-tabs .dropdown-toggle .caret, +.nav-pills .dropdown-toggle .caret { + border-top-color: @linkColor; + margin-top: 6px; +} +.nav-tabs .dropdown-toggle:hover .caret, +.nav-pills .dropdown-toggle:hover .caret { + border-top-color: @linkColorHover; +} + +// Active dropdown links +// ------------------------- +.nav-tabs .active .dropdown-toggle .caret, +.nav-pills .active .dropdown-toggle .caret { + border-top-color: @grayDark; +} + +// Active:hover dropdown links +// ------------------------- +.nav > .dropdown.active > a:hover { + color: @black; + cursor: pointer; +} + +// Open dropdowns +// ------------------------- +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > .open.active > a:hover { + color: @white; + background-color: @grayLight; + border-color: @grayLight; +} +.nav .open .caret, +.nav .open.active .caret, +.nav .open a:hover .caret { + border-top-color: @white; + .opacity(100); +} + +// Dropdowns in stacked tabs +.tabs-stacked .open > a:hover { + border-color: @grayLight; +} + + + +// TABBABLE +// -------- + + +// COMMON STYLES +// ------------- + +// Clear any floats +.tabbable { + .clearfix(); +} +.tab-content { + overflow: hidden; // prevent content from running below tabs +} + +// Remove border on bottom, left, right +.tabs-below .nav-tabs, +.tabs-right .nav-tabs, +.tabs-left .nav-tabs { + border-bottom: 0; +} + +// Show/hide tabbable areas +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} + + +// BOTTOM +// ------ + +.tabs-below .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below .nav-tabs > li > a { + .border-radius(0 0 4px 4px); + &:hover { + border-bottom-color: transparent; + border-top-color: #ddd; + } +} +.tabs-below .nav-tabs .active > a, +.tabs-below .nav-tabs .active > a:hover { + border-color: transparent #ddd #ddd #ddd; +} + +// LEFT & RIGHT +// ------------ + +// Common styles +.tabs-left .nav-tabs > li, +.tabs-right .nav-tabs > li { + float: none; +} +.tabs-left .nav-tabs > li > a, +.tabs-right .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +// Tabs on the left +.tabs-left .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left .nav-tabs > li > a { + margin-right: -1px; + .border-radius(4px 0 0 4px); +} +.tabs-left .nav-tabs > li > a:hover { + border-color: @grayLighter #ddd @grayLighter @grayLighter; +} +.tabs-left .nav-tabs .active > a, +.tabs-left .nav-tabs .active > a:hover { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: @white; +} + +// Tabs on the right +.tabs-right .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right .nav-tabs > li > a { + margin-left: -1px; + .border-radius(0 4px 4px 0); +} +.tabs-right .nav-tabs > li > a:hover { + border-color: @grayLighter @grayLighter @grayLighter #ddd; +} +.tabs-right .nav-tabs .active > a, +.tabs-right .nav-tabs .active > a:hover { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: @white; +} diff --git a/less/bootstrap/pager.less b/less/bootstrap/pager.less new file mode 100644 index 0000000..104e41c --- /dev/null +++ b/less/bootstrap/pager.less @@ -0,0 +1,30 @@ +// PAGER +// ----- + +.pager { + margin-left: 0; + margin-bottom: @baseLineHeight; + list-style: none; + text-align: center; + .clearfix(); +} +.pager li { + display: inline; +} +.pager a { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + .border-radius(15px); +} +.pager a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next a { + float: right; +} +.pager .previous a { + float: left; +} diff --git a/less/bootstrap/pagination.less b/less/bootstrap/pagination.less new file mode 100644 index 0000000..de57807 --- /dev/null +++ b/less/bootstrap/pagination.less @@ -0,0 +1,55 @@ +// PAGINATION +// ---------- + +.pagination { + height: @baseLineHeight * 2; + margin: @baseLineHeight 0; + } +.pagination ul { + display: inline-block; + .ie7-inline-block(); + margin-left: 0; + margin-bottom: 0; + .border-radius(3px); + .box-shadow(0 1px 2px rgba(0,0,0,.05)); +} +.pagination li { + display: inline; + } +.pagination a { + float: left; + padding: 0 14px; + line-height: (@baseLineHeight * 2) - 2; + text-decoration: none; + border: 1px solid #ddd; + border-left-width: 0; +} +.pagination a:hover, +.pagination .active a { + background-color: #f5f5f5; +} +.pagination .active a { + color: @grayLight; + cursor: default; +} +.pagination .disabled a, +.pagination .disabled a:hover { + color: @grayLight; + background-color: transparent; + cursor: default; +} +.pagination li:first-child a { + border-left-width: 1px; + .border-radius(3px 0 0 3px); +} +.pagination li:last-child a { + .border-radius(0 3px 3px 0); +} + +// Centered +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} diff --git a/less/bootstrap/popovers.less b/less/bootstrap/popovers.less new file mode 100644 index 0000000..558d99e --- /dev/null +++ b/less/bootstrap/popovers.less @@ -0,0 +1,49 @@ +// POPOVERS +// -------- + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: @zindexPopover; + display: none; + padding: 5px; + &.top { margin-top: -5px; } + &.right { margin-left: 5px; } + &.bottom { margin-top: 5px; } + &.left { margin-left: -5px; } + &.top .arrow { #popoverArrow > .top(); } + &.right .arrow { #popoverArrow > .right(); } + &.bottom .arrow { #popoverArrow > .bottom(); } + &.left .arrow { #popoverArrow > .left(); } + .arrow { + position: absolute; + width: 0; + height: 0; + } +} +.popover-inner { + padding: 3px; + width: 280px; + overflow: hidden; + background: @black; // has to be full background declaration for IE fallback + background: rgba(0,0,0,.8); + .border-radius(6px); + .box-shadow(0 3px 7px rgba(0,0,0,0.3)); +} +.popover-title { + padding: 9px 15px; + line-height: 1; + background-color: #f5f5f5; + border-bottom:1px solid #eee; + .border-radius(3px 3px 0 0); +} +.popover-content { + padding: 14px; + background-color: @white; + .border-radius(0 0 3px 3px); + .background-clip(padding-box); + p, ul, ol { + margin-bottom: 0; + } +} diff --git a/less/bootstrap/progress-bars.less b/less/bootstrap/progress-bars.less new file mode 100644 index 0000000..c3144e1 --- /dev/null +++ b/less/bootstrap/progress-bars.less @@ -0,0 +1,95 @@ +// PROGRESS BARS +// ------------- + + +// ANIMATIONS +// ---------- + +// Webkit +@-webkit-keyframes progress-bar-stripes { + from { background-position: 0 0; } + to { background-position: 40px 0; } +} + +// Firefox +@-moz-keyframes progress-bar-stripes { + from { background-position: 0 0; } + to { background-position: 40px 0; } +} + +// Spec +@keyframes progress-bar-stripes { + from { background-position: 0 0; } + to { background-position: 40px 0; } +} + + + +// THE BARS +// -------- + +// Outer container +.progress { + overflow: hidden; + height: 18px; + margin-bottom: 18px; + #gradient > .vertical(#f5f5f5, #f9f9f9); + .box-shadow(inset 0 1px 2px rgba(0,0,0,.1)); + .border-radius(4px); +} + +// Bar of progress +.progress .bar { + width: 0%; + height: 18px; + color: @white; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0,0,0,.25); + #gradient > .vertical(#149bdf, #0480be); + .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15)); + .box-sizing(border-box); + .transition(width .6s ease); +} + +// Striped bars +.progress-striped .bar { + #gradient > .striped(#62c462); + .background-size(40px 40px); +} + +// Call animation for the active one +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + + + +// COLORS +// ------ + +// Danger (red) +.progress-danger .bar { + #gradient > .vertical(#ee5f5b, #c43c35); +} +.progress-danger.progress-striped .bar { + #gradient > .striped(#ee5f5b); +} + +// Success (green) +.progress-success .bar { + #gradient > .vertical(#62c462, #57a957); +} +.progress-success.progress-striped .bar { + #gradient > .striped(#62c462); +} + +// Info (teal) +.progress-info .bar { + #gradient > .vertical(#5bc0de, #339bb9); +} +.progress-info.progress-striped .bar { + #gradient > .striped(#5bc0de); +} diff --git a/less/bootstrap/reset.less b/less/bootstrap/reset.less new file mode 100644 index 0000000..1115f59 --- /dev/null +++ b/less/bootstrap/reset.less @@ -0,0 +1,126 @@ +// Reset.less +// Adapted from Normalize.css http://github.com/necolas/normalize.css +// ------------------------------------------------------------------------ + +// Display in IE6-9 and FF3 +// ------------------------- + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} + +// Display block in IE6-9 and FF3 +// ------------------------- + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +// Prevents modern browsers from displaying 'audio' without controls +// ------------------------- + +audio:not([controls]) { + display: none; +} + +// Base settings +// ------------------------- + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +// Focus states +a:focus { + .tab-focus(); +} +// Hover & Active +a:hover, +a:active { + outline: 0; +} + +// Prevents sub and sup affecting line-height in all browsers +// ------------------------- + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} + +// Img border in a's and image quality +// ------------------------- + +img { + max-width: 100%; + height: auto; + border: 0; + -ms-interpolation-mode: bicubic; +} + +// Forms +// ------------------------- + +// Font size in all browsers, margin changes, misc consistency +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; // Inner spacing ie IE6/7 + line-height: normal; // FF3/4 have !important on line-height in UA stylesheet +} +button::-moz-focus-inner, +input::-moz-focus-inner { // Inner padding and border oddities in FF3/4 + padding: 0; + border: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; // Cursors on all buttons applied consistently + -webkit-appearance: button; // Style clickable inputs in iOS +} +input[type="search"] { // Appearance in Safari/Chrome + -webkit-appearance: textfield; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5 +} +textarea { + overflow: auto; // Remove vertical scrollbar in IE6-9 + vertical-align: top; // Readability and alignment cross-browser +} diff --git a/less/bootstrap/responsive.less b/less/bootstrap/responsive.less new file mode 100644 index 0000000..1547dce --- /dev/null +++ b/less/bootstrap/responsive.less @@ -0,0 +1,327 @@ +/*! + * Bootstrap Responsive v2.0.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +// Responsive.less +// For phone and tablet devices +// ------------------------------------------------------------- + + +// REPEAT VARIABLES & MIXINS +// ------------------------- +// Required since we compile the responsive stuff separately + +@import "variables.less"; // Modify this for custom colors, font-sizes, etc +@import "mixins.less"; + + +// RESPONSIVE CLASSES +// ------------------ + +// Hide from screenreaders and browsers +// Credit: HTML5 Boilerplate +.hidden { + display: none; + visibility: hidden; +} + + + +// UP TO LANDSCAPE PHONE +// --------------------- + +@media (max-width: 480px) { + + // Smooth out the collapsing/expanding nav + .nav-collapse { + -webkit-transform: translate3d(0, 0, 0); // activate the GPU + } + + // Block level the page header small tag for readability + .page-header h1 small { + display: block; + line-height: @baseLineHeight; + } + + // Make span* classes full width + input[class*="span"], + select[class*="span"], + textarea[class*="span"], + .uneditable-input { + display: block; + width: 100%; + min-height: 28px; /* Make inputs at least the height of their button counterpart */ + /* Makes inputs behave like true block-level elements */ + -webkit-box-sizing: border-box; /* Older Webkit */ + -moz-box-sizing: border-box; /* Older FF */ + -ms-box-sizing: border-box; /* IE8 */ + box-sizing: border-box; /* CSS3 spec*/ + } + // But don't let it screw up prepend/append inputs + .input-prepend input[class*="span"], + .input-append input[class*="span"] { + width: auto; + } + + // Update checkboxes for iOS + input[type="checkbox"], + input[type="radio"] { + border: 1px solid #ccc; + } + + // Remove the horizontal form styles + .form-horizontal .control-group > label { + float: none; + width: auto; + padding-top: 0; + text-align: left; + } + // Move over all input controls and content + .form-horizontal .controls { + margin-left: 0; + } + // Move the options list down to align with labels + .form-horizontal .control-list { + padding-top: 0; // has to be padding because margin collaspes + } + // Move over buttons in .form-actions to align with .controls + .form-horizontal .form-actions { + padding-left: 10px; + padding-right: 10px; + } + + // Modals + .modal { + position: absolute; + top: 10px; + left: 10px; + right: 10px; + width: auto; + margin: 0; + &.fade.in { top: auto; } + } + .modal-header .close { + padding: 10px; + margin: -10px; + } + + // Carousel + .carousel-caption { + position: static; + } + +} + + + +// LANDSCAPE PHONE TO SMALL DESKTOP & PORTRAIT TABLET +// -------------------------------------------------- + +@media (max-width: 767px) { + // GRID & CONTAINERS + // ----------------- + // Remove width from containers + .container { + width: auto; + padding: 0 20px; + } + // Fluid rows + .row-fluid { + width: 100%; + } + // Undo negative margin on rows + .row { + margin-left: 0; + } + // Make all columns even + .row > [class*="span"], + .row-fluid > [class*="span"] { + float: none; + display: block; + width: auto; + margin: 0; + } +} + + + +// PORTRAIT TABLET TO DEFAULT DESKTOP +// ---------------------------------- + +@media (min-width: 768px) and (max-width: 979px) { + + // Fixed grid + #gridSystem > .generate(12, 42px, 20px); + + // Fluid grid + #fluidGridSystem > .generate(12, 5.801104972%, 2.762430939%); + + // Input grid + #inputGridSystem > .generate(12, 42px, 20px); + +} + + + +// TABLETS AND BELOW +// ----------------- +@media (max-width: 979px) { + + // UNFIX THE TOPBAR + // ---------------- + // Remove any padding from the body + body { + padding-top: 0; + } + // Unfix the navbar + .navbar-fixed-top { + position: static; + margin-bottom: @baseLineHeight; + } + .navbar-fixed-top .navbar-inner { + padding: 5px; + } + .navbar .container { + width: auto; + padding: 0; + } + // Account for brand name + .navbar .brand { + padding-left: 10px; + padding-right: 10px; + margin: 0 0 0 -5px; + } + // Nav collapse clears brand + .navbar .nav-collapse { + clear: left; + } + // Block-level the nav + .navbar .nav { + float: none; + margin: 0 0 (@baseLineHeight / 2); + } + .navbar .nav > li { + float: none; + } + .navbar .nav > li > a { + margin-bottom: 2px; + } + .navbar .nav > .divider-vertical { + display: none; + } + .navbar .nav .nav-header { + color: @navbarText; + text-shadow: none; + } + // Nav and dropdown links in navbar + .navbar .nav > li > a, + .navbar .dropdown-menu a { + padding: 6px 15px; + font-weight: bold; + color: @navbarLinkColor; + .border-radius(3px); + } + .navbar .dropdown-menu li + li a { + margin-bottom: 2px; + } + .navbar .nav > li > a:hover, + .navbar .dropdown-menu a:hover { + background-color: @navbarBackground; + } + // Dropdowns in the navbar + .navbar .dropdown-menu { + position: static; + top: auto; + left: auto; + float: none; + display: block; + max-width: none; + margin: 0 15px; + padding: 0; + background-color: transparent; + border: none; + .border-radius(0); + .box-shadow(none); + } + .navbar .dropdown-menu:before, + .navbar .dropdown-menu:after { + display: none; + } + .navbar .dropdown-menu .divider { + display: none; + } + // Forms in navbar + .navbar-form, + .navbar-search { + float: none; + padding: (@baseLineHeight / 2) 15px; + margin: (@baseLineHeight / 2) 0; + border-top: 1px solid @navbarBackground; + border-bottom: 1px solid @navbarBackground; + @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); + .box-shadow(@shadow); + } + // Pull right (secondary) nav content + .navbar .nav.pull-right { + float: none; + margin-left: 0; + } + // Static navbar + .navbar-static .navbar-inner { + padding-left: 10px; + padding-right: 10px; + } + // Navbar button + .btn-navbar { + display: block; + } + + // Hide everything in the navbar save .brand and toggle button */ + .nav-collapse { + overflow: hidden; + height: 0; + } +} + + + +// DEFAULT DESKTOP +// --------------- + +@media (min-width: 980px) { + .nav-collapse.collapse { + height: auto !important; + } +} + + + +// LARGE DESKTOP & UP +// ------------------ + +@media (min-width: 1200px) { + + // Fixed grid + #gridSystem > .generate(12, 70px, 30px); + + // Fluid grid + #fluidGridSystem > .generate(12, 5.982905983%, 2.564102564%); + + // Input grid + #inputGridSystem > .generate(12, 70px, 30px); + + // Thumbnails + .thumbnails { + margin-left: -30px; + } + .thumbnails > li { + margin-left: 30px; + } + +} diff --git a/less/bootstrap/scaffolding.less b/less/bootstrap/scaffolding.less new file mode 100644 index 0000000..47ce538 --- /dev/null +++ b/less/bootstrap/scaffolding.less @@ -0,0 +1,29 @@ +// Scaffolding +// Basic and global styles for generating a grid system, structural layout, and page templates +// ------------------------------------------------------------------------------------------- + + +// STRUCTURAL LAYOUT +// ----------------- + +body { + margin: 0; + font-family: @baseFontFamily; + font-size: @baseFontSize; + line-height: @baseLineHeight; + color: @textColor; + background-color: @white; +} + + +// LINKS +// ----- + +a { + color: @linkColor; + text-decoration: none; +} +a:hover { + color: @linkColorHover; + text-decoration: underline; +} diff --git a/less/bootstrap/sprites.less b/less/bootstrap/sprites.less new file mode 100644 index 0000000..a774166 --- /dev/null +++ b/less/bootstrap/sprites.less @@ -0,0 +1,158 @@ +// SPRITES +// Glyphs and icons for buttons, nav, and more +// ------------------------------------------- + + +// ICONS +// ----- + +// All icons receive the styles of the tag with a base class +// of .i and are then given a unique class to add width, height, +// and background-position. Your resulting HTML will look like +// . + +// For the white version of the icons, just add the .icon-white class: +// + +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + line-height: 14px; + vertical-align: text-top; + background-image: url(@iconSpritePath); + background-position: 14px 14px; + background-repeat: no-repeat; + + .ie7-restore-right-whitespace(); +} +.icon-white { + background-image: url(@iconWhiteSpritePath); +} + +.icon-glass { background-position: 0 0; } +.icon-music { background-position: -24px 0; } +.icon-search { background-position: -48px 0; } +.icon-envelope { background-position: -72px 0; } +.icon-heart { background-position: -96px 0; } +.icon-star { background-position: -120px 0; } +.icon-star-empty { background-position: -144px 0; } +.icon-user { background-position: -168px 0; } +.icon-film { background-position: -192px 0; } +.icon-th-large { background-position: -216px 0; } +.icon-th { background-position: -240px 0; } +.icon-th-list { background-position: -264px 0; } +.icon-ok { background-position: -288px 0; } +.icon-remove { background-position: -312px 0; } +.icon-zoom-in { background-position: -336px 0; } +.icon-zoom-out { background-position: -360px 0; } +.icon-off { background-position: -384px 0; } +.icon-signal { background-position: -408px 0; } +.icon-cog { background-position: -432px 0; } +.icon-trash { background-position: -456px 0; } + +.icon-home { background-position: 0 -24px; } +.icon-file { background-position: -24px -24px; } +.icon-time { background-position: -48px -24px; } +.icon-road { background-position: -72px -24px; } +.icon-download-alt { background-position: -96px -24px; } +.icon-download { background-position: -120px -24px; } +.icon-upload { background-position: -144px -24px; } +.icon-inbox { background-position: -168px -24px; } +.icon-play-circle { background-position: -192px -24px; } +.icon-repeat { background-position: -216px -24px; } +.icon-refresh { background-position: -240px -24px; } +.icon-list-alt { background-position: -264px -24px; } +.icon-lock { background-position: -287px -24px; } // 1px off +.icon-flag { background-position: -312px -24px; } +.icon-headphones { background-position: -336px -24px; } +.icon-volume-off { background-position: -360px -24px; } +.icon-volume-down { background-position: -384px -24px; } +.icon-volume-up { background-position: -408px -24px; } +.icon-qrcode { background-position: -432px -24px; } +.icon-barcode { background-position: -456px -24px; } + +.icon-tag { background-position: 0 -48px; } +.icon-tags { background-position: -25px -48px; } // 1px off +.icon-book { background-position: -48px -48px; } +.icon-bookmark { background-position: -72px -48px; } +.icon-print { background-position: -96px -48px; } +.icon-camera { background-position: -120px -48px; } +.icon-font { background-position: -144px -48px; } +.icon-bold { background-position: -167px -48px; } // 1px off +.icon-italic { background-position: -192px -48px; } +.icon-text-height { background-position: -216px -48px; } +.icon-text-width { background-position: -240px -48px; } +.icon-align-left { background-position: -264px -48px; } +.icon-align-center { background-position: -288px -48px; } +.icon-align-right { background-position: -312px -48px; } +.icon-align-justify { background-position: -336px -48px; } +.icon-list { background-position: -360px -48px; } +.icon-indent-left { background-position: -384px -48px; } +.icon-indent-right { background-position: -408px -48px; } +.icon-facetime-video { background-position: -432px -48px; } +.icon-picture { background-position: -456px -48px; } + +.icon-pencil { background-position: 0 -72px; } +.icon-map-marker { background-position: -24px -72px; } +.icon-adjust { background-position: -48px -72px; } +.icon-tint { background-position: -72px -72px; } +.icon-edit { background-position: -96px -72px; } +.icon-share { background-position: -120px -72px; } +.icon-check { background-position: -144px -72px; } +.icon-move { background-position: -168px -72px; } +.icon-step-backward { background-position: -192px -72px; } +.icon-fast-backward { background-position: -216px -72px; } +.icon-backward { background-position: -240px -72px; } +.icon-play { background-position: -264px -72px; } +.icon-pause { background-position: -288px -72px; } +.icon-stop { background-position: -312px -72px; } +.icon-forward { background-position: -336px -72px; } +.icon-fast-forward { background-position: -360px -72px; } +.icon-step-forward { background-position: -384px -72px; } +.icon-eject { background-position: -408px -72px; } +.icon-chevron-left { background-position: -432px -72px; } +.icon-chevron-right { background-position: -456px -72px; } + +.icon-plus-sign { background-position: 0 -96px; } +.icon-minus-sign { background-position: -24px -96px; } +.icon-remove-sign { background-position: -48px -96px; } +.icon-ok-sign { background-position: -72px -96px; } +.icon-question-sign { background-position: -96px -96px; } +.icon-info-sign { background-position: -120px -96px; } +.icon-screenshot { background-position: -144px -96px; } +.icon-remove-circle { background-position: -168px -96px; } +.icon-ok-circle { background-position: -192px -96px; } +.icon-ban-circle { background-position: -216px -96px; } +.icon-arrow-left { background-position: -240px -96px; } +.icon-arrow-right { background-position: -264px -96px; } +.icon-arrow-up { background-position: -289px -96px; } // 1px off +.icon-arrow-down { background-position: -312px -96px; } +.icon-share-alt { background-position: -336px -96px; } +.icon-resize-full { background-position: -360px -96px; } +.icon-resize-small { background-position: -384px -96px; } +.icon-plus { background-position: -408px -96px; } +.icon-minus { background-position: -433px -96px; } +.icon-asterisk { background-position: -456px -96px; } + +.icon-exclamation-sign { background-position: 0 -120px; } +.icon-gift { background-position: -24px -120px; } +.icon-leaf { background-position: -48px -120px; } +.icon-fire { background-position: -72px -120px; } +.icon-eye-open { background-position: -96px -120px; } +.icon-eye-close { background-position: -120px -120px; } +.icon-warning-sign { background-position: -144px -120px; } +.icon-plane { background-position: -168px -120px; } +.icon-calendar { background-position: -192px -120px; } +.icon-random { background-position: -216px -120px; } +.icon-comment { background-position: -240px -120px; } +.icon-magnet { background-position: -264px -120px; } +.icon-chevron-up { background-position: -288px -120px; } +.icon-chevron-down { background-position: -313px -119px; } // 1px off +.icon-retweet { background-position: -336px -120px; } +.icon-shopping-cart { background-position: -360px -120px; } +.icon-folder-close { background-position: -384px -120px; } +.icon-folder-open { background-position: -408px -120px; } +.icon-resize-vertical { background-position: -432px -119px; } +.icon-resize-horizontal { background-position: -456px -118px; } diff --git a/less/bootstrap/tables.less b/less/bootstrap/tables.less new file mode 100644 index 0000000..3a4066d --- /dev/null +++ b/less/bootstrap/tables.less @@ -0,0 +1,150 @@ +// +// Tables.less +// Tables for, you guessed it, tabular data +// ---------------------------------------- + + +// BASE TABLES +// ----------------- + +table { + max-width: 100%; + border-collapse: collapse; + border-spacing: 0; +} + +// BASELINE STYLES +// --------------- + +.table { + width: 100%; + margin-bottom: @baseLineHeight; + // Cells + th, + td { + padding: 8px; + line-height: @baseLineHeight; + text-align: left; + vertical-align: top; + border-top: 1px solid #ddd; + } + th { + font-weight: bold; + } + // Bottom align for column headings + thead th { + vertical-align: bottom; + } + // Remove top border from thead by default + thead:first-child tr th, + thead:first-child tr td { + border-top: 0; + } + // Account for multiple tbody instances + tbody + tbody { + border-top: 2px solid #ddd; + } +} + + + +// CONDENSED TABLE W/ HALF PADDING +// ------------------------------- + +.table-condensed { + th, + td { + padding: 4px 5px; + } +} + + +// BORDERED VERSION +// ---------------- + +.table-bordered { + border: 1px solid #ddd; + border-collapse: separate; // Done so we can round those corners! + *border-collapse: collapsed; // IE7 can't round corners anyway + .border-radius(4px); + th + th, + td + td, + th + td, + td + th { + border-left: 1px solid #ddd; + } + // Prevent a double border + thead:first-child tr:first-child th, + tbody:first-child tr:first-child th, + tbody:first-child tr:first-child td { + border-top: 0; + } + // For first th or td in the first row in the first thead or tbody + thead:first-child tr:first-child th:first-child, + tbody:first-child tr:first-child td:first-child { + .border-radius(4px 0 0 0); + } + thead:first-child tr:first-child th:last-child, + tbody:first-child tr:first-child td:last-child { + .border-radius(0 4px 0 0); + } + // For first th or td in the first row in the first thead or tbody + thead:last-child tr:last-child th:first-child, + tbody:last-child tr:last-child td:first-child { + .border-radius(0 0 0 4px); + } + thead:last-child tr:last-child th:last-child, + tbody:last-child tr:last-child td:last-child { + .border-radius(0 0 4px 0); + } +} + + +// ZEBRA-STRIPING +// -------------- + +// Default zebra-stripe styles (alternating gray and transparent backgrounds) +.table-striped { + tbody { + tr:nth-child(odd) td, + tr:nth-child(odd) th { + background-color: #f9f9f9; + } + } +} + + +// HOVER EFFECT +// ------------ +// Placed here since it has to come after the potential zebra striping +.table { + tbody tr:hover td, + tbody tr:hover th { + background-color: #f5f5f5; + } +} + + +// TABLE CELL SIZING +// ----------------- + +// Change the columns +.tableColumns(@columnSpan: 1) { + float: none; + width: ((@gridColumnWidth) * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1)) - 16; + margin-left: 0; +} +table { + .span1 { .tableColumns(1); } + .span2 { .tableColumns(2); } + .span3 { .tableColumns(3); } + .span4 { .tableColumns(4); } + .span5 { .tableColumns(5); } + .span6 { .tableColumns(6); } + .span7 { .tableColumns(7); } + .span8 { .tableColumns(8); } + .span9 { .tableColumns(9); } + .span10 { .tableColumns(10); } + .span11 { .tableColumns(11); } + .span12 { .tableColumns(12); } +} diff --git a/less/bootstrap/thumbnails.less b/less/bootstrap/thumbnails.less new file mode 100644 index 0000000..3a12d4e --- /dev/null +++ b/less/bootstrap/thumbnails.less @@ -0,0 +1,35 @@ +// THUMBNAILS +// ---------- + +.thumbnails { + margin-left: -@gridGutterWidth; + list-style: none; + .clearfix(); +} +.thumbnails > li { + float: left; + margin: 0 0 @baseLineHeight @gridGutterWidth; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 1; + border: 1px solid #ddd; + .border-radius(4px); + .box-shadow(0 1px 1px rgba(0,0,0,.075)); +} +// Add a hover state for linked versions only +a.thumbnail:hover { + border-color: @linkColor; + .box-shadow(0 1px 4px rgba(0,105,214,.25)); +} +// Images and captions +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; +} diff --git a/less/bootstrap/tooltip.less b/less/bootstrap/tooltip.less new file mode 100644 index 0000000..5111a19 --- /dev/null +++ b/less/bootstrap/tooltip.less @@ -0,0 +1,35 @@ +// TOOLTIP +// ------= + +.tooltip { + position: absolute; + z-index: @zindexTooltip; + display: block; + visibility: visible; + padding: 5px; + font-size: 11px; + .opacity(0); + &.in { .opacity(80); } + &.top { margin-top: -2px; } + &.right { margin-left: 2px; } + &.bottom { margin-top: 2px; } + &.left { margin-left: -2px; } + &.top .tooltip-arrow { #popoverArrow > .top(); } + &.left .tooltip-arrow { #popoverArrow > .left(); } + &.bottom .tooltip-arrow { #popoverArrow > .bottom(); } + &.right .tooltip-arrow { #popoverArrow > .right(); } +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: @white; + text-align: center; + text-decoration: none; + background-color: @black; + .border-radius(4px); +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; +} diff --git a/less/bootstrap/type.less b/less/bootstrap/type.less new file mode 100644 index 0000000..6ba83bc --- /dev/null +++ b/less/bootstrap/type.less @@ -0,0 +1,218 @@ +// Typography.less +// Headings, body text, lists, code, and more for a versatile and durable typography system +// ---------------------------------------------------------------------------------------- + + +// BODY TEXT +// --------- + +p { + margin: 0 0 @baseLineHeight / 2; + font-family: @baseFontFamily; + font-size: @baseFontSize; + line-height: @baseLineHeight; + small { + font-size: @baseFontSize - 2; + color: @grayLight; + } +} +.lead { + margin-bottom: @baseLineHeight; + font-size: 20px; + font-weight: 200; + line-height: @baseLineHeight * 1.5; +} + +// HEADINGS +// -------- + +h1, h2, h3, h4, h5, h6 { + margin: 0; + font-weight: bold; + color: @grayDark; + text-rendering: optimizelegibility; // Fix the character spacing for headings + small { + font-weight: normal; + color: @grayLight; + } +} +h1 { + font-size: 30px; + line-height: @baseLineHeight * 2; + small { + font-size: 18px; + } +} +h2 { + font-size: 24px; + line-height: @baseLineHeight * 2; + small { + font-size: 18px; + } +} +h3 { + line-height: @baseLineHeight * 1.5; + font-size: 18px; + small { + font-size: 14px; + } +} +h4, h5, h6 { + line-height: @baseLineHeight; +} +h4 { + font-size: 14px; + small { + font-size: 12px; + } +} +h5 { + font-size: 12px; +} +h6 { + font-size: 11px; + color: @grayLight; + text-transform: uppercase; +} + +// Page header +.page-header { + padding-bottom: @baseLineHeight - 1; + margin: @baseLineHeight 0; + border-bottom: 1px solid @grayLighter; +} +.page-header h1 { + line-height: 1; +} + + + +// LISTS +// ----- + +// Unordered and Ordered lists +ul, ol { + padding: 0; + margin: 0 0 @baseLineHeight / 2 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: @baseLineHeight; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} + +// Description Lists +dl { + margin-bottom: @baseLineHeight; +} +dt, +dd { + line-height: @baseLineHeight; +} +dt { + font-weight: bold; +} +dd { + margin-left: @baseLineHeight / 2; +} + +// MISC +// ---- + +// Horizontal rules +hr { + margin: @baseLineHeight 0; + border: 0; + border-top: 1px solid @hrBorder; + border-bottom: 1px solid @white; +} + +// Emphasis +strong { + font-weight: bold; +} +em { + font-style: italic; +} +.muted { + color: @grayLight; +} + +// Abbreviations and acronyms +abbr { + font-size: 90%; + text-transform: uppercase; + border-bottom: 1px dotted #ddd; + cursor: help; +} + +// Blockquotes +blockquote { + padding: 0 0 0 15px; + margin: 0 0 @baseLineHeight; + border-left: 5px solid @grayLighter; + p { + margin-bottom: 0; + #font > .shorthand(16px,300,@baseLineHeight * 1.25); + } + small { + display: block; + line-height: @baseLineHeight; + color: @grayLight; + &:before { + content: '\2014 \00A0'; + } + } + + // Float right with text-align: right + &.pull-right { + float: right; + padding-left: 0; + padding-right: 15px; + border-left: 0; + border-right: 5px solid @grayLighter; + p, + small { + text-align: right; + } + } +} + +// Quotes +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +// Addresses +address { + display: block; + margin-bottom: @baseLineHeight; + line-height: @baseLineHeight; + font-style: normal; +} + +// Misc +small { + font-size: 100%; +} +cite { + font-style: normal; +} diff --git a/less/bootstrap/utilities.less b/less/bootstrap/utilities.less new file mode 100644 index 0000000..d60d220 --- /dev/null +++ b/less/bootstrap/utilities.less @@ -0,0 +1,23 @@ +// UTILITY CLASSES +// --------------- + +// Quick floats +.pull-right { + float: right; +} +.pull-left { + float: left; +} + +// Toggling content +.hide { + display: none; +} +.show { + display: block; +} + +// Visibility +.invisible { + visibility: hidden; +} diff --git a/less/bootstrap/variables.less b/less/bootstrap/variables.less new file mode 100644 index 0000000..d03daa6 --- /dev/null +++ b/less/bootstrap/variables.less @@ -0,0 +1,107 @@ +// Variables.less +// Variables to customize the look and feel of Bootstrap +// ----------------------------------------------------- + + + +// GLOBAL VALUES +// -------------------------------------------------- + +// Links +@linkColor: #08c; +@linkColorHover: darken(@linkColor, 15%); + +// Grays +@black: #000; +@grayDarker: #222; +@grayDark: #333; +@gray: #555; +@grayLight: #999; +@grayLighter: #eee; +@white: #fff; + +// Accent colors +@blue: #049cdb; +@blueDark: #0064cd; +@green: #46a546; +@red: #9d261d; +@yellow: #ffc40d; +@orange: #f89406; +@pink: #c3325f; +@purple: #7a43b6; + +// Typography +@baseFontSize: 13px; +@baseFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; +@baseLineHeight: 18px; +@textColor: @grayDark; + +// Buttons +@primaryButtonBackground: @linkColor; + + + +// COMPONENT VARIABLES +// -------------------------------------------------- + +// Z-index master list +// Used for a bird's eye view of components dependent on the z-axis +// Try to avoid customizing these :) +@zindexDropdown: 1000; +@zindexPopover: 1010; +@zindexTooltip: 1020; +@zindexFixedNavbar: 1030; +@zindexModalBackdrop: 1040; +@zindexModal: 1050; + +// Sprite icons path +@iconSpritePath: "/static/img/glyphicons-halflings.png"; +@iconWhiteSpritePath: "/static/img/glyphicons-halflings-white.png"; + +// Input placeholder text color +@placeholderText: @grayLight; + +// Hr border color +@hrBorder: @grayLighter; + +// Navbar +@navbarHeight: 40px; +@navbarBackground: @grayDarker; +@navbarBackgroundHighlight: @grayDark; +@navbarLinkBackgroundHover: transparent; + +@navbarText: @grayLight; +@navbarLinkColor: @grayLight; +@navbarLinkColorHover: @white; + +// Form states and alerts +@warningText: #c09853; +@warningBackground: #fcf8e3; +@warningBorder: darken(spin(@warningBackground, -10), 3%); + +@errorText: #b94a48; +@errorBackground: #f2dede; +@errorBorder: darken(spin(@errorBackground, -10), 3%); + +@successText: #468847; +@successBackground: #dff0d8; +@successBorder: darken(spin(@successBackground, -10), 5%); + +@infoText: #3a87ad; +@infoBackground: #d9edf7; +@infoBorder: darken(spin(@infoBackground, -10), 7%); + + + +// GRID +// -------------------------------------------------- + +// Default 940px grid +@gridColumns: 12; +@gridColumnWidth: 60px; +@gridGutterWidth: 20px; +@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); + +// Fluid grid +@fluidGridColumnWidth: 6.382978723%; +@fluidGridGutterWidth: 2.127659574%; diff --git a/less/bootstrap/wells.less b/less/bootstrap/wells.less new file mode 100644 index 0000000..244b8ca --- /dev/null +++ b/less/bootstrap/wells.less @@ -0,0 +1,17 @@ +// WELLS +// ----- + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #eee; + border: 1px solid rgba(0,0,0,.05); + .border-radius(4px); + .box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); + blockquote { + border-color: #ddd; + border-color: rgba(0,0,0,.15); + } +} diff --git a/less/style.less b/less/style.less new file mode 100644 index 0000000..1cbd9f9 --- /dev/null +++ b/less/style.less @@ -0,0 +1,124 @@ + +@import "vars.less"; +@import "bootstrap/bootstrap.less"; + +/* Signin & Signup Page Style */ + +body { + background: url(@bg-noise); +} + +.sign { + margin: 0; + #wrapper { + width: @signWidth; + margin-top: @signYOffset; + .center-block(); + #logo { + margin-bottom: 20px; + padding-left: 40px; + width: @signInnerWidth; + .logo { + font-size: 50px; + font-family: 'Port Lligat Slab', serif; + } + .subtitle { + position: relative; + left: 80px; + top: -5px; + font-size: 10px; + } + } + .signform { + width: @signInnerWidth; + .input-prepend { + input, .btn { + float: left; + } + } + .add-on, input { + height: 28px; + line-height: 28px; + } + .btn { + width: 246px; + height: 34px; + } + a.btn { + width: 226px; + height: 26px; + line-height: 26px; + } + } + } +} + +/* Common Page Style */ + +body { + margin-left: @sidebarWidth + 20; + margin-bottom: @bottomBlank; +} + +nav { + color: white; + background: #2B2B2B; + background-image: url(@bg-sidebar); + width: @sidebarWidth; + height: 100%; + position: fixed; + top: 0; + left: 0; + overflow: hidden; + z-index: 5; + border-right: solid 1px black; + + .profile { + height: 76px; + border-bottom: 1px solid @sidebarLineBottomColor; + + .profile_wrap { + height: 75px; + border-bottom: 1px solid @sidebarLineTopColor; + + .username { + position: absolute; + top: 20px; + left: 70px; + font-family: Arial, sans-serif; + font-size: 14px; + text-shadow: black 0px 1px 1px; + } + + .avatar { + .border-radius(4px); + .box-shadow(0px 1px 0px rgba(255, 255, 255, 0.2)); + .square(45px); + border: 1px solid black; + position: absolute; + top: 15px; + left: 14px; + cursor: pointer; + overflow: hidden; + + img { + .border-radius(4px); + .square(45px); + } + .avatar_mask { + .border-radius(4px); + .box-shadow(inset 0px 0px 9px #000000); + .opacity(50); + .square(45px); + position: absolute; + top: 0; + left: 0; + } + } + } + } + + .nav { + margin-top: 20px; + } +} diff --git a/member.py b/member.py new file mode 100644 index 0000000..bfa2f90 --- /dev/null +++ b/member.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: member.py +# CREATED: 02:18:23 09/03/2012 +# MODIFIED: 03:10:44 09/03/2012 +# DESCRIPTION: member handlers + +import re + +from judge.db import MemberDBMixin +from judge.base import BaseHandler +from judge.base import unauthenticated + +class SigninHandler(BaseHandler, MemberDBMixin): + @unauthenticated + def get(self): + self.render("signin.html", locals()) + +class SignupHandler(BaseHandler, MemberDBMixin): + @unauthenticated + def get(self): + self.render("signup.html", locals()) + +__all__ = ["SigninHandler", "SignupHandler"] diff --git a/signup.html b/signup.html new file mode 100644 index 0000000..099c488 --- /dev/null +++ b/signup.html @@ -0,0 +1,55 @@ + + + + + + {{ page.settings['site_title'] }} + + + + + + + +
      + +
      +{% if error %} +
      + × +
        + {% for err in error %} +
      • {{ err }}
      • + {% endfor %} +
      +
      +{% endif %} +
      +{{ page.xsrf_form_html() }} +
      + + +
      +
      + + +
      +
      + + +
      +
      + +
      + +
      +
      + +
      + + diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..028b38d --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,3811 @@ +/* Background Images */ +/* Common Const Var */ +/* Wrapper Const Var */ +/* Sidebar Const Var */ +/*! + * Bootstrap v2.0.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + max-width: 100%; + height: auto; + border: 0; + -ms-interpolation-mode: bicubic; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} +input[type="search"] { + -webkit-appearance: textfield; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; +} +.clearfix:after { + clear: both; +} +body { + margin: 0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + line-height: 18px; + color: #333333; + background-color: #ffffff; +} +a { + color: #0088cc; + text-decoration: none; +} +a:hover { + color: #005580; + text-decoration: underline; +} +.row { + margin-left: -20px; + *zoom: 1; +} +.row:before, +.row:after { + display: table; + content: ""; +} +.row:after { + clear: both; +} +[class*="span"] { + float: left; + margin-left: 20px; +} +.span1 { + width: 60px; +} +.span2 { + width: 140px; +} +.span3 { + width: 220px; +} +.span4 { + width: 300px; +} +.span5 { + width: 380px; +} +.span6 { + width: 460px; +} +.span7 { + width: 540px; +} +.span8 { + width: 620px; +} +.span9 { + width: 700px; +} +.span10 { + width: 780px; +} +.span11 { + width: 860px; +} +.span12, +.container { + width: 940px; +} +.offset1 { + margin-left: 100px; +} +.offset2 { + margin-left: 180px; +} +.offset3 { + margin-left: 260px; +} +.offset4 { + margin-left: 340px; +} +.offset5 { + margin-left: 420px; +} +.offset6 { + margin-left: 500px; +} +.offset7 { + margin-left: 580px; +} +.offset8 { + margin-left: 660px; +} +.offset9 { + margin-left: 740px; +} +.offset10 { + margin-left: 820px; +} +.offset11 { + margin-left: 900px; +} +.row-fluid { + width: 100%; + *zoom: 1; +} +.row-fluid:before, +.row-fluid:after { + display: table; + content: ""; +} +.row-fluid:after { + clear: both; +} +.row-fluid > [class*="span"] { + float: left; + margin-left: 2.127659574%; +} +.row-fluid > [class*="span"]:first-child { + margin-left: 0; +} +.row-fluid > .span1 { + width: 6.382978723%; +} +.row-fluid > .span2 { + width: 14.89361702%; +} +.row-fluid > .span3 { + width: 23.404255317%; +} +.row-fluid > .span4 { + width: 31.914893614%; +} +.row-fluid > .span5 { + width: 40.425531911%; +} +.row-fluid > .span6 { + width: 48.93617020799999%; +} +.row-fluid > .span7 { + width: 57.446808505%; +} +.row-fluid > .span8 { + width: 65.95744680199999%; +} +.row-fluid > .span9 { + width: 74.468085099%; +} +.row-fluid > .span10 { + width: 82.97872339599999%; +} +.row-fluid > .span11 { + width: 91.489361693%; +} +.row-fluid > .span12 { + width: 99.99999998999999%; +} +.container { + width: 940px; + margin-left: auto; + margin-right: auto; + *zoom: 1; +} +.container:before, +.container:after { + display: table; + content: ""; +} +.container:after { + clear: both; +} +.container-fluid { + padding-left: 20px; + padding-right: 20px; + *zoom: 1; +} +.container-fluid:before, +.container-fluid:after { + display: table; + content: ""; +} +.container-fluid:after { + clear: both; +} +p { + margin: 0 0 9px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + line-height: 18px; +} +p small { + font-size: 11px; + color: #999999; +} +.lead { + margin-bottom: 18px; + font-size: 20px; + font-weight: 200; + line-height: 27px; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + font-weight: bold; + color: #333333; + text-rendering: optimizelegibility; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + color: #999999; +} +h1 { + font-size: 30px; + line-height: 36px; +} +h1 small { + font-size: 18px; +} +h2 { + font-size: 24px; + line-height: 36px; +} +h2 small { + font-size: 18px; +} +h3 { + line-height: 27px; + font-size: 18px; +} +h3 small { + font-size: 14px; +} +h4, +h5, +h6 { + line-height: 18px; +} +h4 { + font-size: 14px; +} +h4 small { + font-size: 12px; +} +h5 { + font-size: 12px; +} +h6 { + font-size: 11px; + color: #999999; + text-transform: uppercase; +} +.page-header { + padding-bottom: 17px; + margin: 18px 0; + border-bottom: 1px solid #eeeeee; +} +.page-header h1 { + line-height: 1; +} +ul, +ol { + padding: 0; + margin: 0 0 9px 25px; +} +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li { + line-height: 18px; +} +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} +dl { + margin-bottom: 18px; +} +dt, +dd { + line-height: 18px; +} +dt { + font-weight: bold; +} +dd { + margin-left: 9px; +} +hr { + margin: 18px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} +strong { + font-weight: bold; +} +em { + font-style: italic; +} +.muted { + color: #999999; +} +abbr { + font-size: 90%; + text-transform: uppercase; + border-bottom: 1px dotted #ddd; + cursor: help; +} +blockquote { + padding: 0 0 0 15px; + margin: 0 0 18px; + border-left: 5px solid #eeeeee; +} +blockquote p { + margin-bottom: 0; + font-size: 16px; + font-weight: 300; + line-height: 22.5px; +} +blockquote small { + display: block; + line-height: 18px; + color: #999999; +} +blockquote small:before { + content: '\2014 \00A0'; +} +blockquote.pull-right { + float: right; + padding-left: 0; + padding-right: 15px; + border-left: 0; + border-right: 5px solid #eeeeee; +} +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} +address { + display: block; + margin-bottom: 18px; + line-height: 18px; + font-style: normal; +} +small { + font-size: 100%; +} +cite { + font-style: normal; +} +code, +pre { + padding: 0 3px 2px; + font-family: Menlo, Monaco, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +code { + padding: 3px 4px; + color: #d14; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 9px; + font-size: 12px; + line-height: 18px; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + white-space: pre; + white-space: pre-wrap; + word-break: break-all; + word-wrap: break-word; +} +pre.prettyprint { + margin-bottom: 18px; +} +pre code { + padding: 0; + color: inherit; + background-color: transparent; + border: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +form { + margin: 0 0 18px; +} +fieldset { + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 27px; + font-size: 19.5px; + line-height: 36px; + color: #333333; + border: 0; + border-bottom: 1px solid #eee; +} +legend small { + font-size: 13.5px; + color: #999999; +} +label, +input, +button, +select, +textarea { + font-size: 13px; + font-weight: normal; + line-height: 18px; +} +input, +button, +select, +textarea { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +label { + display: block; + margin-bottom: 5px; + color: #333333; +} +input, +textarea, +select, +.uneditable-input { + display: inline-block; + width: 210px; + height: 18px; + padding: 4px; + margin-bottom: 9px; + font-size: 13px; + line-height: 18px; + color: #555555; + border: 1px solid #ccc; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.uneditable-textarea { + width: auto; + height: auto; +} +label input, +label textarea, +label select { + display: block; +} +input[type="image"], +input[type="checkbox"], +input[type="radio"] { + width: auto; + height: auto; + padding: 0; + margin: 3px 0; + *margin-top: 0; + /* IE7 */ + + line-height: normal; + cursor: pointer; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + border: 0 \9; + /* IE9 and down */ + +} +input[type="image"] { + border: 0; +} +input[type="file"] { + width: auto; + padding: initial; + line-height: initial; + border: initial; + background-color: #ffffff; + background-color: initial; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +input[type="button"], +input[type="reset"], +input[type="submit"] { + width: auto; + height: auto; +} +select, +input[type="file"] { + height: 28px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 28px; +} +input[type="file"] { + line-height: 18px \9; +} +select { + width: 220px; + background-color: #ffffff; +} +select[multiple], +select[size] { + height: auto; +} +input[type="image"] { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +textarea { + height: auto; +} +input[type="hidden"] { + display: none; +} +.radio, +.checkbox { + padding-left: 18px; +} +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -18px; +} +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} +input, +textarea { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -ms-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} +input:focus, +textarea:focus { + border-color: rgba(82, 168, 236, 0.8); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus, +select:focus { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.input-mini { + width: 60px; +} +.input-small { + width: 90px; +} +.input-medium { + width: 150px; +} +.input-large { + width: 210px; +} +.input-xlarge { + width: 270px; +} +.input-xxlarge { + width: 530px; +} +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input { + float: none; + margin-left: 0; +} +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 50px; +} +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 130px; +} +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 210px; +} +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 290px; +} +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 370px; +} +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 450px; +} +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 530px; +} +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 610px; +} +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 690px; +} +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 770px; +} +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 850px; +} +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 930px; +} +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + background-color: #f5f5f5; + border-color: #ddd; + cursor: not-allowed; +} +.control-group.warning > label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; + border-color: #c09853; +} +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: 0 0 6px #dbc59e; + -moz-box-shadow: 0 0 6px #dbc59e; + box-shadow: 0 0 6px #dbc59e; +} +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} +.control-group.error > label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; + border-color: #b94a48; +} +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: 0 0 6px #d59392; + -moz-box-shadow: 0 0 6px #d59392; + box-shadow: 0 0 6px #d59392; +} +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} +.control-group.success > label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; + border-color: #468847; +} +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: 0 0 6px #7aba7b; + -moz-box-shadow: 0 0 6px #7aba7b; + box-shadow: 0 0 6px #7aba7b; +} +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} +input:focus:required:invalid, +textarea:focus:required:invalid, +select:focus:required:invalid { + color: #b94a48; + border-color: #ee5f5b; +} +input:focus:required:invalid:focus, +textarea:focus:required:invalid:focus, +select:focus:required:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} +.form-actions { + padding: 17px 20px 18px; + margin-top: 18px; + margin-bottom: 18px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; +} +.uneditable-input { + display: block; + background-color: #ffffff; + border-color: #eee; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + cursor: not-allowed; +} +:-moz-placeholder { + color: #999999; +} +::-webkit-input-placeholder { + color: #999999; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 0; + color: #999999; +} +.help-inline { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-bottom: 9px; + vertical-align: middle; + padding-left: 5px; +} +.input-prepend, +.input-append { + margin-bottom: 5px; + *zoom: 1; +} +.input-prepend:before, +.input-append:before, +.input-prepend:after, +.input-append:after { + display: table; + content: ""; +} +.input-prepend:after, +.input-append:after { + clear: both; +} +.input-prepend input, +.input-append input, +.input-prepend .uneditable-input, +.input-append .uneditable-input { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-prepend input:focus, +.input-append input:focus, +.input-prepend .uneditable-input:focus, +.input-append .uneditable-input:focus { + position: relative; + z-index: 2; +} +.input-prepend .uneditable-input, +.input-append .uneditable-input { + border-left-color: #ccc; +} +.input-prepend .add-on, +.input-append .add-on { + float: left; + display: block; + width: auto; + min-width: 16px; + height: 18px; + margin-right: -1px; + padding: 4px 5px; + font-weight: normal; + line-height: 18px; + color: #999999; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #f5f5f5; + border: 1px solid #ccc; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-prepend .active, +.input-append .active { + background-color: #a9dba9; + border-color: #46a546; +} +.input-prepend .add-on { + *margin-top: 1px; + /* IE6-7 */ + +} +.input-append input, +.input-append .uneditable-input { + float: left; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-append .uneditable-input { + border-left-color: #eee; + border-right-color: #ccc; +} +.input-append .add-on { + margin-right: 0; + margin-left: -1px; + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-append input:first-child { + *margin-left: -160px; +} +.input-append input:first-child + .add-on { + *margin-left: -21px; +} +.search-query { + padding-left: 14px; + padding-right: 14px; + margin-bottom: 0; + -webkit-border-radius: 14px; + -moz-border-radius: 14px; + border-radius: 14px; +} +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input { + display: inline-block; + margin-bottom: 0; +} +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} +.form-search label, +.form-inline label, +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + display: inline-block; +} +.form-search .input-append .add-on, +.form-inline .input-prepend .add-on, +.form-search .input-append .add-on, +.form-inline .input-prepend .add-on { + vertical-align: middle; +} +.form-search .radio, +.form-inline .radio, +.form-search .checkbox, +.form-inline .checkbox { + margin-bottom: 0; + vertical-align: middle; +} +.control-group { + margin-bottom: 9px; +} +legend + .control-group { + margin-top: 18px; + -webkit-margin-top-collapse: separate; +} +.form-horizontal .control-group { + margin-bottom: 18px; + *zoom: 1; +} +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + content: ""; +} +.form-horizontal .control-group:after { + clear: both; +} +.form-horizontal .control-label { + float: left; + width: 140px; + padding-top: 5px; + text-align: right; +} +.form-horizontal .controls { + margin-left: 160px; +} +.form-horizontal .form-actions { + padding-left: 160px; +} +table { + max-width: 100%; + border-collapse: collapse; + border-spacing: 0; +} +.table { + width: 100%; + margin-bottom: 18px; +} +.table th, +.table td { + padding: 8px; + line-height: 18px; + text-align: left; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table th { + font-weight: bold; +} +.table thead th { + vertical-align: bottom; +} +.table thead:first-child tr th, +.table thead:first-child tr td { + border-top: 0; +} +.table tbody + tbody { + border-top: 2px solid #ddd; +} +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} +.table-bordered { + border: 1px solid #ddd; + border-collapse: separate; + *border-collapse: collapsed; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.table-bordered th + th, +.table-bordered td + td, +.table-bordered th + td, +.table-bordered td + th { + border-left: 1px solid #ddd; +} +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} +.table-bordered thead:first-child tr:first-child th:first-child, +.table-bordered tbody:first-child tr:first-child td:first-child { + -webkit-border-radius: 4px 0 0 0; + -moz-border-radius: 4px 0 0 0; + border-radius: 4px 0 0 0; +} +.table-bordered thead:first-child tr:first-child th:last-child, +.table-bordered tbody:first-child tr:first-child td:last-child { + -webkit-border-radius: 0 4px 0 0; + -moz-border-radius: 0 4px 0 0; + border-radius: 0 4px 0 0; +} +.table-bordered thead:last-child tr:last-child th:first-child, +.table-bordered tbody:last-child tr:last-child td:first-child { + -webkit-border-radius: 0 0 0 4px; + -moz-border-radius: 0 0 0 4px; + border-radius: 0 0 0 4px; +} +.table-bordered thead:last-child tr:last-child th:last-child, +.table-bordered tbody:last-child tr:last-child td:last-child { + -webkit-border-radius: 0 0 4px 0; + -moz-border-radius: 0 0 4px 0; + border-radius: 0 0 4px 0; +} +.table-striped tbody tr:nth-child(odd) td, +.table-striped tbody tr:nth-child(odd) th { + background-color: #f9f9f9; +} +.table tbody tr:hover td, +.table tbody tr:hover th { + background-color: #f5f5f5; +} +table .span1 { + float: none; + width: 44px; + margin-left: 0; +} +table .span2 { + float: none; + width: 124px; + margin-left: 0; +} +table .span3 { + float: none; + width: 204px; + margin-left: 0; +} +table .span4 { + float: none; + width: 284px; + margin-left: 0; +} +table .span5 { + float: none; + width: 364px; + margin-left: 0; +} +table .span6 { + float: none; + width: 444px; + margin-left: 0; +} +table .span7 { + float: none; + width: 524px; + margin-left: 0; +} +table .span8 { + float: none; + width: 604px; + margin-left: 0; +} +table .span9 { + float: none; + width: 684px; + margin-left: 0; +} +table .span10 { + float: none; + width: 764px; + margin-left: 0; +} +table .span11 { + float: none; + width: 844px; + margin-left: 0; +} +table .span12 { + float: none; + width: 924px; + margin-left: 0; +} +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + line-height: 14px; + vertical-align: text-top; + background-image: url("/static/img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; + *margin-right: .3em; +} +[class^="icon-"]:last-child, +[class*=" icon-"]:last-child { + *margin-left: 0; +} +.icon-white { + background-image: url("/static/img/glyphicons-halflings-white.png"); +} +.icon-glass { + background-position: 0 0; +} +.icon-music { + background-position: -24px 0; +} +.icon-search { + background-position: -48px 0; +} +.icon-envelope { + background-position: -72px 0; +} +.icon-heart { + background-position: -96px 0; +} +.icon-star { + background-position: -120px 0; +} +.icon-star-empty { + background-position: -144px 0; +} +.icon-user { + background-position: -168px 0; +} +.icon-film { + background-position: -192px 0; +} +.icon-th-large { + background-position: -216px 0; +} +.icon-th { + background-position: -240px 0; +} +.icon-th-list { + background-position: -264px 0; +} +.icon-ok { + background-position: -288px 0; +} +.icon-remove { + background-position: -312px 0; +} +.icon-zoom-in { + background-position: -336px 0; +} +.icon-zoom-out { + background-position: -360px 0; +} +.icon-off { + background-position: -384px 0; +} +.icon-signal { + background-position: -408px 0; +} +.icon-cog { + background-position: -432px 0; +} +.icon-trash { + background-position: -456px 0; +} +.icon-home { + background-position: 0 -24px; +} +.icon-file { + background-position: -24px -24px; +} +.icon-time { + background-position: -48px -24px; +} +.icon-road { + background-position: -72px -24px; +} +.icon-download-alt { + background-position: -96px -24px; +} +.icon-download { + background-position: -120px -24px; +} +.icon-upload { + background-position: -144px -24px; +} +.icon-inbox { + background-position: -168px -24px; +} +.icon-play-circle { + background-position: -192px -24px; +} +.icon-repeat { + background-position: -216px -24px; +} +.icon-refresh { + background-position: -240px -24px; +} +.icon-list-alt { + background-position: -264px -24px; +} +.icon-lock { + background-position: -287px -24px; +} +.icon-flag { + background-position: -312px -24px; +} +.icon-headphones { + background-position: -336px -24px; +} +.icon-volume-off { + background-position: -360px -24px; +} +.icon-volume-down { + background-position: -384px -24px; +} +.icon-volume-up { + background-position: -408px -24px; +} +.icon-qrcode { + background-position: -432px -24px; +} +.icon-barcode { + background-position: -456px -24px; +} +.icon-tag { + background-position: 0 -48px; +} +.icon-tags { + background-position: -25px -48px; +} +.icon-book { + background-position: -48px -48px; +} +.icon-bookmark { + background-position: -72px -48px; +} +.icon-print { + background-position: -96px -48px; +} +.icon-camera { + background-position: -120px -48px; +} +.icon-font { + background-position: -144px -48px; +} +.icon-bold { + background-position: -167px -48px; +} +.icon-italic { + background-position: -192px -48px; +} +.icon-text-height { + background-position: -216px -48px; +} +.icon-text-width { + background-position: -240px -48px; +} +.icon-align-left { + background-position: -264px -48px; +} +.icon-align-center { + background-position: -288px -48px; +} +.icon-align-right { + background-position: -312px -48px; +} +.icon-align-justify { + background-position: -336px -48px; +} +.icon-list { + background-position: -360px -48px; +} +.icon-indent-left { + background-position: -384px -48px; +} +.icon-indent-right { + background-position: -408px -48px; +} +.icon-facetime-video { + background-position: -432px -48px; +} +.icon-picture { + background-position: -456px -48px; +} +.icon-pencil { + background-position: 0 -72px; +} +.icon-map-marker { + background-position: -24px -72px; +} +.icon-adjust { + background-position: -48px -72px; +} +.icon-tint { + background-position: -72px -72px; +} +.icon-edit { + background-position: -96px -72px; +} +.icon-share { + background-position: -120px -72px; +} +.icon-check { + background-position: -144px -72px; +} +.icon-move { + background-position: -168px -72px; +} +.icon-step-backward { + background-position: -192px -72px; +} +.icon-fast-backward { + background-position: -216px -72px; +} +.icon-backward { + background-position: -240px -72px; +} +.icon-play { + background-position: -264px -72px; +} +.icon-pause { + background-position: -288px -72px; +} +.icon-stop { + background-position: -312px -72px; +} +.icon-forward { + background-position: -336px -72px; +} +.icon-fast-forward { + background-position: -360px -72px; +} +.icon-step-forward { + background-position: -384px -72px; +} +.icon-eject { + background-position: -408px -72px; +} +.icon-chevron-left { + background-position: -432px -72px; +} +.icon-chevron-right { + background-position: -456px -72px; +} +.icon-plus-sign { + background-position: 0 -96px; +} +.icon-minus-sign { + background-position: -24px -96px; +} +.icon-remove-sign { + background-position: -48px -96px; +} +.icon-ok-sign { + background-position: -72px -96px; +} +.icon-question-sign { + background-position: -96px -96px; +} +.icon-info-sign { + background-position: -120px -96px; +} +.icon-screenshot { + background-position: -144px -96px; +} +.icon-remove-circle { + background-position: -168px -96px; +} +.icon-ok-circle { + background-position: -192px -96px; +} +.icon-ban-circle { + background-position: -216px -96px; +} +.icon-arrow-left { + background-position: -240px -96px; +} +.icon-arrow-right { + background-position: -264px -96px; +} +.icon-arrow-up { + background-position: -289px -96px; +} +.icon-arrow-down { + background-position: -312px -96px; +} +.icon-share-alt { + background-position: -336px -96px; +} +.icon-resize-full { + background-position: -360px -96px; +} +.icon-resize-small { + background-position: -384px -96px; +} +.icon-plus { + background-position: -408px -96px; +} +.icon-minus { + background-position: -433px -96px; +} +.icon-asterisk { + background-position: -456px -96px; +} +.icon-exclamation-sign { + background-position: 0 -120px; +} +.icon-gift { + background-position: -24px -120px; +} +.icon-leaf { + background-position: -48px -120px; +} +.icon-fire { + background-position: -72px -120px; +} +.icon-eye-open { + background-position: -96px -120px; +} +.icon-eye-close { + background-position: -120px -120px; +} +.icon-warning-sign { + background-position: -144px -120px; +} +.icon-plane { + background-position: -168px -120px; +} +.icon-calendar { + background-position: -192px -120px; +} +.icon-random { + background-position: -216px -120px; +} +.icon-comment { + background-position: -240px -120px; +} +.icon-magnet { + background-position: -264px -120px; +} +.icon-chevron-up { + background-position: -288px -120px; +} +.icon-chevron-down { + background-position: -313px -119px; +} +.icon-retweet { + background-position: -336px -120px; +} +.icon-shopping-cart { + background-position: -360px -120px; +} +.icon-folder-close { + background-position: -384px -120px; +} +.icon-folder-open { + background-position: -408px -120px; +} +.icon-resize-vertical { + background-position: -432px -119px; +} +.icon-resize-horizontal { + background-position: -456px -118px; +} +.dropdown { + position: relative; +} +.dropdown-toggle { + *margin-bottom: -3px; +} +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} +.caret { + display: inline-block; + width: 0; + height: 0; + text-indent: -99999px; + *text-indent: 0; + vertical-align: top; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #000000; + opacity: 0.3; + filter: alpha(opacity=30); + content: "\2193"; +} +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} +.dropdown:hover .caret, +.open.dropdown .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + float: left; + display: none; + min-width: 160px; + _width: 160px; + padding: 4px 0; + margin: 0; + list-style: none; + background-color: #ffffff; + border-color: #ccc; + border-color: rgba(0, 0, 0, 0.2); + border-style: solid; + border-width: 1px; + -webkit-border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + *border-right-width: 2px; + *border-bottom-width: 2px; +} +.dropdown-menu.bottom-up { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +.dropdown-menu .divider { + height: 1px; + margin: 5px 1px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; + *width: 100%; + *margin: -5px 0 5px; +} +.dropdown-menu a { + display: block; + padding: 3px 15px; + clear: both; + font-weight: normal; + line-height: 18px; + color: #555555; + white-space: nowrap; +} +.dropdown-menu li > a:hover, +.dropdown-menu .active > a, +.dropdown-menu .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: #0088cc; +} +.dropdown.open { + *z-index: 1000; +} +.dropdown.open .dropdown-toggle { + color: #ffffff; + background: #ccc; + background: rgba(0, 0, 0, 0.3); +} +.dropdown.open .dropdown-menu { + display: block; +} +.typeahead { + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #eee; + border: 1px solid rgba(0, 0, 0, 0.05); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.fade { + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -ms-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; + opacity: 0; +} +.fade.in { + opacity: 1; +} +.collapse { + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -ms-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; + position: relative; + overflow: hidden; + height: 0; +} +.collapse.in { + height: auto; +} +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover { + color: #000000; + text-decoration: none; + opacity: 0.4; + filter: alpha(opacity=40); + cursor: pointer; +} +.btn { + display: inline-block; + padding: 4px 10px 4px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + background-color: #f5f5f5; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(top, #ffffff, #e6e6e6); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0); + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border: 1px solid #ccc; + border-bottom-color: #bbb; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + cursor: pointer; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + *margin-left: .3em; +} +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + background-color: #e6e6e6; +} +.btn:active, +.btn.active { + background-color: #cccccc \9; +} +.btn:first-child { + *margin-left: 0; +} +.btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -ms-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn.active, +.btn:active { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + background-color: #e6e6e6; + background-color: #d9d9d9 \9; + outline: 0; +} +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + background-color: #e6e6e6; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-large [class^="icon-"] { + margin-top: 1px; +} +.btn-small { + padding: 5px 9px; + font-size: 11px; + line-height: 16px; +} +.btn-small [class^="icon-"] { + margin-top: -1px; +} +.btn-mini { + padding: 2px 6px; + font-size: 11px; + line-height: 14px; +} +.btn-primary, +.btn-primary:hover, +.btn-warning, +.btn-warning:hover, +.btn-danger, +.btn-danger:hover, +.btn-success, +.btn-success:hover, +.btn-info, +.btn-info:hover, +.btn-inverse, +.btn-inverse:hover { + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + color: #ffffff; +} +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-dark.active { + color: rgba(255, 255, 255, 0.75); +} +.btn-primary { + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -ms-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(top, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + background-color: #0044cc; +} +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} +.btn-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -ms-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(top, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0); + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-warning:hover, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + background-color: #f89406; +} +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} +.btn-danger { + background-color: #da4f49; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -ms-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(top, #ee5f5b, #bd362f); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0); + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-danger:hover, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + background-color: #bd362f; +} +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} +.btn-success { + background-color: #5bb75b; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -ms-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(top, #62c462, #51a351); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0); + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-success:hover, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + background-color: #51a351; +} +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} +.btn-info { + background-color: #49afcd; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -ms-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(top, #5bc0de, #2f96b4); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0); + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-info:hover, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + background-color: #2f96b4; +} +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} +.btn-inverse { + background-color: #393939; + background-image: -moz-linear-gradient(top, #454545, #262626); + background-image: -ms-linear-gradient(top, #454545, #262626); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#454545), to(#262626)); + background-image: -webkit-linear-gradient(top, #454545, #262626); + background-image: -o-linear-gradient(top, #454545, #262626); + background-image: linear-gradient(top, #454545, #262626); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#454545', endColorstr='#262626', GradientType=0); + border-color: #262626 #262626 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.btn-inverse:hover, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + background-color: #262626; +} +.btn-inverse:active, +.btn-inverse.active { + background-color: #0c0c0c \9; +} +button.btn, +input[type="submit"].btn { + *padding-top: 2px; + *padding-bottom: 2px; +} +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.large, +input[type="submit"].btn.large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.small, +input[type="submit"].btn.small { + *padding-top: 3px; + *padding-bottom: 3px; +} +.btn-group { + position: relative; + *zoom: 1; + *margin-left: .3em; +} +.btn-group:before, +.btn-group:after { + display: table; + content: ""; +} +.btn-group:after { + clear: both; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + margin-top: 9px; + margin-bottom: 9px; +} +.btn-toolbar .btn-group { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} +.btn-group .btn { + position: relative; + float: left; + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group .btn:last-child, +.btn-group .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.btn-group .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group .btn.large:last-child, +.btn-group .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group .btn:hover, +.btn-group .btn:focus, +.btn-group .btn:active, +.btn-group .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group.open { + *z-index: 1000; +} +.btn-group.open .dropdown-menu { + display: block; + margin-top: 1px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.btn .caret { + margin-top: 7px; + margin-left: 0; +} +.btn:hover .caret, +.open.btn-group .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.btn-primary .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + opacity: 0.75; + filter: alpha(opacity=75); +} +.btn-small .caret { + margin-top: 4px; +} +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 18px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.alert, +.alert-heading { + color: #c09853; +} +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 18px; +} +.alert-success { + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success, +.alert-success .alert-heading { + color: #468847; +} +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #eed3d7; +} +.alert-danger, +.alert-error, +.alert-danger .alert-heading, +.alert-error .alert-heading { + color: #b94a48; +} +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info, +.alert-info .alert-heading { + color: #3a87ad; +} +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} +.alert-block p + p { + margin-top: 5px; +} +.nav { + margin-left: 0; + margin-bottom: 18px; + list-style: none; +} +.nav > li > a { + display: block; +} +.nav > li > a:hover { + text-decoration: none; + background-color: #eeeeee; +} +.nav .nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 18px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} +.nav li + .nav-header { + margin-top: 9px; +} +.nav-list { + padding-left: 14px; + padding-right: 14px; + margin-bottom: 0; +} +.nav-list > li > a, +.nav-list .nav-header { + margin-left: -15px; + margin-right: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.nav-list > li > a { + padding: 3px 15px; +} +.nav-list .active > a, +.nav-list .active > a:hover { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} +.nav-list [class^="icon-"] { + margin-right: 2px; +} +.nav-tabs, +.nav-pills { + *zoom: 1; +} +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + content: ""; +} +.nav-tabs:after, +.nav-pills:after { + clear: both; +} +.nav-tabs > li, +.nav-pills > li { + float: left; +} +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + margin-bottom: -1px; +} +.nav-tabs > li > a { + padding-top: 9px; + padding-bottom: 9px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover { + color: #555555; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.nav-pills .active > a, +.nav-pills .active > a:hover { + color: #ffffff; + background-color: #0088cc; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li > a { + margin-right: 0; +} +.nav-tabs.nav-stacked { + border-bottom: 0; +} +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.nav-tabs.nav-stacked > li > a:hover { + border-color: #ddd; + z-index: 2; +} +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} +.nav-tabs .dropdown-menu, +.nav-pills .dropdown-menu { + margin-top: 1px; + border-width: 1px; +} +.nav-pills .dropdown-menu { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.nav-tabs .dropdown-toggle .caret, +.nav-pills .dropdown-toggle .caret { + border-top-color: #0088cc; + margin-top: 6px; +} +.nav-tabs .dropdown-toggle:hover .caret, +.nav-pills .dropdown-toggle:hover .caret { + border-top-color: #005580; +} +.nav-tabs .active .dropdown-toggle .caret, +.nav-pills .active .dropdown-toggle .caret { + border-top-color: #333333; +} +.nav > .dropdown.active > a:hover { + color: #000000; + cursor: pointer; +} +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > .open.active > a:hover { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} +.nav .open .caret, +.nav .open.active .caret, +.nav .open a:hover .caret { + border-top-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} +.tabs-stacked .open > a:hover { + border-color: #999999; +} +.tabbable { + *zoom: 1; +} +.tabbable:before, +.tabbable:after { + display: table; + content: ""; +} +.tabbable:after { + clear: both; +} +.tab-content { + overflow: hidden; +} +.tabs-below .nav-tabs, +.tabs-right .nav-tabs, +.tabs-left .nav-tabs { + border-bottom: 0; +} +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} +.tab-content > .active, +.pill-content > .active { + display: block; +} +.tabs-below .nav-tabs { + border-top: 1px solid #ddd; +} +.tabs-below .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} +.tabs-below .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.tabs-below .nav-tabs > li > a:hover { + border-bottom-color: transparent; + border-top-color: #ddd; +} +.tabs-below .nav-tabs .active > a, +.tabs-below .nav-tabs .active > a:hover { + border-color: transparent #ddd #ddd #ddd; +} +.tabs-left .nav-tabs > li, +.tabs-right .nav-tabs > li { + float: none; +} +.tabs-left .nav-tabs > li > a, +.tabs-right .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} +.tabs-left .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} +.tabs-left .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} +.tabs-left .nav-tabs > li > a:hover { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} +.tabs-left .nav-tabs .active > a, +.tabs-left .nav-tabs .active > a:hover { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} +.tabs-right .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} +.tabs-right .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.tabs-right .nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} +.tabs-right .nav-tabs .active > a, +.tabs-right .nav-tabs .active > a:hover { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} +.navbar { + overflow: visible; + margin-bottom: 18px; +} +.navbar-inner { + padding-left: 20px; + padding-right: 20px; + background-color: #2c2c2c; + background-image: -moz-linear-gradient(top, #333333, #222222); + background-image: -ms-linear-gradient(top, #333333, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222)); + background-image: -webkit-linear-gradient(top, #333333, #222222); + background-image: -o-linear-gradient(top, #333333, #222222); + background-image: linear-gradient(top, #333333, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); +} +.btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-left: 5px; + margin-right: 5px; + background-color: #2c2c2c; + background-image: -moz-linear-gradient(top, #333333, #222222); + background-image: -ms-linear-gradient(top, #333333, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222)); + background-image: -webkit-linear-gradient(top, #333333, #222222); + background-image: -o-linear-gradient(top, #333333, #222222); + background-image: linear-gradient(top, #333333, #222222); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} +.btn-navbar:hover, +.btn-navbar:active, +.btn-navbar.active, +.btn-navbar.disabled, +.btn-navbar[disabled] { + background-color: #222222; +} +.btn-navbar:active, +.btn-navbar.active { + background-color: #080808 \9; +} +.btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} +.nav-collapse.collapse { + height: auto; +} +.navbar .brand:hover { + text-decoration: none; +} +.navbar .brand { + float: left; + display: block; + padding: 8px 20px 12px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + line-height: 1; + color: #ffffff; +} +.navbar .navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #999999; +} +.navbar .navbar-text a:hover { + color: #ffffff; + background-color: transparent; +} +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} +.navbar .btn-group .btn { + margin-top: 0; +} +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} +.navbar-form:before, +.navbar-form:after { + display: table; + content: ""; +} +.navbar-form:after { + clear: both; +} +.navbar-form input, +.navbar-form select { + display: inline-block; + margin-top: 5px; + margin-bottom: 0; +} +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 6px; + white-space: nowrap; +} +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} +.navbar-search { + position: relative; + float: left; + margin-top: 6px; + margin-bottom: 0; +} +.navbar-search .search-query { + padding: 4px 9px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + color: #ffffff; + color: rgba(255, 255, 255, 0.75); + background: #666; + background: rgba(255, 255, 255, 0.3); + border: 1px solid #111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0px rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -ms-transition: none; + -o-transition: none; + transition: none; +} +.navbar-search .search-query :-moz-placeholder { + color: #eeeeee; +} +.navbar-search .search-query::-webkit-input-placeholder { + color: #eeeeee; +} +.navbar-search .search-query:hover { + color: #ffffff; + background-color: #999999; + background-color: rgba(255, 255, 255, 0.5); +} +.navbar-search .search-query:focus, +.navbar-search .search-query.focused { + padding: 5px 10px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + outline: 0; +} +.navbar-fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} +.navbar-fixed-top .navbar-inner { + padding-left: 0; + padding-right: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} +.navbar .nav.pull-right { + float: right; +} +.navbar .nav > li { + display: block; + float: left; +} +.navbar .nav > li > a { + float: none; + padding: 10px 10px 11px; + line-height: 19px; + color: #999999; + text-decoration: none; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.navbar .nav > li > a:hover { + background-color: transparent; + color: #ffffff; + text-decoration: none; +} +.navbar .nav .active > a, +.navbar .nav .active > a:hover { + color: #ffffff; + text-decoration: none; + background-color: #222222; +} +.navbar .divider-vertical { + height: 40px; + width: 1px; + margin: 0 9px; + overflow: hidden; + background-color: #222222; + border-right: 1px solid #333333; +} +.navbar .nav.pull-right { + margin-left: 10px; + margin-right: 0; +} +.navbar .dropdown-menu { + margin-top: 1px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.navbar .dropdown-menu:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 9px; +} +.navbar .dropdown-menu:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 10px; +} +.navbar .nav .dropdown-toggle .caret, +.navbar .nav .open.dropdown .caret { + border-top-color: #ffffff; +} +.navbar .nav .active .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.navbar .nav .open > .dropdown-toggle, +.navbar .nav .active > .dropdown-toggle, +.navbar .nav .open.active > .dropdown-toggle { + background-color: transparent; +} +.navbar .nav .active > .dropdown-toggle:hover { + color: #ffffff; +} +.navbar .nav.pull-right .dropdown-menu { + left: auto; + right: 0; +} +.navbar .nav.pull-right .dropdown-menu:before { + left: auto; + right: 12px; +} +.navbar .nav.pull-right .dropdown-menu:after { + left: auto; + right: 13px; +} +.breadcrumb { + padding: 7px 14px; + margin: 0 0 18px; + background-color: #fbfbfb; + background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5)); + background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5); + background-image: -o-linear-gradient(top, #ffffff, #f5f5f5); + background-image: linear-gradient(top, #ffffff, #f5f5f5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0); + border: 1px solid #ddd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} +.breadcrumb li { + display: inline-block; + text-shadow: 0 1px 0 #ffffff; +} +.breadcrumb .divider { + padding: 0 5px; + color: #999999; +} +.breadcrumb .active a { + color: #333333; +} +.pagination { + height: 36px; + margin: 18px 0; +} +.pagination ul { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; + margin-left: 0; + margin-bottom: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.pagination li { + display: inline; +} +.pagination a { + float: left; + padding: 0 14px; + line-height: 34px; + text-decoration: none; + border: 1px solid #ddd; + border-left-width: 0; +} +.pagination a:hover, +.pagination .active a { + background-color: #f5f5f5; +} +.pagination .active a { + color: #999999; + cursor: default; +} +.pagination .disabled a, +.pagination .disabled a:hover { + color: #999999; + background-color: transparent; + cursor: default; +} +.pagination li:first-child a { + border-left-width: 1px; + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.pagination li:last-child a { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.pagination-centered { + text-align: center; +} +.pagination-right { + text-align: right; +} +.pager { + margin-left: 0; + margin-bottom: 18px; + list-style: none; + text-align: center; + *zoom: 1; +} +.pager:before, +.pager:after { + display: table; + content: ""; +} +.pager:after { + clear: both; +} +.pager li { + display: inline; +} +.pager a { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} +.pager a:hover { + text-decoration: none; + background-color: #f5f5f5; +} +.pager .next a { + float: right; +} +.pager .previous a { + float: left; +} +.modal-open .dropdown-menu { + z-index: 2050; +} +.modal-open .dropdown.open { + *z-index: 2050; +} +.modal-open .popover { + z-index: 2060; +} +.modal-open .tooltip { + z-index: 2070; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.modal { + position: fixed; + top: 50%; + left: 50%; + z-index: 1050; + max-height: 500px; + overflow: auto; + width: 560px; + margin: -250px 0 0 -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + /* IE6-7 */ + + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.modal.fade { + -webkit-transition: opacity .3s linear, top .3s ease-out; + -moz-transition: opacity .3s linear, top .3s ease-out; + -ms-transition: opacity .3s linear, top .3s ease-out; + -o-transition: opacity .3s linear, top .3s ease-out; + transition: opacity .3s linear, top .3s ease-out; + top: -25%; +} +.modal.fade.in { + top: 50%; +} +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} +.modal-header .close { + margin-top: 2px; +} +.modal-body { + padding: 15px; +} +.modal-body .modal-form { + margin-bottom: 0; +} +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; + *zoom: 1; +} +.modal-footer:before, +.modal-footer:after { + display: table; + content: ""; +} +.modal-footer:after { + clear: both; +} +.modal-footer .btn { + float: right; + margin-left: 5px; + margin-bottom: 0; +} +.tooltip { + position: absolute; + z-index: 1020; + display: block; + visibility: visible; + padding: 5px; + font-size: 11px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} +.tooltip.top { + margin-top: -2px; +} +.tooltip.right { + margin-left: 2px; +} +.tooltip.bottom { + margin-top: 2px; +} +.tooltip.left { + margin-left: -2px; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + padding: 5px; +} +.popover.top { + margin-top: -5px; +} +.popover.right { + margin-left: 5px; +} +.popover.bottom { + margin-top: 5px; +} +.popover.left { + margin-left: -5px; +} +.popover.top .arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 5px solid #000000; +} +.popover.right .arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-right: 5px solid #000000; +} +.popover.bottom .arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-bottom: 5px solid #000000; +} +.popover.left .arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + border-left: 5px solid #000000; +} +.popover .arrow { + position: absolute; + width: 0; + height: 0; +} +.popover-inner { + padding: 3px; + width: 280px; + overflow: hidden; + background: #000000; + background: rgba(0, 0, 0, 0.8); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); +} +.popover-title { + padding: 9px 15px; + line-height: 1; + background-color: #f5f5f5; + border-bottom: 1px solid #eee; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.popover-content { + padding: 14px; + background-color: #ffffff; + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} +.popover-content p, +.popover-content ul, +.popover-content ol { + margin-bottom: 0; +} +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} +.thumbnails:before, +.thumbnails:after { + display: table; + content: ""; +} +.thumbnails:after { + clear: both; +} +.thumbnails > li { + float: left; + margin: 0 0 18px 20px; +} +.thumbnail { + display: block; + padding: 4px; + line-height: 1; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075); +} +a.thumbnail:hover { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} +.thumbnail > img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; +} +.thumbnail .caption { + padding: 9px; +} +.label { + padding: 2px 4px 3px; + font-size: 11.049999999999999px; + font-weight: bold; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #999999; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.label:hover { + color: #ffffff; + text-decoration: none; +} +.label-important { + background-color: #b94a48; +} +.label-important:hover { + background-color: #953b39; +} +.label-warning { + background-color: #f89406; +} +.label-warning:hover { + background-color: #c67605; +} +.label-success { + background-color: #468847; +} +.label-success:hover { + background-color: #356635; +} +.label-info { + background-color: #3a87ad; +} +.label-info:hover { + background-color: #2d6987; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@-moz-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} +.progress { + overflow: hidden; + height: 18px; + margin-bottom: 18px; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -ms-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(top, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.progress .bar { + width: 0%; + height: 18px; + color: #ffffff; + font-size: 12px; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -ms-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(top, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -ms-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .bar { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-danger .bar { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(top, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0); +} +.progress-danger.progress-striped .bar { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-success .bar { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -ms-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(top, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0); +} +.progress-success.progress-striped .bar { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-info .bar { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -ms-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(top, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0); +} +.progress-info.progress-striped .bar { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.accordion { + margin-bottom: 18px; +} +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.accordion-heading { + border-bottom: 0; +} +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} +.carousel { + position: relative; + margin-bottom: 18px; + line-height: 1; +} +.carousel-inner { + overflow: hidden; + width: 100%; + position: relative; +} +.carousel .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -ms-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel .item > img { + display: block; + line-height: 1; +} +.carousel .active, +.carousel .next, +.carousel .prev { + display: block; +} +.carousel .active { + left: 0; +} +.carousel .next, +.carousel .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel .next { + left: 100%; +} +.carousel .prev { + left: -100%; +} +.carousel .next.left, +.carousel .prev.right { + left: 0; +} +.carousel .active.left { + left: -100%; +} +.carousel .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} +.carousel-control.right { + left: auto; + right: 15px; +} +.carousel-control:hover { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-caption { + position: absolute; + left: 0; + right: 0; + bottom: 0; + padding: 10px 15px 5px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} +.carousel-caption h4, +.carousel-caption p { + color: #ffffff; +} +.hero-unit { + padding: 60px; + margin-bottom: 30px; + background-color: #f5f5f5; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; +} +.hero-unit p { + font-size: 18px; + font-weight: 200; + line-height: 27px; +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +/* Signin & Signup Page Style */ +body { + background: url("/static/img/bg-noise.jpg"); +} +.sign { + margin: 0; +} +.sign #wrapper { + width: 250px; + margin-top: 200px; + display: block; + margin-left: auto; + margin-right: auto; +} +.sign #wrapper #logo { + margin-bottom: 20px; + padding-left: 40px; + width: 260px; +} +.sign #wrapper #logo .logo { + font-size: 50px; + font-family: 'Port Lligat Slab', serif; +} +.sign #wrapper #logo .subtitle { + position: relative; + left: 80px; + top: -5px; + font-size: 10px; +} +.sign #wrapper .signform { + width: 260px; +} +.sign #wrapper .signform .input-prepend input, +.sign #wrapper .signform .input-prepend .btn { + float: left; +} +.sign #wrapper .signform .add-on, +.sign #wrapper .signform input { + height: 28px; + line-height: 28px; +} +.sign #wrapper .signform .btn { + width: 246px; + height: 34px; +} +.sign #wrapper .signform a.btn { + width: 226px; + height: 26px; + line-height: 26px; +} +/* Common Page Style */ +body { + margin-left: 260px; + margin-bottom: 20px; +} +nav { + color: white; + background: #2B2B2B; + background-image: url("/static/img/lines.jpg"); + width: 240px; + height: 100%; + position: fixed; + top: 0; + left: 0; + overflow: hidden; + z-index: 5; + border-right: solid 1px black; +} +nav .profile { + height: 76px; + border-bottom: 1px solid #4a4a54; +} +nav .profile .profile_wrap { + height: 75px; + border-bottom: 1px solid #1d1e21; +} +nav .profile .profile_wrap .username { + position: absolute; + top: 20px; + left: 70px; + font-family: Arial, sans-serif; + font-size: 14px; + text-shadow: black 0px 1px 1px; +} +nav .profile .profile_wrap .avatar { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2); + -moz-box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2); + box-shadow: 0px 1px 0px rgba(255, 255, 255, 0.2); + width: 45px; + height: 45px; + border: 1px solid black; + position: absolute; + top: 15px; + left: 14px; + cursor: pointer; + overflow: hidden; +} +nav .profile .profile_wrap .avatar img { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + width: 45px; + height: 45px; +} +nav .profile .profile_wrap .avatar .avatar_mask { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0px 0px 9px #000000; + -moz-box-shadow: inset 0px 0px 9px #000000; + box-shadow: inset 0px 0px 9px #000000; + opacity: 0.5; + filter: alpha(opacity=50); + width: 45px; + height: 45px; + position: absolute; + top: 0; + left: 0; +} +nav .nav { + margin-top: 20px; +} diff --git a/static/img/avatar.png b/static/img/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..0356f911c6b01894f0983ecb5f66b01401f84cdc GIT binary patch literal 1323 zcmex=_1P|rX?qqI0P zFI~aY%U!`Mz|~!$%*;qrN1?DZF(6Oj-S5fuR$!pIEN!@|nR z%E~Fi%grl7GWdUhL6CzXfFXdHQHg;`kdaxC@&6G9d7vj*8Nq-73K*GyZe(NU;N;>4 zD%dK(z{JSR%*4VBay3wOEl{3;MUYiU(a@1iI53f2sZhkIapFP_Wv7h?MT0JWP%%y_ zYU1P)6PJ*bQdLve(9|+9H8Z!cv~qTFb#wRd^a>6M4GWKmj7m;PO-s+n%qlJ^Ei136 ztZHs)ZENr7?3y%r%G7DoXUv?nXz`Mz%a*TLxoXqqEnBy3-?4Mop~FXx9y@;G&P778mFHFAhJO}QuuFG%jI8)?h-XAJ6@h5YR)O`c_i3@nTG!`{*0kPR0$*NuTT_rc4C@4(PRNs(4 z-F|H?^N;W|&CPM=AMnc@UKe>ZwNk;?%W(TM`_~QcZ2!7Hc92~v->NFYu)no}zfV6n z;A7fSlN6E9WlYv@8S9r;<@eVV@-?QbE?v{)>*acjY0giF{|tiPzlc6s^5n@UUj|SJ zfWk!7bncSt-wSR#v_6~Kq}2E10_$1k!{6sA?-RS0x#Mf4bgSbl-)i=DJGsm%rX~Fn zdw0vsTqeozpJCHp_Rrtf%5(oH;^%o;calO0eFJIcG!SE;3UMfn1dD=(y z!*})L!zU(-mG_>X&vDHExA%qr4E9wY|JDO7k=bWrV~Pw}aRuXt+(Bjq$cJdsno z^knN4)(JHiz54=p%P(KcQ1kQ0#UEF$Pn#SOdp6ffWR|+dscL~NDF*EebpjcOo(J!| zk`l9a)0=+fAGcTjVgJ0|ZhhvDzzl^Cvpm?1&%CQ=-u|BTrkM36MTsPB0ch;RW{QLApz2KkK=U3mV(~j!=qxMPgjIeU^SL^z3Ss$|) H{@(-u!z~QS literal 0 HcmV?d00001 diff --git a/static/img/background-dark.png b/static/img/background-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9d76791ac0a585910397e84955f302aa6ec1ec GIT binary patch literal 23656 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 LNkvXXu0mjfo`NDK literal 0 HcmV?d00001 diff --git a/static/img/bg-black.gif b/static/img/bg-black.gif new file mode 100644 index 0000000000000000000000000000000000000000..11f8f9332893195644769b220671283622123a67 GIT binary patch literal 14700 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 literal 0 HcmV?d00001 diff --git a/static/img/lines.jpg b/static/img/lines.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d393aac718d278b3e0a532e02f9f19a318a4fcf4 GIT binary patch literal 19856 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 RL44YHjr}SM{XPXp|JnGV)?@$x literal 0 HcmV?d00001 diff --git a/tpl/base.html b/tpl/base.html new file mode 100644 index 0000000..caa974f --- /dev/null +++ b/tpl/base.html @@ -0,0 +1,9 @@ +{% include 'base/head.html' %} + +{% include 'base/sidebar.html' %} +
      +{% include 'base/breadcrumb.html' %} +{% block body %}{% endblock %} +
      + + diff --git a/tpl/base/breadcrumb.html b/tpl/base/breadcrumb.html new file mode 100644 index 0000000..fceb910 --- /dev/null +++ b/tpl/base/breadcrumb.html @@ -0,0 +1,16 @@ +{% if breadcrumb %} + +{% endif %} diff --git a/tpl/base/head.html b/tpl/base/head.html new file mode 100644 index 0000000..00ddddf --- /dev/null +++ b/tpl/base/head.html @@ -0,0 +1,9 @@ + + + + + {% if title %}{{ title }} - {% endif %}{{ page.settings['site_title'] }} + + + {% block head %}{% endblock %} + diff --git a/tpl/base/sidebar.html b/tpl/base/sidebar.html new file mode 100644 index 0000000..4682e87 --- /dev/null +++ b/tpl/base/sidebar.html @@ -0,0 +1,129 @@ + diff --git a/tpl/home.html b/tpl/home.html new file mode 100644 index 0000000..eefdfd3 --- /dev/null +++ b/tpl/home.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} + +{% block body %} +body +{% endblock %} diff --git a/tpl/signin.html b/tpl/signin.html new file mode 100644 index 0000000..8056191 --- /dev/null +++ b/tpl/signin.html @@ -0,0 +1,49 @@ + + + + + {{ page.settings['site_title'] }} + + + + + + +
      + +
      +{% if error %} +
      + × +
        + {% for err in error %} +
      • {{ err }}
      • + {% endfor %} +
      +
      +{% endif %} +
      +{{ page.xsrf_form_html() }} +
      + + +
      +
      + + +
      +
      + +
      + +
      +
      + +
      + + diff --git a/tpl/signup.html b/tpl/signup.html new file mode 100644 index 0000000..b0d1b95 --- /dev/null +++ b/tpl/signup.html @@ -0,0 +1,53 @@ + + + + + {{ page.settings['site_title'] }} + + + + + + +
      + +
      +{% if error %} +
      + × +
        + {% for err in error %} +
      • {{ err }}
      • + {% endfor %} +
      +
      +{% endif %} +
      +{{ page.xsrf_form_html() }} +
      + + +
      +
      + + +
      +
      + + +
      +
      + +
      + +
      +
      + +
      + + diff --git a/vars.less b/vars.less new file mode 100644 index 0000000..766669e --- /dev/null +++ b/vars.less @@ -0,0 +1,22 @@ + +/* Background Images */ + +@bg-noise: "/static/img/bg-noise.jpg"; +@bg-sidebar: "/static/img/lines.jpg"; + +/* Common Const Var */ + +@bottomBlank: 20px; + +/* Wrapper Const Var */ + +@signWidth: 250px; +@signYOffset: 200px; +@signInnerWidth: 260px; + +/* Sidebar Const Var */ + +@sidebarWidth: 240px; +@sidebarLineTopColor: #1D1E21; +@sidebarLineBottomColor: #4A4A54; + From 12de5fa7a41711eb51a4ac20d7ce894fc0856668 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Fri, 9 Mar 2012 19:12:13 +0800 Subject: [PATCH 10/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=20nav=20=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- less/style.less | 41 +++++++++++++++++++++++++++ vars.less => less/vars.less | 0 signup.html | 55 ------------------------------------- static/css/style.css | 35 +++++++++++++++++++++++ 4 files changed, 76 insertions(+), 55 deletions(-) rename vars.less => less/vars.less (100%) delete mode 100644 signup.html diff --git a/less/style.less b/less/style.less index 1cbd9f9..234e4ac 100644 --- a/less/style.less +++ b/less/style.less @@ -90,6 +90,16 @@ nav { text-shadow: black 0px 1px 1px; } + .tagline { + position: absolute; + top: 40px; + left: 70px; + width: 140px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .avatar { .border-radius(4px); .box-shadow(0px 1px 0px rgba(255, 255, 255, 0.2)); @@ -120,5 +130,36 @@ nav { .nav { margin-top: 20px; + + li > a { + color: white; + text-shadow: 0px 1px 1px black; + -webkit-transition-property: background; + -webkit-transition-duration: .2s; + + &:hover { + background: rgba(0, 0, 0, 0.2); + color: white; + text-shadow: 0px 1px 1px black; + } + } + } + + .sep { + margin-top: 20px; + height: 0px; + border-bottom: 1px solid #4A4A54; + border-top: 1px solid #1D1E21; + } + + .copyright { + font-size: 10px; + text-shadow: black 0px 1px 1px; + padding-top: 20px; + padding-left: 14px; + + a { + color: white; + } } } diff --git a/vars.less b/less/vars.less similarity index 100% rename from vars.less rename to less/vars.less diff --git a/signup.html b/signup.html deleted file mode 100644 index 099c488..0000000 --- a/signup.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - {{ page.settings['site_title'] }} - - - - - - - -
      - -
      -{% if error %} -
      - × -
        - {% for err in error %} -
      • {{ err }}
      • - {% endfor %} -
      -
      -{% endif %} -
      -{{ page.xsrf_form_html() }} -
      - - -
      -
      - - -
      -
      - - -
      -
      - -
      - -
      -
      - -
      - - diff --git a/static/css/style.css b/static/css/style.css index 028b38d..0e8f716 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3768,6 +3768,15 @@ nav .profile .profile_wrap .username { font-size: 14px; text-shadow: black 0px 1px 1px; } +nav .profile .profile_wrap .tagline { + position: absolute; + top: 40px; + left: 70px; + width: 140px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} nav .profile .profile_wrap .avatar { -webkit-border-radius: 4px; -moz-border-radius: 4px; @@ -3809,3 +3818,29 @@ nav .profile .profile_wrap .avatar .avatar_mask { nav .nav { margin-top: 20px; } +nav .nav li > a { + color: white; + text-shadow: 0px 1px 1px black; + -webkit-transition-property: background; + -webkit-transition-duration: .2s; +} +nav .nav li > a:hover { + background: rgba(0, 0, 0, 0.2); + color: white; + text-shadow: 0px 1px 1px black; +} +nav .sep { + margin-top: 20px; + height: 0px; + border-bottom: 1px solid #4A4A54; + border-top: 1px solid #1D1E21; +} +nav .copyright { + font-size: 10px; + text-shadow: black 0px 1px 1px; + padding-top: 20px; + padding-left: 14px; +} +nav .copyright a { + color: white; +} From c3df2c2b9f85308c226b65206e9e03d64bea13e6 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Fri, 9 Mar 2012 22:54:21 +0800 Subject: [PATCH 11/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完成公共 .cell 样式,采用 bootstrap 双列排版 各种输出统一格式,采用 macro 方式,见 tpl/macros.html --- less/style.less | 64 ++++++++++++++++++++++++++++++++++++++++++ static/css/style.css | 54 +++++++++++++++++++++++++++++++++++ tpl/home.html | 43 +++++++++++++++++++++++++++- tpl/macros.html | 24 ++++++++++++++++ tpl/widget/count.html | 16 +++++++++++ tpl/widget/notice.html | 1 + 6 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 tpl/macros.html create mode 100644 tpl/widget/count.html create mode 100644 tpl/widget/notice.html diff --git a/less/style.less b/less/style.less index 234e4ac..ed7bed9 100644 --- a/less/style.less +++ b/less/style.less @@ -60,6 +60,53 @@ body { margin-bottom: @bottomBlank; } +.main { + padding-top: 40px; + padding-right: 20px; + width: 96%; +} + +.sep30 { + height: 30px; +} + +.cell { + .border-radius(4px); + .box-shadow(0px 0px 2px #BBB); + border: 2px solid #EEE; + margin-bottom: 30px; + background-color: white; + + &.span8 { + width: 64.95744680199999%; + } + + .title { + font-size: 16px; + font-weight: bold; + line-height: 30px; + padding-left: 10px; + padding-top: 5px; + border-bottom: 1px solid #DDD; + } + + .table { + .border-radius(0px); + margin-bottom: 0; + border: none; + } + + .content { + padding: 10px 20px; + + p { + line-height: 30px; + } + } +} + +/* Navigator Style */ + nav { color: white; background: #2B2B2B; @@ -163,3 +210,20 @@ nav { } } } + +/* HomePage Style */ + +#count .table tr { + + &:hover { + td, th { + background-color: white; + } + } + + th { + color: fade(black, 30); + font-weight: normal; + text-align: right; + } +} diff --git a/static/css/style.css b/static/css/style.css index 0e8f716..261f879 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3739,6 +3739,50 @@ body { margin-left: 260px; margin-bottom: 20px; } +.main { + padding-top: 40px; + padding-right: 20px; + width: 96%; +} +.sep30 { + height: 30px; +} +.cell { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0px 0px 2px #bbbbbb; + -moz-box-shadow: 0px 0px 2px #bbbbbb; + box-shadow: 0px 0px 2px #bbbbbb; + border: 2px solid #EEE; + margin-bottom: 30px; + background-color: white; +} +.cell.span8 { + width: 64.95744680199999%; +} +.cell .title { + font-size: 16px; + font-weight: bold; + line-height: 30px; + padding-left: 10px; + padding-top: 5px; + border-bottom: 1px solid #DDD; +} +.cell .table { + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + border-radius: 0px; + margin-bottom: 0; + border: none; +} +.cell .content { + padding: 10px 20px; +} +.cell .content p { + line-height: 30px; +} +/* Navigator Style */ nav { color: white; background: #2B2B2B; @@ -3844,3 +3888,13 @@ nav .copyright { nav .copyright a { color: white; } +/* HomePage Style */ +#count .table tr:hover td, +#count .table tr:hover th { + background-color: white; +} +#count .table tr th { + color: rgba(0, 0, 0, 0.3); + font-weight: normal; + text-align: right; +} diff --git a/tpl/home.html b/tpl/home.html index eefdfd3..4dec764 100644 --- a/tpl/home.html +++ b/tpl/home.html @@ -1,5 +1,46 @@ {% extends "base.html" %} +{% from 'macros.html' import show_topic_list %} +{% from 'macros.html' import show_problem_list %} +{% from 'macros.html' import show_contest_list %} {% block body %} -body +
      +
      +
      +
      {{ _('Latest Problem') }}
      +
      + {% set latest_problem = "" %} + {{ show_problem_list(latest_problem) }} +
      +
      +
      +
      {{ _('Latest Contest') }}
      +
      + {% set latest_contest = "" %} + {{ show_contest_list(latest_contest) }} +
      +
      +
      +
      {{ _('Latest Discuss') }}
      +
      + {% set latest_topic = "" %} + {{ show_topic_list(latest_topic) }} +
      +
      +
      +
      +
      +
      {{ _('Notice') }}
      +
      + {% include 'widget/notice.html' %} +
      +
      +
      +
      {{ _('Site Count') }}
      +
      + {% include 'widget/count.html' %} +
      +
      +
      +
      {% endblock %} diff --git a/tpl/macros.html b/tpl/macros.html new file mode 100644 index 0000000..f319eab --- /dev/null +++ b/tpl/macros.html @@ -0,0 +1,24 @@ +{% macro show_problem_list(problem_list) %} + + + + + + + + + + + + + + + +
      #TitleShort Name
      1Hello Worldhelloworld
      +{% endmacro %} + +{% macro show_topic_list(topic_list) %} +{% endmacro %} + +{% macro show_contest_list(contest_list) %} +{% endmacro %} diff --git a/tpl/widget/count.html b/tpl/widget/count.html new file mode 100644 index 0000000..d08f7da --- /dev/null +++ b/tpl/widget/count.html @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + +
      Total Problems1
      Total Nodes1
      Total Topics2
      diff --git a/tpl/widget/notice.html b/tpl/widget/notice.html new file mode 100644 index 0000000..c1b3f38 --- /dev/null +++ b/tpl/widget/notice.html @@ -0,0 +1 @@ +

      欢迎来到Vulpix. 这里还正在开发中. BUG提交请至讨论区.

      From caa5caa02918245902aaf3d06fdb2c9050e6016d Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Sat, 10 Mar 2012 16:23:43 +0800 Subject: [PATCH 12/56] =?UTF-8?q?=E5=AF=B9=20cell=20=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E5=B0=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- less/style.less | 7 +++++-- static/css/style.css | 15 +++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/less/style.less b/less/style.less index ed7bed9..e2de5c0 100644 --- a/less/style.less +++ b/less/style.less @@ -6,6 +6,7 @@ body { background: url(@bg-noise); + font-family: "Helvetica Neue", "Luxi Sans", "DejaVu Sans", Tahoma, "Hiragino Sans GB", STHeiti; } .sign { @@ -72,7 +73,7 @@ body { .cell { .border-radius(4px); - .box-shadow(0px 0px 2px #BBB); + .box-shadow(0px 1px 2px rgba(0, 0, 0, 0.15)); border: 2px solid #EEE; margin-bottom: 30px; background-color: white; @@ -108,6 +109,7 @@ body { /* Navigator Style */ nav { + .box-shadow(0px 0px 5px black); color: white; background: #2B2B2B; background-image: url(@bg-sidebar); @@ -200,10 +202,11 @@ nav { } .copyright { + .center-block; font-size: 10px; text-shadow: black 0px 1px 1px; padding-top: 20px; - padding-left: 14px; + width: @sidebarWidth - 28px; a { color: white; diff --git a/static/css/style.css b/static/css/style.css index 261f879..e9e3d03 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3687,6 +3687,7 @@ a.thumbnail:hover { /* Signin & Signup Page Style */ body { background: url("/static/img/bg-noise.jpg"); + font-family: "Helvetica Neue", "Luxi Sans", "DejaVu Sans", Tahoma, "Hiragino Sans GB", STHeiti; } .sign { margin: 0; @@ -3751,9 +3752,9 @@ body { -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; - -webkit-box-shadow: 0px 0px 2px #bbbbbb; - -moz-box-shadow: 0px 0px 2px #bbbbbb; - box-shadow: 0px 0px 2px #bbbbbb; + -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15); + box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15); border: 2px solid #EEE; margin-bottom: 30px; background-color: white; @@ -3784,6 +3785,9 @@ body { } /* Navigator Style */ nav { + -webkit-box-shadow: 0px 0px 5px #000000; + -moz-box-shadow: 0px 0px 5px #000000; + box-shadow: 0px 0px 5px #000000; color: white; background: #2B2B2B; background-image: url("/static/img/lines.jpg"); @@ -3880,10 +3884,13 @@ nav .sep { border-top: 1px solid #1D1E21; } nav .copyright { + display: block; + margin-left: auto; + margin-right: auto; font-size: 10px; text-shadow: black 0px 1px 1px; padding-top: 20px; - padding-left: 14px; + width: 212px; } nav .copyright a { color: white; From 07cbae7427232f720eb27936a3cc71270b834a47 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Tue, 13 Mar 2012 16:32:34 +0800 Subject: [PATCH 13/56] finish sign in & sign up & sign out --- handlers.py | 3 ++- home.py | 8 +++++- judge/base/__init__.py | 33 ++++++++++++++++++++++- judge/db/__init__.py | 47 ++++++++++++++++++++++++++++++-- less/style.less | 17 +++++++++--- member.py | 61 ++++++++++++++++++++++++++++++++++++++++-- static/css/style.css | 11 +++++--- tpl/signin.html | 2 +- tpl/signup.html | 2 +- 9 files changed, 168 insertions(+), 16 deletions(-) diff --git a/handlers.py b/handlers.py index 46893fa..caf2467 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 03:10:54 09/03/2012 +# MODIFIED: 16:27:22 13/03/2012 # DESCRIPTION: URL Route from home import * @@ -17,5 +17,6 @@ (r'/', HomeHandler), (r'/signin', SigninHandler), (r'/signup', SignupHandler), + (r'/signout', SignoutHandler), (r'/lang/(.*)', SetLanguageHandler), ] diff --git a/home.py b/home.py index 6dc41b2..cf5b23b 100644 --- a/home.py +++ b/home.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: home.py # CREATED: 02:00:16 08/03/2012 -# MODIFIED: 03:06:43 08/03/2012 +# MODIFIED: 19:38:23 10/03/2012 # DESCRIPTION: Home handler from judge.base import BaseHandler @@ -12,6 +12,12 @@ def get(self): title = self._("Home") breadcrumb = [] breadcrumb.append((self._("Home"), "/")) + latest_problem = [] + latest_contest = [] + latest_topic = [] + count_problem = 0 + count_topic = 0 + count_member = 0 self.render("home.html", locals()) __all__ = ["HomeHandler"] diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 7767aa8..44c540b 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,9 +2,11 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 02:44:38 09/03/2012 +# MODIFIED: 16:12:25 13/03/2012 # DESCRIPTION: Base handler +import re +import hashlib import httplib import functools import traceback @@ -64,6 +66,35 @@ def write_error(self, status_code, **kwargs): return msg = httplib.responses[status_code] self.render("error.html", locals()) + @staticmethod + def check_text_value(value, valName, max = 65535, min = 0, regex = None, regex_msg = None): + ''' Common Check Text Value Function ''' + return [] + def check_username(self, usr, queryDB = False): + error = [] + error.extend(self.check_text_value(usr, self._("Username"), max = 20, min = 3, \ + regex = re.compile(r'^([\w\d]*)$'), \ + regex_msg = self._("A username can only contain letters and digits."))) + if not error and queryDB: + query = self.select_member_by_username_lower(usr.lower()) + if query: + error.append(self._("That username is taken. Please choose another.")) + return error + def check_password(self, pwd): + return self.check_text_value(pwd, self._("Password"), max = 32, min = 6) + def check_email(self, email, queryDB = False): + error = [] + error.extend(self.check_text_value(email, self._("E-mail"), max = 100, min = 3, \ + regex = re.compile(r"(?:^|\s)[-a-z0-9_.+]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}(?:\s|$)", re.IGNORECASE), \ + regex_msg = self._("Your Email address is invalid."))) + if not error and queryDB: + query = self.select_member_by_email(email) + if query: + error.append(self._("That Email is taken. Please choose another.")) + return error + def get_gravatar_url(self, email): + gravatar_id = hashlib.md5(email.lower()).hexdigest() + return "http://www.gravatar.com/avatar/%s?d=mm" % (gravatar_id) @property def db(self): return self.application.db diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 8e85ab0..58eb2cb 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,9 +2,12 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 02:29:52 08/03/2012 +# MODIFIED: 16:17:30 13/03/2012 # DESCRIPTION: Database Table Object +import uuid +import binascii + from judge.base import BaseDBMixin from judge.base import BaseDBObject @@ -45,7 +48,47 @@ class ResetMail(BaseDBObject): create = None class MemberDBMixin(BaseDBMixin): - pass + ''' New Data Model ''' + def _new_member(self, row): + member = Member() + member._init_row(row) + return member + ''' SELECT ''' + def select_member_by_username_lower(self, username_lower): + row = self.db.get("""SELECT * FROM `member` WHERE `username_lower` = %s LIMIT 1""", username_lower) + if row: + return self._new_member(row) + return None + def select_member_by_email(self, email): + row = self.db.get("""SELECT * FROM `member` WHERE `email` = %s LIMIT 1""", email) + if row: + return self._new_member(row) + return None + def select_member_by_usr_pwd(self, usr, pwd): + row = self.db.get("""SELECT * FROM `member` WHERE `username` = %s AND `password` = %s LIMIT 1""", usr, pwd) + if row: + return self._new_member(row) + return None + ''' INSERT ''' + def insert_member(self, member): + member.id = self.db.execute("""INSERT INTO `member` (`username`, `username_lower`, `password`, `email`, + `gravatar_link`, `create`, `website`, `tagline`, `bio`, + `admin`, `lang`) + VALUES (%s, %s, %s, %s, %s, UTC_TIMESTAMP(), %s, %s, %s, %s, %s)""", \ + member.username, member.username_lower, member.passowrd, member.email, member.gravatar_link, \ + member.website, member.tagline, member.bio, member.admin, member.lang) + def insert_auth(self, member_id, random): + self.db.execute("""INSERT INTO `auth` (`member_id`, `secret`, `create`) VALUES (%s, %s, UTC_TIMESTAMP())""", \ + member_id, random) + auth = Auth() + auth.member_id = member_id + auth.secret = random + return auth + ''' OTHER ''' + def create_auth(self, member_id): + random = binascii.b2a_hex(uuid.uuid4().bytes) + return self.insert_auth(member_id, random) + ''' '' =================================== diff --git a/less/style.less b/less/style.less index e2de5c0..272d57e 100644 --- a/less/style.less +++ b/less/style.less @@ -2,6 +2,17 @@ @import "vars.less"; @import "bootstrap/bootstrap.less"; +/* Mixins */ + +.top-border-radius(@radius) { + -webkit-border-top-left-radius: @radius; + -webkit-border-top-right-radius: @radius; + -moz-border-radius-topleft: @radius; + -moz-border-radius-topright: @radius; + border-top-left-radius: @radius; + border-top-right-radius: @radius; +} + /* Signin & Signup Page Style */ body { @@ -78,11 +89,8 @@ body { margin-bottom: 30px; background-color: white; - &.span8 { - width: 64.95744680199999%; - } - .title { + .top-border-radius(4px); font-size: 16px; font-weight: bold; line-height: 30px; @@ -226,6 +234,7 @@ nav { th { color: fade(black, 30); + font-size: 11px; font-weight: normal; text-align: right; } diff --git a/member.py b/member.py index bfa2f90..be052a0 100644 --- a/member.py +++ b/member.py @@ -2,11 +2,13 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 03:10:44 09/03/2012 +# MODIFIED: 16:25:52 13/03/2012 # DESCRIPTION: member handlers import re +import bcrypt +from judge.db import Member from judge.db import MemberDBMixin from judge.base import BaseHandler from judge.base import unauthenticated @@ -15,10 +17,65 @@ class SigninHandler(BaseHandler, MemberDBMixin): @unauthenticated def get(self): self.render("signin.html", locals()) + @unauthenticated + def post(self): + usr = self.get_argument("usr", default = None) + pwd = self.get_argument("pwd", default = None) + error = [] + error.extend(self.check_username(usr.lower())) + error.extend(self.check_password(pwd)) + pwd = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) + member = self.select_member_by_usr_pwd(usr, pwd) + if not member: + error.append(self._("Wrong Username and password combination.")) + if error: + self.render("signin.html", locals()) + return + auth = self.create_auth(member.id) + self.set_secure_cookie("auth", auth.secret) + self.set_secure_cookie("uid", str(auth.member_id)) + go_next = self.get_argument("next", default = None) + if go_next: + self.redirect(go_next) + return + self.redirect("/") class SignupHandler(BaseHandler, MemberDBMixin): @unauthenticated def get(self): self.render("signup.html", locals()) + @unauthenticated + def post(self): + self.require_setting('bcrypt_salt', 'bcrypt for Password') + usr = self.get_argument("usr", default = None) + pwd = self.get_argument("pwd", default = None) + email = self.get_argument("email", default = None) + error = [] + error.extend(self.check_username(usr.lower(), queryDB = True)) + error.extend(self.check_password(pwd)) + error.extend(self.check_email(email, queryDB = True)) + if error: + self.render("signup.html", locals()) + return + member = Member() + member.username = usr + member.username_lower = usr.lower() + member.passowrd = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) + member.email = email + member.gravatar_link = self.get_gravatar_url(email) + self.insert_member(member) + auth = self.create_auth(member.id) + self.set_secure_cookie('auth', auth.secret) + self.set_secure_cookie('uid', str(auth.member_id)) + self.redirect('/') + +class SignoutHandler(BaseHandler, MemberDBMixin): + @authenticated + def get(self): + auth = self.get_secure_cookie('auth') + self.delete_auth_by_secret(auth) + self.clear_cookie('auth') + self.clear_cookie('uid') + self.redirect('/') -__all__ = ["SigninHandler", "SignupHandler"] +__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler"] diff --git a/static/css/style.css b/static/css/style.css index e9e3d03..0fe5f22 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3684,6 +3684,7 @@ a.thumbnail:hover { .invisible { visibility: hidden; } +/* Mixins */ /* Signin & Signup Page Style */ body { background: url("/static/img/bg-noise.jpg"); @@ -3759,10 +3760,13 @@ body { margin-bottom: 30px; background-color: white; } -.cell.span8 { - width: 64.95744680199999%; -} .cell .title { + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; font-size: 16px; font-weight: bold; line-height: 30px; @@ -3902,6 +3906,7 @@ nav .copyright a { } #count .table tr th { color: rgba(0, 0, 0, 0.3); + font-size: 12px; font-weight: normal; text-align: right; } diff --git a/tpl/signin.html b/tpl/signin.html index 8056191..edc663f 100644 --- a/tpl/signin.html +++ b/tpl/signin.html @@ -2,7 +2,7 @@ - {{ page.settings['site_title'] }} + {{ _('Sign In') }} - {{ page.settings['site_title'] }} diff --git a/tpl/signup.html b/tpl/signup.html index b0d1b95..2a71141 100644 --- a/tpl/signup.html +++ b/tpl/signup.html @@ -2,7 +2,7 @@ - {{ page.settings['site_title'] }} + {{ _('Sign Up') }} - {{ page.settings['site_title'] }} From f40cb456ba84ea31e31ecf43a05f8a44786258e1 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 15 Mar 2012 02:43:25 +0800 Subject: [PATCH 14/56] finish member system --- judge/__init__.py | 3 ++ judge/base/__init__.py | 80 +++++++++++++++++++++++++++-------------- judge/db/__init__.py | 24 +++++++++++-- judge/utils/__init__.py | 10 ++++++ less/style.less | 18 ++++++++++ member.py | 22 +++++++----- static/css/style.css | 18 +++++++++- tpl/base/sidebar.html | 11 +++--- tpl/signup.html | 2 +- 9 files changed, 143 insertions(+), 45 deletions(-) create mode 100644 judge/utils/__init__.py diff --git a/judge/__init__.py b/judge/__init__.py index e69de29..faaaf79 100644 --- a/judge/__init__.py +++ b/judge/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + + diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 44c540b..e78e669 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,18 +2,23 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 16:12:25 13/03/2012 +# MODIFIED: 02:29:10 15/03/2012 # DESCRIPTION: Base handler import re import hashlib import httplib +import datetime import functools import traceback import tornado.web import tornado.escape +from judge.db import Member +from judge.utils import _len + + def unauthenticated(method): """Decorate methods with this to require that user be NOT logged in""" @functools.wraps(method) @@ -37,7 +42,33 @@ def get_page_num(self): pass def get_current_user(self): '''Check user is logined''' - pass + auth = self.get_secure_cookie("auth") + uid = self.get_secure_cookie("uid") + member = None + if auth and uid: + auth = self.db.get("""SELECT * FROM `auth` WHERE `secret` = %s AND `member_id` = %s LIMIT 1""", auth, uid) + if auth: + member = Member() + query = self.db.get("""SELECT * FROM `member` WHERE `id` = %s LIMIT 1""", auth["member_id"]) + if query: + member._init_row(query) + delta = auth['create'] - datetime.datetime.now() + if delta.days > 20: + """ Refresh Token """ + sql = """DELETE FROM `auth` WHERE `secret` = '%s' LIMIT 1""" \ + % auth + self.db.execute(sql) + random = binascii.b2a_hex(uuid.uuid4().bytes) + sql = """INSERT INTO `auth` (`uid`, `secret`, `create`) \ + VALUES ('%d', '%s', UTC_TIMESTAMP())""" \ + % (uid, random) + self.db.execute(sql) + self.set_cookie('auth', random) + self.set_cookie('uid', str(uid)) + else: + self.clear_cookie("auth") + self.clear_cookie("uid") + return member def get_user_locale(self): '''Get user locale, first check cookie, then browser''' pass @@ -66,13 +97,27 @@ def write_error(self, status_code, **kwargs): return msg = httplib.responses[status_code] self.render("error.html", locals()) - @staticmethod - def check_text_value(value, valName, max = 65535, min = 0, regex = None, regex_msg = None): + def check_text_value(self, value, valName, required = False, max = 65535, min = 0, regex = None, regex_msg = None): ''' Common Check Text Value Function ''' - return [] + error = [] + if not value: + if required: + error.append(self._("%s is required" % valName)) + return error + if _len(value) > max: + error.append(self._("%s is too long." % valName)) + elif _len(value) < min: + error.append(self._("%s is too short." % valName)) + if regex: + if not regex.match(value): + if regex_msg: + error.append(regex_msg) + else: + error.append(self._("%s is invalid." % valName)) + return error def check_username(self, usr, queryDB = False): error = [] - error.extend(self.check_text_value(usr, self._("Username"), max = 20, min = 3, \ + error.extend(self.check_text_value(usr, self._("Username"), required = True, max = 20, min = 3, \ regex = re.compile(r'^([\w\d]*)$'), \ regex_msg = self._("A username can only contain letters and digits."))) if not error and queryDB: @@ -81,10 +126,10 @@ def check_username(self, usr, queryDB = False): error.append(self._("That username is taken. Please choose another.")) return error def check_password(self, pwd): - return self.check_text_value(pwd, self._("Password"), max = 32, min = 6) + return self.check_text_value(pwd, self._("Password"), required = True, max = 32, min = 6) def check_email(self, email, queryDB = False): error = [] - error.extend(self.check_text_value(email, self._("E-mail"), max = 100, min = 3, \ + error.extend(self.check_text_value(email, self._("E-mail"), required = True, max = 100, min = 3, \ regex = re.compile(r"(?:^|\s)[-a-z0-9_.+]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}(?:\s|$)", re.IGNORECASE), \ regex_msg = self._("Your Email address is invalid."))) if not error and queryDB: @@ -101,22 +146,3 @@ def db(self): @property def jinja2(self): return self.application.jinja2 - -class BaseDBObject(object): - ''' Base Table Object ''' - def __repr__(self): - ''' for debug ''' - result = ", \n".join(["'%s': '%s'" % (attr, getattr(self, attr)) for attr in dir(self) if attr[0] != '_' and not callable(getattr(self, attr)) ]) - return "<{%s}>" % result - def _init_row(self, row): - keys = row.keys() - for key in keys: - setattr(self, key, row[key]) - -class BaseDBMixin(object): - ''' Base Database Mixin ''' - def _new_object_by_row(self, Obj, row): - obj = Obj() - obj._init_row(row) - return obj - diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 58eb2cb..5d74f9f 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,14 +2,29 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 16:17:30 13/03/2012 +# MODIFIED: 02:39:32 15/03/2012 # DESCRIPTION: Database Table Object import uuid import binascii -from judge.base import BaseDBMixin -from judge.base import BaseDBObject +class BaseDBObject(object): + ''' Base Table Object ''' + def __repr__(self): + ''' for debug ''' + result = ", \n".join(["'%s': '%s'" % (attr, getattr(self, attr)) for attr in dir(self) if attr[0] != '_' and not callable(getattr(self, attr)) ]) + return "<{%s}>" % result + def _init_row(self, row): + keys = row.keys() + for key in keys: + setattr(self, key, row[key]) + +class BaseDBMixin(object): + ''' Base Database Mixin ''' + def _new_object_by_row(self, Obj, row): + obj = Obj() + obj._init_row(row) + return obj ''' '' =================================== @@ -84,6 +99,9 @@ def insert_auth(self, member_id, random): auth.member_id = member_id auth.secret = random return auth + ''' DELETE ''' + def delete_auth_by_secret(self, secret): + self.db.execute("""DELETE FROM `auth` WHERE `secret` = %s""", secret) ''' OTHER ''' def create_auth(self, member_id): random = binascii.b2a_hex(uuid.uuid4().bytes) diff --git a/judge/utils/__init__.py b/judge/utils/__init__.py new file mode 100644 index 0000000..8334b98 --- /dev/null +++ b/judge/utils/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: judge/utils/__init__.py +# CREATED: 02:09:10 15/03/2012 +# MODIFIED: 02:10:04 15/03/2012 + +def _len(text): + if isinstance(text, str): + text = text.decode('utf-8') + return len(text) diff --git a/less/style.less b/less/style.less index 272d57e..578efd4 100644 --- a/less/style.less +++ b/less/style.less @@ -63,6 +63,9 @@ body { } } } + .alert ul { + margin-bottom: 0; + } } /* Common Page Style */ @@ -72,6 +75,17 @@ body { margin-bottom: @bottomBlank; } +::selection { + color: rgba(255, 255, 255, .75); + background: rgba(0, 0, 0, .5); + text-shadow: none; +} +::-moz-selection { + color: rgba(255, 255, 255, .75); + background: rgba(0, 0, 0, .5); + text-shadow: none; +} + .main { padding-top: 40px; padding-right: 20px; @@ -145,6 +159,10 @@ nav { font-family: Arial, sans-serif; font-size: 14px; text-shadow: black 0px 1px 1px; + + a { + color: white; + } } .tagline { diff --git a/member.py b/member.py index be052a0..1895cd4 100644 --- a/member.py +++ b/member.py @@ -2,12 +2,14 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 16:25:52 13/03/2012 +# MODIFIED: 02:10:17 15/03/2012 # DESCRIPTION: member handlers import re import bcrypt +from tornado.web import authenticated + from judge.db import Member from judge.db import MemberDBMixin from judge.base import BaseHandler @@ -19,15 +21,17 @@ def get(self): self.render("signin.html", locals()) @unauthenticated def post(self): - usr = self.get_argument("usr", default = None) - pwd = self.get_argument("pwd", default = None) + usr = self.get_argument("usr", default = "") + pwd = self.get_argument("pwd", default = "") error = [] error.extend(self.check_username(usr.lower())) error.extend(self.check_password(pwd)) + pwd = pwd.encode("utf-8") pwd = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) - member = self.select_member_by_usr_pwd(usr, pwd) - if not member: - error.append(self._("Wrong Username and password combination.")) + if not error: + member = self.select_member_by_usr_pwd(usr, pwd) + if not member: + error.append(self._("Wrong Username and password combination.")) if error: self.render("signin.html", locals()) return @@ -47,9 +51,9 @@ def get(self): @unauthenticated def post(self): self.require_setting('bcrypt_salt', 'bcrypt for Password') - usr = self.get_argument("usr", default = None) - pwd = self.get_argument("pwd", default = None) - email = self.get_argument("email", default = None) + usr = self.get_argument("usr", default = "") + pwd = self.get_argument("pwd", default = "") + email = self.get_argument("email", default = "") error = [] error.extend(self.check_username(usr.lower(), queryDB = True)) error.extend(self.check_password(pwd)) diff --git a/static/css/style.css b/static/css/style.css index 0fe5f22..933baf9 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3736,11 +3736,24 @@ body { height: 26px; line-height: 26px; } +.sign .alert ul { + margin-bottom: 0; +} /* Common Page Style */ body { margin-left: 260px; margin-bottom: 20px; } +::selection { + color: rgba(255, 255, 255, 0.75); + background: rgba(0, 0, 0, 0.5); + text-shadow: none; +} +::-moz-selection { + color: rgba(255, 255, 255, 0.75); + background: rgba(0, 0, 0, 0.5); + text-shadow: none; +} .main { padding-top: 40px; padding-right: 20px; @@ -3820,6 +3833,9 @@ nav .profile .profile_wrap .username { font-size: 14px; text-shadow: black 0px 1px 1px; } +nav .profile .profile_wrap .username a { + color: white; +} nav .profile .profile_wrap .tagline { position: absolute; top: 40px; @@ -3906,7 +3922,7 @@ nav .copyright a { } #count .table tr th { color: rgba(0, 0, 0, 0.3); - font-size: 12px; + font-size: 11px; font-weight: normal; text-align: right; } diff --git a/tpl/base/sidebar.html b/tpl/base/sidebar.html index 4682e87..6eb718b 100644 --- a/tpl/base/sidebar.html +++ b/tpl/base/sidebar.html @@ -6,18 +6,21 @@ {{ user['tagline'] }} {% else %} Guest + {% endif %}
    • ~Nbx@I`&~$@zx`w!Uoca@d}QA4 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%0AqWFXi}Jf92>9a2uQcJw0X=B_fwG@6)tl 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 ALjV8( literal 0 HcmV?d00001 diff --git a/tpl/404.html b/tpl/404.html new file mode 100644 index 0000000..363f33a --- /dev/null +++ b/tpl/404.html @@ -0,0 +1,35 @@ + + + + + Error 404(Not Found)!!1 + + + +

      diff --git a/tpl/signup.html b/tpl/signup.html index 2a71141..866c594 100644 --- a/tpl/signup.html +++ b/tpl/signup.html @@ -37,7 +37,7 @@
      - +
      From 553ea1e0142e4cb41b393511e3bb2a6d855408cc Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 15 Mar 2012 04:03:49 +0800 Subject: [PATCH 15/56] finish add problem --- backstage.py | 88 ++++++++++++++++++++++++++++++++ handlers.py | 4 +- judge/base/__init__.py | 16 +++++- judge/db/__init__.py | 50 +++++++++++++++++- less/style.less | 30 ++++++++++- static/css/style.css | 28 ++++++++++- tpl/backstage/add_problem.html | 92 ++++++++++++++++++++++++++++++++++ tpl/form.html | 0 tpl/macros.html | 49 ++++++++++++++++++ 9 files changed, 350 insertions(+), 7 deletions(-) create mode 100644 backstage.py create mode 100644 tpl/backstage/add_problem.html create mode 100644 tpl/form.html diff --git a/backstage.py b/backstage.py new file mode 100644 index 0000000..70d3564 --- /dev/null +++ b/backstage.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: backstage.py +# CREATED: 02:43:49 15/03/2012 +# MODIFIED: 04:03:09 15/03/2012 + +import functools + +from tornado.web import HTTPError + +from judge.db import Problem +from judge.db import ProblemDBMixin +from judge.base import BaseHandler + +def backstage(method): + """Decorate methods with this to require that user be NOT logged in""" + @functools.wraps(method) + def wrapper(self, *args, **kwargs): + if self.current_user: + if self.current_user.admin: + return method(self, *args, **kwargs) + raise HTTPError(404) + return wrapper + +class AddProblemHandler(BaseHandler, ProblemDBMixin): + @backstage + def get(self): + title = self._("Add Problem") + pid = self.get_argument("pid", default = None) + problem = None + if pid: + title = self._("Edit Problem") + problem = self.select_problem_by_id(pid) + if not problem: + raise HTTPError(404) + problem.content = self.xhtml_escape(problem.content) + tagquery = self.select_problem_tag_by_problem_id(problem.id) + tags = [] + for tag in tagquery: + tags.append(tag.tagname) + self.render("backstage/add_problem.html", locals()) + @backstage + def post(self): + probtitle = self.get_argument('probtitle', default = None) + shortname = self.get_argument('shortname', default = None) + timelimit = self.get_argument('timelimit', default = 1000) + memlimit = self.get_argument('memlimit', default = 128) + testpoint = self.get_argument('testpoint', default = None) + invisible = self.get_argument('invisible', default = 0) + content = self.get_argument('content', default = None) + pid = self.get_argument('pid', default = 0) + tags = self.get_arguments('tags[]') + tags = map(self.xhtml_escape, tags) + problem = Problem() + error = [] + error.extend(self.check_text_value(probtitle, self._("Title"), required = True)) + error.extend(self.check_text_value(shortname, self._("Short Name"), required = True)) + error.extend(self.check_text_value(timelimit, self._("Time Limit"), required = True, is_num = True)) + error.extend(self.check_text_value(memlimit, self._("Memory Limit"), required = True, is_num = True)) + error.extend(self.check_text_value(testpoint, self._("Testpoint"), required = True, is_num = True)) + error.extend(self.check_text_value(invisible, self._("Invisible"), is_num = True, vaild = [0, 1])) + error.extend(self.check_text_value(content, self._("Content"), max = 1000000, required = True)) + error.extend(self.check_text_value(testpoint, self._("Test Point"), required = True)) + problem.id = int(pid) + problem.title = self.xhtml_escape(probtitle) + problem.shortname = self.xhtml_escape(shortname) + problem.timelimit = self.xhtml_escape(timelimit) + problem.memlimit = self.xhtml_escape(memlimit) + problem.testpoint = self.xhtml_escape(testpoint) + problem.invisible = self.xhtml_escape(invisible) + if error: + problem.content = self.xhtml_escape(content) + title = self._("Edit Problem") + self.render("backstage/add_problem.html", locals()) + return + problem.content = content + if problem.id: + self.update_problem(problem) + self.delete_problem_tag_by_problem_id(problem.id) + else: + self.insert_problem(problem) + for tag in tags: + self.insert_problem_tag(tag, problem.id) + self.redirect('/problem/%d' % problem.id) + + + +__all__ = ["AddProblemHandler"] diff --git a/handlers.py b/handlers.py index caf2467..f0e2db8 100644 --- a/handlers.py +++ b/handlers.py @@ -2,12 +2,13 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 16:27:22 13/03/2012 +# MODIFIED: 02:52:56 15/03/2012 # DESCRIPTION: URL Route from home import * from lang import * from member import * +from backstage import * ''' '' Handler 命名规范: [动宾结构 / 名词] + Handler @@ -19,4 +20,5 @@ (r'/signup', SignupHandler), (r'/signout', SignoutHandler), (r'/lang/(.*)', SetLanguageHandler), + (r'/backstage/problem/add', AddProblemHandler), ] diff --git a/judge/base/__init__.py b/judge/base/__init__.py index e78e669..f502ad7 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 02:29:10 15/03/2012 +# MODIFIED: 04:02:16 15/03/2012 # DESCRIPTION: Base handler import re @@ -97,13 +97,22 @@ def write_error(self, status_code, **kwargs): return msg = httplib.responses[status_code] self.render("error.html", locals()) - def check_text_value(self, value, valName, required = False, max = 65535, min = 0, regex = None, regex_msg = None): + def check_text_value(self, value, valName, required = False, max = 65535, min = 0, regex = None, regex_msg = None, is_num = False, vaild = []): ''' Common Check Text Value Function ''' error = [] if not value: if required: error.append(self._("%s is required" % valName)) return error + if is_num: + try: + tmp = int(value) + except ValueError: + return [self._("%s must be a number." % valName)] + else: + if vaild and tmp not in vaild: + return [self._("%s is invalid." % valName)] + return [] if _len(value) > max: error.append(self._("%s is too long." % valName)) elif _len(value) < min: @@ -114,6 +123,9 @@ def check_text_value(self, value, valName, required = False, max = 65535, min = error.append(regex_msg) else: error.append(self._("%s is invalid." % valName)) + else: + if vaild and value not in vaild: + errora.append(self._("%s is invalid." % valName)) return error def check_username(self, usr, queryDB = False): error = [] diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 5d74f9f..30f9316 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 02:39:32 15/03/2012 +# MODIFIED: 04:00:13 15/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -213,7 +213,53 @@ class Submit(BaseDBObject): create = 0 class ProblemDBMixin(BaseDBMixin): - pass + ''' New Data Model ''' + def _new_problem(self, row): + problem = Problem() + problem._init_row(row) + return problem + def _new_problem_tag(self, row): + problem_tag = ProblemTag() + problem_tag._init_row(row) + return problem_tag + ''' SELECT ''' + def select_problem_by_id(self, id): + row = self.db.get("""SELECT * FROM `problem` WHERE `id` = %s LIMIT 1""", id) + if row: + return self._new_problem(row) + return None + def select_problem_tag_by_problem_id(self, problem_id): + rows = self.db.query("""SELECT * FROM `problem_tag` WHERE `problem_id` = %s""", problem_id) + result = [] + for row in rows: + result.append(self._new_problem_tag(row)) + return result + ''' INSERT ''' + def insert_problem(self, problem): + problem.id = self.db.execute("""INSERT INTO `problem` (`title`, `shortname`, `content`, \ + `timelimit`, `memlimit`, `testpoint`, `invisible`, `create`) \ + VALUES (%s, %s, %s, %s, %s, %s, %s, UTC_TIMESTAMP())""" \ + , problem.title, problem.shortname, problem.content, \ + int(problem.timelimit), int(problem.memlimit), int(problem.testpoint), int(problem.invisible)) + def insert_problem_tag(self, tagname, problem_id): + self.db.execute("""INSERT INTO `problem_tag` (`tagname`, `problem_id`) VAlUES (%s, %s)""", tagname, int(problem_id)) + ''' UPDATE ''' + def update_problem(self, problem): + self.db.execute("""UPDATE `problem` SET `title` = %s, + `shortname` = %s, + `content` = %s, + `timelimit` = %s, + `memlimit` = %s, + `testpoint` = %s, + `invisible` = %s + WHERE `id` = %s""", \ + problem.title, problem.shortname, problem.content, \ + int(problem.timelimit), int(problem.memlimit), int(problem.testpoint), int(problem.invisible), \ + problem.id) + ''' DELETE ''' + def delete_problem_tag_by_problem_id(self, problem_id): + self.db.execute("""DELETE FROM `problem_tag` WHERE `problem_id` = %s""", int(problem_id)) + ''' OTHER ''' ''' '' =================================== diff --git a/less/style.less b/less/style.less index 578efd4..703f7b4 100644 --- a/less/style.less +++ b/less/style.less @@ -103,7 +103,7 @@ body { margin-bottom: 30px; background-color: white; - .title { + .title, legend { .top-border-radius(4px); font-size: 16px; font-weight: bold; @@ -111,6 +111,11 @@ body { padding-left: 10px; padding-top: 5px; border-bottom: 1px solid #DDD; + } + + legend { + padding-left: 20px; + padding-top: 20px; } .table { @@ -126,6 +131,29 @@ body { line-height: 30px; } } + + .form-actions { + margin-bottom: 0; + } +} + +.tagclound { + list-style: none; + margin-left: 0; + margin-top: 10px; + + .tag { + .border-radius(4px); + background-color: #EEE; + padding: 4px 4px 2px 10px; + float: left; + margin-right: 4px; + margin-bottom: 5px; + + a { + color: black; + } + } } /* Navigator Style */ diff --git a/static/css/style.css b/static/css/style.css index 933baf9..8b29375 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3773,7 +3773,8 @@ body { margin-bottom: 30px; background-color: white; } -.cell .title { +.cell .title, +.cell legend { -webkit-border-top-left-radius: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-topleft: 4px; @@ -3787,6 +3788,10 @@ body { padding-top: 5px; border-bottom: 1px solid #DDD; } +.cell legend { + padding-left: 20px; + padding-top: 20px; +} .cell .table { -webkit-border-radius: 0px; -moz-border-radius: 0px; @@ -3800,6 +3805,27 @@ body { .cell .content p { line-height: 30px; } +.cell .form-actions { + margin-bottom: 0; +} +.tagclound { + list-style: none; + margin-left: 0; + margin-top: 10px; +} +.tagclound .tag { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + background-color: #EEE; + padding: 4px 4px 2px 10px; + float: left; + margin-right: 4px; + margin-bottom: 5px; +} +.tagclound .tag a { + color: black; +} /* Navigator Style */ nav { -webkit-box-shadow: 0px 0px 5px #000000; diff --git a/tpl/backstage/add_problem.html b/tpl/backstage/add_problem.html new file mode 100644 index 0000000..4ed31aa --- /dev/null +++ b/tpl/backstage/add_problem.html @@ -0,0 +1,92 @@ +{% extends "base.html" %} +{% from "macros.html" import input %} +{% from "macros.html" import checkbox %} +{% from "macros.html" import textarea %} +{% from "macros.html" import form_actions %} +{% from "macros.html" import show_error_list %} + +{% block body %} +{{ show_error_list(error) }} +
      +
      + {{ _('Add Problem') }} + {{ page.xsrf_form_html() }} + +
      + {{ input('probtitle', _('Title'), value=problem.title) }} + {{ input('shortname', _('Short Name'), value=problem.shortname) }} + {{ input('timelimit', _('Time Limit'), value=problem.timelimit, class="span1", default="1000", addon="ms") }} + {{ input('memlimit', _('Memory Limit'), value=problem.memlimit, class="span1", default="128", addon="MB") }} + {{ input('testpoint', _('Test Point'), value=problem.testpoint, class="span1") }} + {{ checkbox('invisible', _('Invisible'), checked=problem.invisible) }} + {{ textarea('content', _('Content'), value=problem.content, style="width:522px; height: 427px; ") }} +
      + +
      + + {{ _('Add') }} +
        + {% if tags %} + {% for tag in tags %} +
      • + {{ tag }} + +
      • + {% endfor%} + {% endif %} +
      +
      +
      + {{ form_actions(submit = _('Submit')) }} +
      +{% if tags %} +{% for tag in tags %} + +{% endfor %} +{% endif %} +
      + +{% endblock %} diff --git a/tpl/form.html b/tpl/form.html new file mode 100644 index 0000000..e69de29 diff --git a/tpl/macros.html b/tpl/macros.html index f319eab..f3f4e1c 100644 --- a/tpl/macros.html +++ b/tpl/macros.html @@ -1,3 +1,15 @@ +{% macro show_error_list(error) %} +{%- if error -%} +
      +
        +{% for err in error %} +
      • {{ err }}
      • +{% endfor %} +
      +
      +{% endif %} +{% endmacro %} + {% macro show_problem_list(problem_list) %} @@ -22,3 +34,40 @@ {% macro show_contest_list(contest_list) %} {% endmacro %} + +{#================ Form ================#} + +{% macro input(name, label, value = '', type = 'TEXT', class = 'input-xlarge', default = '', addon = '') %} +
      + +
      + {% if addon %}
      {% endif %} + + {% if addon %}{{ addon }}
      {% endif %} +
      +
      +{% endmacro %} + +{% macro checkbox(name, label, checked = 0) %} +
      + +
      + +
      +
      +{% endmacro %} + +{% macro textarea(name, label, value = '', class = 'input-xlarge', style = '') %} +
      + +
      + +
      +
      +{% endmacro %} + +{% macro form_actions(submit) %} +
      + +
      +{% endmacro %} From 211db7a09cffb722be3a851bd3e50c7f1ec5004f Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 15 Mar 2012 04:49:38 +0800 Subject: [PATCH 16/56] finish problem style & logic --- handlers.py | 4 +- judge/filters/__init__.py | 53 ++++++++++++++++++++- less/style.less | 49 ++++++++++++++++--- problem.py | 32 +++++++++++++ static/css/style.css | 32 +++++++++++-- tpl/backstage/add_problem.html | 2 +- tpl/problem.html | 86 ++++++++++++++++++++++++++++++++++ 7 files changed, 244 insertions(+), 14 deletions(-) create mode 100644 problem.py create mode 100644 tpl/problem.html diff --git a/handlers.py b/handlers.py index f0e2db8..958f642 100644 --- a/handlers.py +++ b/handlers.py @@ -2,12 +2,13 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 02:52:56 15/03/2012 +# MODIFIED: 04:09:12 15/03/2012 # DESCRIPTION: URL Route from home import * from lang import * from member import * +from problem import * from backstage import * ''' @@ -20,5 +21,6 @@ (r'/signup', SignupHandler), (r'/signout', SignoutHandler), (r'/lang/(.*)', SetLanguageHandler), + (r'/problem/([\d]*)', ViewProblemHandler), (r'/backstage/problem/add', AddProblemHandler), ] diff --git a/judge/filters/__init__.py b/judge/filters/__init__.py index 3c75492..6f90f41 100644 --- a/judge/filters/__init__.py +++ b/judge/filters/__init__.py @@ -2,12 +2,63 @@ # AUTHOR: Zeray Rice # FILE: judge/filters/__init__.py # CREATED: 01:48:10 08/03/2012 -# MODIFIED: 04:06:44 09/03/2012 +# MODIFIED: 04:25:41 15/03/2012 # DESCRIPTION: jinja2 filters +import re +import string + +# Configuration for urlize() function +LEADING_PUNCTUATION = ['(', '<', '<'] +TRAILING_PUNCTUATION = ['.', ',', ')', '>', '\n', '>'] + +# list of possible strings used for bullets in bulleted lists +DOTS = ['·', '*', '\xe2\x80\xa2', '•', '•', '•'] + +word_split_re = re.compile(r'(\s+)') +punctuation_re = re.compile('^(?P(?:%s)*)(?P.*?)(?P(?:%s)*)$' % \ + ('|'.join([re.escape(x) for x in LEADING_PUNCTUATION]), + '|'.join([re.escape(x) for x in TRAILING_PUNCTUATION]))) +simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$') + +def autolink(text, trim_url_limit=None, nofollow=False): + """ + Converts any URLs in text into clickable links. Works on http://, https:// and + www. links. Links can have trailing punctuation (periods, commas, close-parens) + and leading punctuation (opening parens) and it'll still do the right thing. + + If trim_url_limit is not None, the URLs in link text will be limited to + trim_url_limit characters. + + If nofollow is True, the URLs in link text will get a rel="nofollow" attribute. + + Copy from https://github.com/livid/v2ex/blob/master/v2ex/templatetags/filters.py#L35 + """ + trim_url = lambda x, limit=trim_url_limit: limit is not None and (x[:limit] + (len(x) >=limit and '...' or '')) or x + words = word_split_re.split(text) + nofollow_attr = nofollow and ' rel="nofollow"' or '' + for i, word in enumerate(words): + match = punctuation_re.match(word) + if match: + lead, middle, trail = match.groups() + if middle.startswith('www.') or ('@' not in middle and not middle.startswith('http://') and \ + len(middle) > 0 and middle[0] in string.letters + string.digits and \ + (middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))): + middle = '%s' % (middle, nofollow_attr, trim_url(middle)) + if middle.startswith('http://') or middle.startswith('https://'): + middle = '%s' % (middle, nofollow_attr, trim_url(middle)) + if '@' in middle and not middle.startswith('www.') and not ':' in middle \ + and simple_email_re.match(middle): + middle = '%s' % (middle, middle) + if lead + middle + trail != word: + words[i] = lead + middle + trail + return ''.join(words) + + def avatar_img(link, size = 45): return "" % (link, size, size) filters = { + 'autolink' : autolink, 'avatar_img' : avatar_img, } diff --git a/less/style.less b/less/style.less index 703f7b4..ffe0c35 100644 --- a/less/style.less +++ b/less/style.less @@ -103,7 +103,7 @@ body { margin-bottom: 30px; background-color: white; - .title, legend { + .title { .top-border-radius(4px); font-size: 16px; font-weight: bold; @@ -111,12 +111,13 @@ body { padding-left: 10px; padding-top: 5px; border-bottom: 1px solid #DDD; - } - legend { - padding-left: 20px; - padding-top: 20px; - } + .fr { + float: right; + margin-right: 10px; + font-weight: normal; + } + } .table { .border-radius(0px); @@ -137,6 +138,11 @@ body { } } +form.cell fieldset .title { + padding-left: 20px; + padding-top: 20px; +} + .tagclound { list-style: none; margin-left: 0; @@ -285,3 +291,34 @@ nav { text-align: right; } } + +/* Single Problem Page Style */ + +.signleproblem { + + .table tr { + + &:hover { + td, th { + background-color: #FAFAFA; + } + } + + th { + text-align: right; + width: 13%; + } + } + + .title { + padding-left: 20px; + } + + .tagclound { + margin-top: 0; + + .tag { + padding-right: 10px; + } + } +} diff --git a/problem.py b/problem.py new file mode 100644 index 0000000..7924faf --- /dev/null +++ b/problem.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: problem.py +# CREATED: 04:04:57 15/03/2012 +# MODIFIED: 04:09:32 15/03/2012 + +from tornado.web import HTTPError + +from judge.db import Problem +from judge.db import ProblemDBMixin +from judge.base import BaseHandler + +class ViewProblemHandler(BaseHandler, ProblemDBMixin): + def get(self, pid): + try: + pid = int(pid) + except ValueError: + raise HTTPError(404) + problem = self.select_problem_by_id(pid) + if not problem: + raise HTTPError(404) + if problem.invisible and (self.current_user == None or self.current_user.admin == 0): + raise HTTPError(404) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Problem'), '/problem')) + breadcrumb.append((problem.title, '/problem/%d' % problem.id)) + title = problem.title + tags = self.select_problem_tag_by_problem_id(problem.id) + self.render("problem.html", locals()) + +__all__ = ["ViewProblemHandler"] diff --git a/static/css/style.css b/static/css/style.css index 8b29375..4800f53 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3773,8 +3773,7 @@ body { margin-bottom: 30px; background-color: white; } -.cell .title, -.cell legend { +.cell .title { -webkit-border-top-left-radius: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-topleft: 4px; @@ -3788,9 +3787,10 @@ body { padding-top: 5px; border-bottom: 1px solid #DDD; } -.cell legend { - padding-left: 20px; - padding-top: 20px; +.cell .title .fr { + float: right; + margin-right: 10px; + font-weight: normal; } .cell .table { -webkit-border-radius: 0px; @@ -3808,6 +3808,10 @@ body { .cell .form-actions { margin-bottom: 0; } +form.cell fieldset .title { + padding-left: 20px; + padding-top: 20px; +} .tagclound { list-style: none; margin-left: 0; @@ -3952,3 +3956,21 @@ nav .copyright a { font-weight: normal; text-align: right; } +/* Single Problem Page Style */ +.signleproblem .table tr:hover td, +.signleproblem .table tr:hover th { + background-color: #FAFAFA; +} +.signleproblem .table tr th { + text-align: right; + width: 13%; +} +.signleproblem .title { + padding-left: 20px; +} +.signleproblem .tagclound { + margin-top: 0; +} +.signleproblem .tagclound .tag { + padding-right: 10px; +} diff --git a/tpl/backstage/add_problem.html b/tpl/backstage/add_problem.html index 4ed31aa..85f5f5a 100644 --- a/tpl/backstage/add_problem.html +++ b/tpl/backstage/add_problem.html @@ -9,7 +9,7 @@ {{ show_error_list(error) }}
      - {{ _('Add Problem') }} +
      {{ _('Add Problem') }}
      {{ page.xsrf_form_html() }}
      diff --git a/tpl/problem.html b/tpl/problem.html new file mode 100644 index 0000000..c2e4cd7 --- /dev/null +++ b/tpl/problem.html @@ -0,0 +1,86 @@ +{% extends "base.html" %} +{% from 'macros.html' import form_actions %} + +{% block body %} +{% if problem.invisible %} +
      + {{ _('This Problem is Invisible!') }} +
      +{% endif %} +
      +
      + {% if user.admin %} + + {% endif %} + {{ problem.title }} +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + +
      ID{{ problem.id }}
      {{ _('Short Name') }}{{ problem.shortname }}
      {{ _('Time') }}{{ problem.timelimit }}ms
      {{ _('Memory') }}{{ problem.memlimit }}MB
      {{ _('Content') }}{{ problem.content | autolink | replace('\n', '
      ') }}
      {{ _('Tags') }} + +
      +
      + +{% if user %} + +
      +
      {{ _('Submit Problem') }}
      +
      +
      + +
      + +
      +
      +
      + + +
      + Pascal + C + C++ +
      +
      + {{ form_actions(_('Submit')) }} +
      + + +{% endif %} +{% endblock %} From 80a9c8ac019f71a430a7a0ec8d8728cbc528879e Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 15 Mar 2012 13:38:57 +0800 Subject: [PATCH 17/56] finish setting.. --- handlers.py | 3 ++- judge/base/__init__.py | 7 +++-- judge/db/__init__.py | 16 ++++++++++- less/style.less | 8 +++--- member.py | 61 ++++++++++++++++++++++++++++++++++++++++-- static/css/style.css | 7 ++--- tpl/macros.html | 4 +-- tpl/problem.html | 2 +- tpl/settings.html | 47 ++++++++++++++++++++++++++++++++ 9 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 tpl/settings.html diff --git a/handlers.py b/handlers.py index 958f642..2c09d9f 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 04:09:12 15/03/2012 +# MODIFIED: 12:56:09 15/03/2012 # DESCRIPTION: URL Route from home import * @@ -20,6 +20,7 @@ (r'/signin', SigninHandler), (r'/signup', SignupHandler), (r'/signout', SignoutHandler), + (r'/settings', SettingsHandler), (r'/lang/(.*)', SetLanguageHandler), (r'/problem/([\d]*)', ViewProblemHandler), (r'/backstage/problem/add', AddProblemHandler), diff --git a/judge/base/__init__.py b/judge/base/__init__.py index f502ad7..892d4e0 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 04:02:16 15/03/2012 +# MODIFIED: 13:13:55 15/03/2012 # DESCRIPTION: Base handler import re @@ -123,9 +123,8 @@ def check_text_value(self, value, valName, required = False, max = 65535, min = error.append(regex_msg) else: error.append(self._("%s is invalid." % valName)) - else: - if vaild and value not in vaild: - errora.append(self._("%s is invalid." % valName)) + elif vaild and value not in vaild: + errora.append(self._("%s is invalid." % valName)) return error def check_username(self, usr, queryDB = False): error = [] diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 30f9316..99cfba1 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 04:00:13 15/03/2012 +# MODIFIED: 13:35:01 15/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -99,6 +99,20 @@ def insert_auth(self, member_id, random): auth.member_id = member_id auth.secret = random return auth + ''' UPDATE ''' + def update_member(self, member): + self.db.execute("""UPDATE `member` + SET `email` = %s, + `gravatar_link` = %s, + `website` = %s, + `tagline` = %s, + `bio` = %s, + `lang` = %s + WHERE `id` = %s""", member.email, member.gravatar_link, \ + member.website, member.tagline, member.bio, \ + member.lang, member.id) + def update_member_password(self, member): + self.db.execute("""UPDATE `member` SET `passowrd` = %s WHERE `id` = %s""", member.password, member.id) ''' DELETE ''' def delete_auth_by_secret(self, secret): self.db.execute("""DELETE FROM `auth` WHERE `secret` = %s""", secret) diff --git a/less/style.less b/less/style.less index ffe0c35..a4665c5 100644 --- a/less/style.less +++ b/less/style.less @@ -63,9 +63,6 @@ body { } } } - .alert ul { - margin-bottom: 0; - } } /* Common Page Style */ @@ -89,9 +86,14 @@ body { .main { padding-top: 40px; padding-right: 20px; + margin-bottom: 20px; width: 96%; } +.alert ul { + margin-bottom: 0; +} + .sep30 { height: 30px; } diff --git a/member.py b/member.py index 1895cd4..2dfea4f 100644 --- a/member.py +++ b/member.py @@ -2,10 +2,11 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 02:10:17 15/03/2012 +# MODIFIED: 13:32:38 15/03/2012 # DESCRIPTION: member handlers import re +import copy import bcrypt from tornado.web import authenticated @@ -82,4 +83,60 @@ def get(self): self.clear_cookie('uid') self.redirect('/') -__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler"] +class SettingsHandler(BaseHandler, MemberDBMixin): + @staticmethod + def get_lang_code(lang): + lang_dict = { + 'pas' : 1, + 'c' : 2, + 'cpp' : 3, + } + if lang not in lang_dict.keys(): + return 1 + return lang_dict[lang] + @authenticated + def get(self): + title = self._("Settings") + msg = self.get_secure_cookie("msg") + if msg: + self.clear_cookie("msg") + member = self.current_user + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self.current_user.username, '/member/%s' % self.current_user.username)) + breadcrumb.append((self._('Settings'), '/settings')) + self.render("settings.html", locals()) + @authenticated + def post(self): + email = self.get_argument("email", default = None) + website = self.get_argument("website", default = "") + tagline = self.get_argument("tagline", default = "") + lang = self.get_argument("lang", default = "pas").lower() + bio = self.get_argument("bio", default = "") + error = [] + member = copy.copy(self.current_user) + error.extend(self.check_email(email)) + error.extend(self.check_text_value(website, self._("Website"), max = 200, \ + regex = re.compile('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'))) + error.extend(self.check_text_value(tagline, self._("Tagline"), max = 70)) + error.extend(self.check_text_value(lang, self._("Code Language"), vaild=["pas", "c", "cpp"])) + error.extend(self.check_text_value(bio, self._("Bio"), max = 20000)) + member.email = self.xhtml_escape(email) + member.website = self.xhtml_escape(website) + member.tagline = self.xhtml_escape(tagline) + member.bio = self.xhtml_escape(bio) + member.lang = self.get_lang_code(lang) + if error: + title = self._("Settings") + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self.current_user.username, '/member/%s' % self.current_user.username)) + breadcrumb.append((self._('Settings'), '/settings')) + self.render("settings.html", locals()) + return + member.gravatar_link = self.get_gravatar_url(email) + self.update_member(member) + self.set_secure_cookie('msg', self._('Settings Updated.')) + self.redirect('/settings') + +__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler"] diff --git a/static/css/style.css b/static/css/style.css index 4800f53..efdb23a 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3736,9 +3736,6 @@ body { height: 26px; line-height: 26px; } -.sign .alert ul { - margin-bottom: 0; -} /* Common Page Style */ body { margin-left: 260px; @@ -3757,8 +3754,12 @@ body { .main { padding-top: 40px; padding-right: 20px; + margin-bottom: 20px; width: 96%; } +.alert ul { + margin-bottom: 0; +} .sep30 { height: 30px; } diff --git a/tpl/macros.html b/tpl/macros.html index f3f4e1c..22766a6 100644 --- a/tpl/macros.html +++ b/tpl/macros.html @@ -66,8 +66,8 @@ {% endmacro %} -{% macro form_actions(submit) %} +{% macro form_actions(submit, class="btn-primary") %}
      - +
      {% endmacro %} diff --git a/tpl/problem.html b/tpl/problem.html index c2e4cd7..858b4ba 100644 --- a/tpl/problem.html +++ b/tpl/problem.html @@ -15,7 +15,7 @@ {{ problem.title }}
      - +
      diff --git a/tpl/settings.html b/tpl/settings.html new file mode 100644 index 0000000..6afe6a8 --- /dev/null +++ b/tpl/settings.html @@ -0,0 +1,47 @@ +{% extends "base.html" %} +{% from "macros.html" import input %} +{% from "macros.html" import textarea %} +{% from "macros.html" import form_actions %} +{% from "macros.html" import show_error_list %} + +{% block body %} +{{ show_error_list(error) }} +{% if msg %} +
      + {{ msg }} +
      +{% endif %} + +
      +
      {{ _('Basic Settings') }}
      +
      + {{ page.xsrf_form_html() }} + {{ input("email", _("Email"), value=member.email) }} + {{ input("website", _("Website"), value=member.website) }} + {{ input("tagline", _("Tagline"), value=member.tagline) }} +
      + +
      + +
      +
      + {{ textarea("bio", _("Bio"), value=member.bio, style="width: 400px; height: 300px") }} + {{ form_actions(_("Save Changes")) }} +
      + + + +
      +
      {{ _('Change Password') }}
      + {{ page.xsrf_form_html() }} +
      + {{ input("oldpwd", _("Current Password"), type="PASSWORD") }} + {{ input("newpwd", _("New Password"), type="PASSWORD") }} + {{ form_actions(_("Change Password"), class="btn-danger") }} +
      + +{% endblock %} From c91a4ae32e81fdb3e18ac4cb5e726afcc66e1466 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 15 Mar 2012 14:04:58 +0800 Subject: [PATCH 18/56] finish change password --- backstage.py | 4 +--- handlers.py | 3 ++- judge/db/__init__.py | 6 ++++-- member.py | 29 +++++++++++++++++++++++++++-- tpl/settings_changepass.html | 18 ++++++++++++++++++ 5 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 tpl/settings_changepass.html diff --git a/backstage.py b/backstage.py index 70d3564..d33cd25 100644 --- a/backstage.py +++ b/backstage.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: backstage.py # CREATED: 02:43:49 15/03/2012 -# MODIFIED: 04:03:09 15/03/2012 +# MODIFIED: 13:39:21 15/03/2012 import functools @@ -83,6 +83,4 @@ def post(self): self.insert_problem_tag(tag, problem.id) self.redirect('/problem/%d' % problem.id) - - __all__ = ["AddProblemHandler"] diff --git a/handlers.py b/handlers.py index 2c09d9f..ca6eeaf 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 12:56:09 15/03/2012 +# MODIFIED: 13:47:59 15/03/2012 # DESCRIPTION: URL Route from home import * @@ -21,6 +21,7 @@ (r'/signup', SignupHandler), (r'/signout', SignoutHandler), (r'/settings', SettingsHandler), + (r'/settings/changepass', ChangePasswordHandler), (r'/lang/(.*)', SetLanguageHandler), (r'/problem/([\d]*)', ViewProblemHandler), (r'/backstage/problem/add', AddProblemHandler), diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 99cfba1..9201fe0 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 13:35:01 15/03/2012 +# MODIFIED: 13:51:26 15/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -112,10 +112,12 @@ def update_member(self, member): member.website, member.tagline, member.bio, \ member.lang, member.id) def update_member_password(self, member): - self.db.execute("""UPDATE `member` SET `passowrd` = %s WHERE `id` = %s""", member.password, member.id) + self.db.execute("""UPDATE `member` SET `password` = %s WHERE `id` = %s""", member.password, member.id) ''' DELETE ''' def delete_auth_by_secret(self, secret): self.db.execute("""DELETE FROM `auth` WHERE `secret` = %s""", secret) + def delete_auth_by_member_id(self, member_id): + self.db.execute("""DELETE FROM `auth` WHERE `member_id` = %s""", member_id) ''' OTHER ''' def create_auth(self, member_id): random = binascii.b2a_hex(uuid.uuid4().bytes) diff --git a/member.py b/member.py index 2dfea4f..551bee0 100644 --- a/member.py +++ b/member.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 13:32:38 15/03/2012 +# MODIFIED: 14:00:53 15/03/2012 # DESCRIPTION: member handlers import re @@ -139,4 +139,29 @@ def post(self): self.set_secure_cookie('msg', self._('Settings Updated.')) self.redirect('/settings') -__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler"] +class ChangePasswordHandler(BaseHandler, MemberDBMixin): + @authenticated + def post(self): + oldpwd = self.get_argument('oldpwd', default = None) + newpwd = self.get_argument('newpwd', default = None) + error = [] + error.extend(self.check_password(oldpwd)) + error.extend(self.check_password(newpwd)) + oldpwd_hash = bcrypt.hashpw(oldpwd, self.settings['bcrypt_salt']) + if oldpwd_hash != self.current_user.password: + error.append(self._("Wrong Passowrd")) + if error: + title = self._("Change Password") + self.render("settings_changepass.html", locals()) + return + member = self.current_user + member.password = bcrypt.hashpw(newpwd, self.settings['bcrypt_salt']) + self.update_member_password(member) + self.delete_auth_by_member_id(member.id) + auth = self.create_auth(member.id) + self.set_secure_cookie('auth', auth.secret) + self.set_secure_cookie('uid', str(auth.member_id)) + self.set_secure_cookie('msg', self._('Password Updated.')) + self.redirect('/settings') + +__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler", "ChangePasswordHandler"] diff --git a/tpl/settings_changepass.html b/tpl/settings_changepass.html new file mode 100644 index 0000000..2c96b86 --- /dev/null +++ b/tpl/settings_changepass.html @@ -0,0 +1,18 @@ +{% extends 'base.html' %} +{% from "macros.html" import input %} +{% from "macros.html" import form_actions %} +{% from "macros.html" import show_error_list %} + +{% block body %} +{{ show_error_list(error) }} +
      +
      +
      {{ _('Change Password') }}
      + {{ page.xsrf_form_html() }} +
      + {{ input("oldpwd", _("Current Password"), type="PASSWORD") }} + {{ input("newpwd", _("New Password"), type="PASSWORD") }} + {{ form_actions(_("Change Password"), class="btn-danger") }} +
      + +{% endblock %} From 76d49e8c0f5518f74e7e284dbf7fb72bd4bede56 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 15 Mar 2012 14:37:11 +0800 Subject: [PATCH 19/56] finish problem list --- handlers.py | 3 ++- judge/base/__init__.py | 6 ++--- judge/db/__init__.py | 24 +++++++++++++++++++- judge/filters/__init__.py | 47 +++++++++++++++++++++++++++++++++++---- less/style.less | 8 +++++++ problem.py | 24 ++++++++++++++++++-- static/css/style.css | 6 +++++ tpl/count.html | 15 +++++++++++++ tpl/problem_list.html | 34 ++++++++++++++++++++++++++++ 9 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 tpl/count.html create mode 100644 tpl/problem_list.html diff --git a/handlers.py b/handlers.py index ca6eeaf..87d554c 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 13:47:59 15/03/2012 +# MODIFIED: 14:19:36 15/03/2012 # DESCRIPTION: URL Route from home import * @@ -23,6 +23,7 @@ (r'/settings', SettingsHandler), (r'/settings/changepass', ChangePasswordHandler), (r'/lang/(.*)', SetLanguageHandler), + (r'/problem', ProblemListHandler), (r'/problem/([\d]*)', ViewProblemHandler), (r'/backstage/problem/add', AddProblemHandler), ] diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 892d4e0..65bd31a 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 13:13:55 15/03/2012 +# MODIFIED: 14:20:39 15/03/2012 # DESCRIPTION: Base handler import re @@ -37,9 +37,9 @@ class BaseHandler(tornado.web.RequestHandler): def _check_text_value(self): '''Check text value is vaild''' pass - def get_page_num(self): + def get_page_count(self, count): '''Return page num by input item num''' - pass + return count / 10 + (1 if count % 10 else 0) def get_current_user(self): '''Check user is logined''' auth = self.get_secure_cookie("auth") diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 9201fe0..5b4b809 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 13:51:26 15/03/2012 +# MODIFIED: 14:18:11 15/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -238,6 +238,16 @@ def _new_problem_tag(self, row): problem_tag = ProblemTag() problem_tag._init_row(row) return problem_tag + ''' COUNT ''' + def count_problem(self): + count = self.db.get("""SELECT COUNT(*) FROM `problem`""") + return count["COUNT(*)"] + def count_visible_problem(self): + count = self.db.get("""SELECT COUNT(*) FROM `problem` WHERE `invisible` = 0""") + return count["COUNT(*)"] + def count_problem_by_tagname(self, tagname): + count = self.db.get("""SELECT COUNT(*) FROM `problem_tag` WHERE `tagname` = %s""", tagname) + return count["COUNT(*)"] ''' SELECT ''' def select_problem_by_id(self, id): row = self.db.get("""SELECT * FROM `problem` WHERE `id` = %s LIMIT 1""", id) @@ -250,6 +260,18 @@ def select_problem_tag_by_problem_id(self, problem_id): for row in rows: result.append(self._new_problem_tag(row)) return result + def select_problem_order_by_id(self, count = 10, start = 0): + rows = self.db.query("""SELECT * FROM `problem` LIMIT %s, %s""", int(start), int(count)) + result = [] + for row in rows: + result.append(self._new_problem(row)) + return result + def select_visible_problem_order_by_id(self, count = 10, start = 0): + rows = self.db.query("""SELECT * FROM `problem` WHERE `invisible` = 0 LIMIT %s, %s""", int(start), int(count)) + result = [] + for row in rows: + result.append(self._new_problem(row)) + return result ''' INSERT ''' def insert_problem(self, problem): problem.id = self.db.execute("""INSERT INTO `problem` (`title`, `shortname`, `content`, \ diff --git a/judge/filters/__init__.py b/judge/filters/__init__.py index 6f90f41..2c9969d 100644 --- a/judge/filters/__init__.py +++ b/judge/filters/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/filters/__init__.py # CREATED: 01:48:10 08/03/2012 -# MODIFIED: 04:25:41 15/03/2012 +# MODIFIED: 14:29:20 15/03/2012 # DESCRIPTION: jinja2 filters import re @@ -54,11 +54,50 @@ def autolink(text, trim_url_limit=None, nofollow=False): words[i] = lead + middle + trail return ''.join(words) - def avatar_img(link, size = 45): return "" % (link, size, size) +def get_prev_page(start): + prev = get_now_page(start) - 10 + return prev if prev >= 0 else 0 + +def get_now_page(start): + start = int(start) + now = start / 10 * 10 + return now + +def get_next_page(start): + return get_now_page(start) + 10 + +def get_page_nav(pages, start): + now = start / 10 + dotdot = lambda a: "
    • ...
    • " + button = lambda page: "
    • %d
    • " % (page * 10, page + 1) + activebutton = lambda page: "
    • %d
    • " % (page * 10, page + 1) + result = [] + for i in range(pages if pages <= 4 else 4): + if i == now: + result.append(activebutton(i)) + else: + result.append(button(i)) + if now == 3 and pages > 4: + result.append(button(4)) + if now > 3: + if now > 4: + result.append(dotdot(1)) + result.append(button(now - 1)) + result.append(activebutton(now)) + if now + 1 < pages: + result.append(button(now + 1)) + if pages - 1 > 3 and now + 1 < pages - 1: + result.append(dotdot(1)) + result.append(button(pages - 1)) + return result + filters = { - 'autolink' : autolink, - 'avatar_img' : avatar_img, + 'autolink' : autolink, + 'avatar_img' : avatar_img, + 'get_prev_page' : get_prev_page, + 'get_next_page' : get_next_page, + 'get_page_nav' : get_page_nav, } diff --git a/less/style.less b/less/style.less index a4665c5..08239e3 100644 --- a/less/style.less +++ b/less/style.less @@ -164,6 +164,14 @@ form.cell fieldset .title { } } +.pagination { + text-align: center; + + ul { + background-color: white; + } +} + /* Navigator Style */ nav { diff --git a/problem.py b/problem.py index 7924faf..f64f4af 100644 --- a/problem.py +++ b/problem.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 04:09:32 15/03/2012 +# MODIFIED: 14:19:53 15/03/2012 from tornado.web import HTTPError @@ -29,4 +29,24 @@ def get(self, pid): tags = self.select_problem_tag_by_problem_id(problem.id) self.render("problem.html", locals()) -__all__ = ["ViewProblemHandler"] +class ProblemListHandler(BaseHandler, ProblemDBMixin): + def get(self): + start = self.get_argument("start", default = 0) + try: + start = int(start) + except ValueError: + start = 0 + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Problem'), '/problem')) + title = self._("Problem") + if self.current_user and self.current_user.admin: + count = self.count_problem() + problems = self.select_problem_order_by_id(10, start) + else: + count = self.count_visible_problem() + problems = self.select_problem_order_by_id_visible(10, start) + pages = self.get_page_count(count) + self.render("problem_list.html", locals()) + +__all__ = ["ViewProblemHandler", "ProblemListHandler"] diff --git a/static/css/style.css b/static/css/style.css index efdb23a..22bde40 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3831,6 +3831,12 @@ form.cell fieldset .title { .tagclound .tag a { color: black; } +.pagination { + text-align: center; +} +.pagination ul { + background-color: white; +} /* Navigator Style */ nav { -webkit-box-shadow: 0px 0px 5px #000000; diff --git a/tpl/count.html b/tpl/count.html new file mode 100644 index 0000000..94d8ac3 --- /dev/null +++ b/tpl/count.html @@ -0,0 +1,15 @@ +{% if count %} + +{% endif %} diff --git a/tpl/problem_list.html b/tpl/problem_list.html new file mode 100644 index 0000000..dab6674 --- /dev/null +++ b/tpl/problem_list.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} + +{% block body %} +
      +
      {{ _('Problem List') }}
      +
      +
      ID {{ problem.id }}
      + + + + + + + + + + + {% for problem in problems %} + {% if problem.invisible == 0 or user.admin == 1%} + + + + + + + + {% endif %} + {% endfor %} + +
      #{{ _('Title') }}{{ _('Time') }}{{ _('Memory') }}{{ _('Short Name') }}
      {{ problem.id }}{{ problem.title }}{{ problem.timelimit }} ms{{ problem.memlimit }} MB{{ problem.shortname }}
      +
      + +{% include 'count.html' %} +{% endblock %} From 2298fd9b3c48fbcd6f3bb827638219884c632ab8 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 15 Mar 2012 15:39:39 +0800 Subject: [PATCH 20/56] add member profile page --- handlers.py | 3 ++- judge/db/__init__.py | 2 +- judge/filters/__init__.py | 4 +++- less/style.less | 46 +++++++++++++++++++++++++++++++++++++++ member.py | 16 ++++++++++++-- static/css/style.css | 39 +++++++++++++++++++++++++++++++++ tpl/member.html | 20 +++++++++++++++++ 7 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 tpl/member.html diff --git a/handlers.py b/handlers.py index 87d554c..7f50d02 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 14:19:36 15/03/2012 +# MODIFIED: 14:49:25 15/03/2012 # DESCRIPTION: URL Route from home import * @@ -22,6 +22,7 @@ (r'/signout', SignoutHandler), (r'/settings', SettingsHandler), (r'/settings/changepass', ChangePasswordHandler), + (r'/member/(.*)', MemberHandler), (r'/lang/(.*)', SetLanguageHandler), (r'/problem', ProblemListHandler), (r'/problem/([\d]*)', ViewProblemHandler), diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 5b4b809..de42f7d 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 14:18:11 15/03/2012 +# MODIFIED: 14:51:08 15/03/2012 # DESCRIPTION: Database Table Object import uuid diff --git a/judge/filters/__init__.py b/judge/filters/__init__.py index 2c9969d..e18855a 100644 --- a/judge/filters/__init__.py +++ b/judge/filters/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/filters/__init__.py # CREATED: 01:48:10 08/03/2012 -# MODIFIED: 14:29:20 15/03/2012 +# MODIFIED: 15:38:22 15/03/2012 # DESCRIPTION: jinja2 filters import re @@ -55,6 +55,8 @@ def autolink(text, trim_url_limit=None, nofollow=False): return ''.join(words) def avatar_img(link, size = 45): + if link != "/static/img/avatar.png": + link = link + "&s=100" return "" % (link, size, size) def get_prev_page(start): diff --git a/less/style.less b/less/style.less index 08239e3..bd93403 100644 --- a/less/style.less +++ b/less/style.less @@ -138,6 +138,10 @@ body { .form-actions { margin-bottom: 0; } + + .line { + border-bottom: 1px solid #DDD; + } } form.cell fieldset .title { @@ -332,3 +336,45 @@ nav { } } } + +/* Member Page */ + +.member-top { + + .line { + padding: 10px 15px; + min-height: 100px; + } + + .avatar { + float: left; + img { + .border-radius(4px); + } + } + + .profile { + float: left; + margin-left: 15px; + width: 80%; + + .username { + font-family: Georgia,Times New Roman,serif; + } + .tagline { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 16px; + color: #999; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif + } + .meta { + font-size: 12px; + color: #CCC; + } + .website i { + margin-right: 5px; + } + } +} diff --git a/member.py b/member.py index 551bee0..758b1b0 100644 --- a/member.py +++ b/member.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 14:00:53 15/03/2012 +# MODIFIED: 14:51:21 15/03/2012 # DESCRIPTION: member handlers import re @@ -164,4 +164,16 @@ def post(self): self.set_secure_cookie('msg', self._('Password Updated.')) self.redirect('/settings') -__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler", "ChangePasswordHandler"] +class MemberHandler(BaseHandler, MemberDBMixin): + def get(self, username): + title = username + username = username.lower() + member = self.select_member_by_username_lower(username) + if not member: + raise HTTPError(404) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((member.username, '/member/%s' % member.username)) + self.render("member.html", locals()) + +__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler", "ChangePasswordHandler", "MemberHandler"] diff --git a/static/css/style.css b/static/css/style.css index 22bde40..a8444f7 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3809,6 +3809,9 @@ body { .cell .form-actions { margin-bottom: 0; } +.cell .line { + border-bottom: 1px solid #DDD; +} form.cell fieldset .title { padding-left: 20px; padding-top: 20px; @@ -3981,3 +3984,39 @@ nav .copyright a { .signleproblem .tagclound .tag { padding-right: 10px; } +/* Member Page */ +.member-top .line { + padding: 10px 15px; + min-height: 100px; +} +.member-top .avatar { + float: left; +} +.member-top .avatar img { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.member-top .profile { + float: left; + margin-left: 15px; + width: 80%; +} +.member-top .profile .username { + font-family: Georgia,Times New Roman,serif; +} +.member-top .profile .tagline { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 16px; + color: #999; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.member-top .profile .meta { + font-size: 12px; + color: #CCC; +} +.member-top .profile .website i { + margin-right: 5px; +} diff --git a/tpl/member.html b/tpl/member.html new file mode 100644 index 0000000..6c3221e --- /dev/null +++ b/tpl/member.html @@ -0,0 +1,20 @@ +{% extends 'base.html' %} + +{% block body %} +
      +
      +
      + {{ member.gravatar_link | avatar_img(100) }} +
      +
      +

      {{ member.username.title() }}

      +
      {{ member.tagline }}
      +
      {{ _('ID:') }}{{ member.id }}. {{ _('Joined at') }} {{ member.create }}
      + +
      +
      +
      + {{ member.bio | autolink | replace("\n", "
      ")}} +
      +
      +{% endblock %} From d527381abae185c6834f013af4da0c7f8717bb8b Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 15 Mar 2012 17:10:48 +0800 Subject: [PATCH 21/56] get method in add contest handler --- backstage.py | 18 +++++++++-- contest.py | 7 +++++ handlers.py | 3 +- judge/base/__init__.py | 13 ++++---- judge/db/__init__.py | 30 ++++++++++++++++-- judge/filters/__init__.py | 16 ++++++---- main.py | 2 +- tpl/backstage/add_contest.html | 56 ++++++++++++++++++++++++++++++++++ tpl/backstage/add_problem.html | 2 +- tpl/base/sidebar.html | 2 +- 10 files changed, 129 insertions(+), 20 deletions(-) create mode 100644 contest.py create mode 100644 tpl/backstage/add_contest.html diff --git a/backstage.py b/backstage.py index d33cd25..979553b 100644 --- a/backstage.py +++ b/backstage.py @@ -2,13 +2,15 @@ # AUTHOR: Zeray Rice # FILE: backstage.py # CREATED: 02:43:49 15/03/2012 -# MODIFIED: 13:39:21 15/03/2012 +# MODIFIED: 15:53:23 15/03/2012 import functools from tornado.web import HTTPError +from judge.db import Contest from judge.db import Problem +from judge.db import ContestDBMixin from judge.db import ProblemDBMixin from judge.base import BaseHandler @@ -83,4 +85,16 @@ def post(self): self.insert_problem_tag(tag, problem.id) self.redirect('/problem/%d' % problem.id) -__all__ = ["AddProblemHandler"] +class AddContestHandler(BaseHandler, ProblemDBMixin, ContestDBMixin): + @backstage + def get(self): + title = self._("Add Contest") + cid = self.get_argument("cid", default = 0) + contest = None + if cid: + contest = self.select_contest_by_id(cid) + title = self._("Edit Contest") + related_problem = self.select_contest_problem_by_contest_id(contest.id) + self.render("backstage/add_contest.html", locals()) + +__all__ = ["AddProblemHandler", "AddContestHandler"] diff --git a/contest.py b/contest.py new file mode 100644 index 0000000..3a223f0 --- /dev/null +++ b/contest.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: contest.py +# CREATED: 15:46:17 15/03/2012 +# MODIFIED: 15:46:36 15/03/2012 + + diff --git a/handlers.py b/handlers.py index 7f50d02..6bd87fc 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 14:49:25 15/03/2012 +# MODIFIED: 15:54:23 15/03/2012 # DESCRIPTION: URL Route from home import * @@ -27,4 +27,5 @@ (r'/problem', ProblemListHandler), (r'/problem/([\d]*)', ViewProblemHandler), (r'/backstage/problem/add', AddProblemHandler), + (r'/backstage/contest/add', AddContestHandler), ] diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 65bd31a..7388d3f 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 14:20:39 15/03/2012 +# MODIFIED: 15:41:54 15/03/2012 # DESCRIPTION: Base handler import re @@ -18,7 +18,6 @@ from judge.db import Member from judge.utils import _len - def unauthenticated(method): """Decorate methods with this to require that user be NOT logged in""" @functools.wraps(method) @@ -34,9 +33,6 @@ def wrapper(self, *args, **kwargs): class BaseHandler(tornado.web.RequestHandler): _ = lambda self, text: self.locale.translate(text) # i18n func xhtml_escape = lambda self, text: tornado.escape.xhtml_escape(text) if text else text # xhtml escape - def _check_text_value(self): - '''Check text value is vaild''' - pass def get_page_count(self, count): '''Return page num by input item num''' return count / 10 + (1 if count % 10 else 0) @@ -71,7 +67,12 @@ def get_current_user(self): return member def get_user_locale(self): '''Get user locale, first check cookie, then browser''' - pass + result = self.get_cookie('LANG', default = None) + if result == None: + result = self.get_browser_locale() + else: + result = tornado.locale.get(result) + return result def sendmail(self): '''Send mail func, send mail to someone''' pass diff --git a/judge/db/__init__.py b/judge/db/__init__.py index de42f7d..40ac28d 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 14:51:08 15/03/2012 +# MODIFIED: 15:53:03 15/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -341,4 +341,30 @@ class ContestSubmit(BaseDBObject): create = 0 class ContestDBMixin(BaseDBMixin): - pass + ''' New Data Model ''' + def _new_contest(self, row): + contest = Contest() + contest._init_row(row) + return contest + def _new_contest_problem(self, row): + contest_problem = ContestProblem() + contest_problem._init_row(row) + return contest + ''' COUNT ''' + ''' SELECT ''' + def select_countest_by_id(contest_id): + row = self.db.get("""SELECT * FROM `contest` WHERE `id` = %s""", contest_id) + if row: + return self._new_contest(row) + return None + def select_contest_problem_by_contest_id(contest_id): + rows = self.db.query("""SELECT * FROM `contest_problem` WHERE `contest_id` = %s""", contest_id) + result = [] + for row in rows: + result.append(self._new_contest_problem(row)) + return result + ''' INSERT ''' + ''' UPDATE ''' + ''' DELETE ''' + ''' OTHER ''' + diff --git a/judge/filters/__init__.py b/judge/filters/__init__.py index e18855a..0ec7f90 100644 --- a/judge/filters/__init__.py +++ b/judge/filters/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/filters/__init__.py # CREATED: 01:48:10 08/03/2012 -# MODIFIED: 15:38:22 15/03/2012 +# MODIFIED: 16:00:06 15/03/2012 # DESCRIPTION: jinja2 filters import re @@ -96,10 +96,14 @@ def get_page_nav(pages, start): result.append(button(pages - 1)) return result +def datetimeformat(value, format='%m/%d/%Y %H:%M'): + return value.strftime(format) + filters = { - 'autolink' : autolink, - 'avatar_img' : avatar_img, - 'get_prev_page' : get_prev_page, - 'get_next_page' : get_next_page, - 'get_page_nav' : get_page_nav, + 'autolink' : autolink, + 'avatar_img' : avatar_img, + 'get_prev_page' : get_prev_page, + 'get_next_page' : get_next_page, + 'get_page_nav' : get_page_nav, + 'datetimeformat' : datetimeformat, } diff --git a/main.py b/main.py index 5de66e9..a745e75 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: main.py # CREATED: 01:37:19 08/03/2012 -# MODIFIED: 01:47:54 08/03/2012 +# MODIFIED: 15:46:12 15/03/2012 # DESCRIPTION: Main Server File, run as `python2 main.py [port_num]` import re diff --git a/tpl/backstage/add_contest.html b/tpl/backstage/add_contest.html new file mode 100644 index 0000000..89e7de1 --- /dev/null +++ b/tpl/backstage/add_contest.html @@ -0,0 +1,56 @@ +{% extends "base.html" %} +{% from "macros.html" import input %} +{% from "macros.html" import textarea %} +{% from "macros.html" import checkbox %} +{% from "macros.html" import form_actions %} +{% from "macros.html" import show_error_list %} + +{% block body %} +{{ show_error_list(error) }} +
      +
      +
      {{ title }}
      + {{ page.xsrf_form_html() }} + +
      + {{ input("title", _("Title"), value=contest.title) }} +
      + +
      + +
      +
      +
      + +
      + +
      +
      + {{ checkbox('invisible', _('Invisible'), checked=contest.invisible) }} + {{ textarea("description", _("Descriptiopn"), value=contest.description, style="width:400px; height:300px; ") }} +
      + +
      + + {{ _('Add') }} + +
      +
      +{% if related_problem %} +{% for problem in related_problem %} + +{% endfor %} +{% endif %} + {{ form_actions(_("Submit")) }} +
      +
      +{% endblock %} diff --git a/tpl/backstage/add_problem.html b/tpl/backstage/add_problem.html index 85f5f5a..afba90d 100644 --- a/tpl/backstage/add_problem.html +++ b/tpl/backstage/add_problem.html @@ -9,7 +9,7 @@ {{ show_error_list(error) }}
      -
      {{ _('Add Problem') }}
      +
      {{ title }}
      {{ page.xsrf_form_html() }}
      diff --git a/tpl/base/sidebar.html b/tpl/base/sidebar.html index 6eb718b..4dcc934 100644 --- a/tpl/base/sidebar.html +++ b/tpl/base/sidebar.html @@ -94,7 +94,7 @@
    • - + {{ _('Add Contest') }} From def1d912d86f0b2c54de543b8e52e28948499251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A5=AD=E5=9B=A2?= Date: Thu, 15 Mar 2012 20:40:02 +0800 Subject: [PATCH 22/56] add contest & list contest --- backstage.py | 51 +- contest.py | 39 + judge/db/__init__.py | 37 + static/css/timepicker.css | 566 ++++++++++ static/js/base.js | 5 + static/js/bootstrap.min.js | 1 + static/js/jquery-ui-timepicker-addon.js | 1326 +++++++++++++++++++++++ static/js/jquery-ui.min.js | 414 +++++++ static/js/timepicker.js | 38 + tpl/backstage/add_contest.html | 65 +- tpl/base.html | 2 + tpl/base/head.html | 3 +- 12 files changed, 2540 insertions(+), 7 deletions(-) create mode 100644 static/css/timepicker.css create mode 100644 static/js/base.js create mode 100644 static/js/bootstrap.min.js create mode 100644 static/js/jquery-ui-timepicker-addon.js create mode 100644 static/js/jquery-ui.min.js create mode 100644 static/js/timepicker.js diff --git a/backstage.py b/backstage.py index 979553b..f1781ba 100644 --- a/backstage.py +++ b/backstage.py @@ -4,6 +4,7 @@ # CREATED: 02:43:49 15/03/2012 # MODIFIED: 15:53:23 15/03/2012 +import datetime import functools from tornado.web import HTTPError @@ -94,7 +95,55 @@ def get(self): if cid: contest = self.select_contest_by_id(cid) title = self._("Edit Contest") - related_problem = self.select_contest_problem_by_contest_id(contest.id) + related_problem_id = self.select_contest_problem_by_contest_id(contest.id) + related_problem = [] + for pid in related_problem_id: + related_problem.append(self.select_problem_by_id(pid)) self.render("backstage/add_contest.html", locals()) + @backstage + def post(self): + title = self.get_argument("title", default = "") + description = self.get_argument("description", default = "") + start_time = self.get_argument("start_time", default = "") + end_time = self.get_argument("end_time", default = "") + invisible = self.get_argument("invisible", default = 0) + cid = self.get_argument("cid", default = None) + related_problem = self.get_arguments("link_problem[]") + contest = Contest() + contest.id = cid + error = [] + error.extend(self.check_text_value(title, self._("Title"), required = True, max = 100)) + error.extend(self.check_text_value(description, self._("Description"), max = 20000)) + try: + start_datetime = datetime.datetime.strptime(start_time, "%m/%d/%Y %H:%M") + end_datetime = datetime.datetime.strptime(end_time, "%m/%d/%Y %H:%M") + except ValueError: + error.append(self._("Start/End Time Format is Invalid.")) + else: + if start_datetime > end_datetime: + error.append(self._("Start/End Time is invalid.")) + contest.title = self.xhtml_escape(title) + contest.description = self.xhtml_escape(description) + contest.start_time = self.xhtml_escape(start_time) + contest.end_time = self.xhtml_escape(end_time) + contest.invisible = self.xhtml_escape(invisible) + contest.related_problem = related_problem + if error: + title = self._("Add Contest") + related_problem = [] + for pid in contest.related_problem: + related_problem.append(self.select_problem_by_id(pid)) + self.render("backstage/contest_create.html", locals()) + return + contest.start_time = start_datetime + contest.end_time = end_datetime + if contest.id: + self.update_contest(contest) + self.delete_contest_problem_by_cid(contest.id) + else: + self.insert_contest(contest) + for pid in contest.related_problem: + self.insert_contest_problem(cid = contest.id, pid = pid) + self.redirect("/contest/%d" % int(contest.id)) __all__ = ["AddProblemHandler", "AddContestHandler"] diff --git a/contest.py b/contest.py index 3a223f0..e040188 100644 --- a/contest.py +++ b/contest.py @@ -4,4 +4,43 @@ # CREATED: 15:46:17 15/03/2012 # MODIFIED: 15:46:36 15/03/2012 +import datetime +from tornado.web import HTTPError +from tornado.web import authenticated + +from judge.db import Contest +from judge.db import ContestDBMixin +from judge.base import BaseHandler + +class ViewContestHandler(BaseHandler, ContestDBMixin): + @authenticated + def get(self, cid): + try: + cid = int(cid) + except ValueError: + raise HTTPError(404) + contest = self.select_contest_by_id(cid) + if not contest: + raise HTTPError(404) + now = datetime.datetime.now() + self.render("contest.html", locals()) + +class ListContestHandlder(BaseHandler, ContestDBMixin): + def get(self): + start = self.get_argument("start", default = 0) + title = self._("Contest List") + try: + start = int(start) + except ValueError: + start = 0 + if self.current_user and self.current_user.admin: + count = self.count_contest() + contests = self.select_contest(start = start) + else: + count = self.count_visible_contest() + contests = self.select_visible_contest(start = start) + pages = self.get_page_count(count) + self.render("contest_list.html", locals()) + +__all__ = ["ViewContestHandler"] diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 40ac28d..0385359 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -351,6 +351,12 @@ def _new_contest_problem(self, row): contest_problem._init_row(row) return contest ''' COUNT ''' + def count_contest(self): + row = self.db.get("""SELECT COUNT(*) FROM `contest`""") + return row["COUNT(*)"] + def count_visible_contest(self): + row = self.db.get("""SELECT COUNT(*) FROM `contest` WHERE invisible = 0""") + return row["COUNT(*)"] ''' SELECT ''' def select_countest_by_id(contest_id): row = self.db.get("""SELECT * FROM `contest` WHERE `id` = %s""", contest_id) @@ -363,8 +369,39 @@ def select_contest_problem_by_contest_id(contest_id): for row in rows: result.append(self._new_contest_problem(row)) return result + def select_countest(self, start = 0, count = 20): + rows = self.db.query("""SELECT * FROM `contest` LIMIT %s, %s""", start, count) + result = [] + for row in rows: + result.append(self._new_contest(row)) + return result + def select_visible_contest(self, start = 0, count = 20): + rows = self.db.query("""SELECT * FROM `contest` WHERE `invisible` = 0 LIMIT %s, %s""", start, count) + result = [] + for row in rows: + result.append(self._new_contest(row)) + return result ''' INSERT ''' + def insert_contest(self, contest): + contest.id = self.db.execute("""INSERT INTO `contest` (`title`, `description`, `start_time`, + `end_time`, `invisible`, `create`) + VALUES (%s, %s, %s, %s, %s, UTC_TIMESTAMP())""", \ + contest.title, contest.description, contest.start_time, contest.end_time, \ + contest.invisible) + def insert_contest_problem(self, contest_problem): + self.db.execute("""INSERT INTO `contest_problem` (`contest_id`, `problem_id`) VALUES (%s, %s)""", int(cid), int(pid)) ''' UPDATE ''' + def update_contest(self, contest): + self.db.execute("""UPDATE `contest` SET `title` = %s, + `description` = %s, + `start_time` = %s, + `end_time` = %s, + `invisible` = %s + WHERE `id` = %s""" \ + , contest.title, contest.description, contest.start_time, contest.end_time, \ + contest.invisible, contest.id) ''' DELETE ''' + def delete_contest_problem_by_contest_id(self, contest_id): + self.db.execute("""DELETE FROM `contest_problem` WHERE `cid` = %s""", cid) ''' OTHER ''' diff --git a/static/css/timepicker.css b/static/css/timepicker.css new file mode 100644 index 0000000..7bba024 --- /dev/null +++ b/static/css/timepicker.css @@ -0,0 +1,566 @@ +/* + * jQuery UI CSS Framework 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* + * jQuery UI Resizable 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.17 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.17 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } + diff --git a/static/js/base.js b/static/js/base.js new file mode 100644 index 0000000..2429807 --- /dev/null +++ b/static/js/base.js @@ -0,0 +1,5 @@ +$(document).ready(function() { + $('.disabled').click(function() { + return false; + }); +}); diff --git a/static/js/bootstrap.min.js b/static/js/bootstrap.min.js new file mode 100644 index 0000000..1f295a1 --- /dev/null +++ b/static/js/bootstrap.min.js @@ -0,0 +1 @@ +!function(a){a(function(){"use strict",a.support.transition=function(){var b=document.body||document.documentElement,c=b.style,d=c.transition!==undefined||c.WebkitTransition!==undefined||c.MozTransition!==undefined||c.MsTransition!==undefined||c.OTransition!==undefined;return d&&{end:function(){var b="TransitionEnd";return a.browser.webkit?b="webkitTransitionEnd":a.browser.mozilla?b="transitionend":a.browser.opera&&(b="oTransitionEnd"),b}()}}()})}(window.jQuery),!function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype={constructor:c,close:function(b){function f(){e.remove(),e.trigger("closed")}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),e.trigger("close"),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()}},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype={constructor:b,setState:function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},toggle:function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")}},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){a(b.target).button("toggle")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.carousel.defaults,c),this.options.slide&&this.slide(this.options.slide)};b.prototype={cycle:function(){return this.interval=setInterval(a.proxy(this.next,this),this.options.interval),this},to:function(b){var c=this.$element.find(".active"),d=c.parent().children(),e=d.index(c),f=this;if(b>d.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){f.to(b)}):e==b?this.pause().cycle():this.slide(b>e?"next":"prev",a(d[b]))},pause:function(){return clearInterval(this.interval),this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(b,c){var d=this.$element.find(".active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this;return this.sliding=!0,f&&this.pause(),e=e.length?e:this.$element.find(".item")[h](),!a.support.transition&&this.$element.hasClass("slide")?(this.$element.trigger("slide"),d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")):(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),this.$element.trigger("slide"),this.$element.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)})),f&&this.cycle(),this}},a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("carousel"),f=typeof c=="object"&&c;e||d.data("carousel",e=new b(this,f)),typeof c=="number"?e.to(c):typeof c=="string"||(c=f.slide)?e[c]():e.cycle()})},a.fn.carousel.defaults={interval:5e3},a.fn.carousel.Constructor=b,a(function(){a("body").on("click.carousel.data-api","[data-slide]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=!e.data("modal")&&a.extend({},e.data(),c.data());e.carousel(f),b.preventDefault()})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find(".in"),e;d&&d.length&&(e=d.data("collapse"),d.collapse("hide"),e||d.data("collapse",null)),this.$element[b](0),this.transition("addClass","show","shown"),this.$element[b](this.$element[0][c])},hide:function(){var a=this.dimension();this.reset(this.$element[a]()),this.transition("removeClass","hide","hidden"),this.$element[a](0)},reset:function(a){var b=this.dimension();this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element.addClass("collapse")},transition:function(b,c,d){var e=this,f=function(){c=="show"&&e.reset(),e.$element.trigger(d)};this.$element.trigger(c)[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}"use strict";var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e=c.attr("data-target"),f,g;return e||(e=c.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,"")),f=a(e),f.length||(f=c.parent()),g=f.hasClass("open"),d(),!g&&f.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('
    • '},a.fn.typeahead.Constructor=b,a(function(){a("body").on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(b){var c=a(this);if(c.data("typeahead"))return;b.preventDefault(),c.typeahead(c.data())})})}(window.jQuery); \ No newline at end of file diff --git a/static/js/jquery-ui-timepicker-addon.js b/static/js/jquery-ui-timepicker-addon.js new file mode 100644 index 0000000..f83839e --- /dev/null +++ b/static/js/jquery-ui-timepicker-addon.js @@ -0,0 +1,1326 @@ +/* +* jQuery timepicker addon +* By: Trent Richardson [http://trentrichardson.com] +* Version 0.9.9 +* Last Modified: 02/05/2012 +* +* Copyright 2012 Trent Richardson +* Dual licensed under the MIT and GPL licenses. +* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt +* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt +* +* HERES THE CSS: +* .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } +* .ui-timepicker-div dl { text-align: left; } +* .ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; } +* .ui-timepicker-div dl dd { margin: 0 10px 10px 65px; } +* .ui-timepicker-div td { font-size: 90%; } +* .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } +*/ + +(function($) { + +$.extend($.ui, { timepicker: { version: "0.9.9" } }); + +/* Time picker manager. + Use the singleton instance of this class, $.timepicker, to interact with the time picker. + Settings for (groups of) time pickers are maintained in an instance object, + allowing multiple different settings on the same page. */ + +function Timepicker() { + this.regional = []; // Available regional settings, indexed by language code + this.regional[''] = { // Default regional settings + currentText: 'Now', + closeText: 'Done', + ampm: false, + amNames: ['AM', 'A'], + pmNames: ['PM', 'P'], + timeFormat: 'hh:mm tt', + timeSuffix: '', + timeOnlyTitle: 'Choose Time', + timeText: 'Time', + hourText: 'Hour', + minuteText: 'Minute', + secondText: 'Second', + millisecText: 'Millisecond', + timezoneText: 'Time Zone' + }; + this._defaults = { // Global defaults for all the datetime picker instances + showButtonPanel: true, + timeOnly: false, + showHour: true, + showMinute: true, + showSecond: false, + showMillisec: false, + showTimezone: false, + showTime: true, + stepHour: 1, + stepMinute: 1, + stepSecond: 1, + stepMillisec: 1, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + timezone: '+0000', + hourMin: 0, + minuteMin: 0, + secondMin: 0, + millisecMin: 0, + hourMax: 23, + minuteMax: 59, + secondMax: 59, + millisecMax: 999, + minDateTime: null, + maxDateTime: null, + onSelect: null, + hourGrid: 0, + minuteGrid: 0, + secondGrid: 0, + millisecGrid: 0, + alwaysSetTime: true, + separator: ' ', + altFieldTimeOnly: true, + showTimepicker: true, + timezoneIso8609: false, + timezoneList: null, + addSliderAccess: false, + sliderAccessArgs: null + }; + $.extend(this._defaults, this.regional['']); +}; + +$.extend(Timepicker.prototype, { + $input: null, + $altInput: null, + $timeObj: null, + inst: null, + hour_slider: null, + minute_slider: null, + second_slider: null, + millisec_slider: null, + timezone_select: null, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + timezone: '+0000', + hourMinOriginal: null, + minuteMinOriginal: null, + secondMinOriginal: null, + millisecMinOriginal: null, + hourMaxOriginal: null, + minuteMaxOriginal: null, + secondMaxOriginal: null, + millisecMaxOriginal: null, + ampm: '', + formattedDate: '', + formattedTime: '', + formattedDateTime: '', + timezoneList: null, + + /* Override the default settings for all instances of the time picker. + @param settings object - the new settings to use as defaults (anonymous object) + @return the manager object */ + setDefaults: function(settings) { + extendRemove(this._defaults, settings || {}); + return this; + }, + + //######################################################################## + // Create a new Timepicker instance + //######################################################################## + _newInst: function($input, o) { + var tp_inst = new Timepicker(), + inlineSettings = {}; + + for (var attrName in this._defaults) { + var attrValue = $input.attr('time:' + attrName); + if (attrValue) { + try { + inlineSettings[attrName] = eval(attrValue); + } catch (err) { + inlineSettings[attrName] = attrValue; + } + } + } + tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, { + beforeShow: function(input, dp_inst) { + if ($.isFunction(o.beforeShow)) + return o.beforeShow(input, dp_inst, tp_inst); + }, + onChangeMonthYear: function(year, month, dp_inst) { + // Update the time as well : this prevents the time from disappearing from the $input field. + tp_inst._updateDateTime(dp_inst); + if ($.isFunction(o.onChangeMonthYear)) + o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); + }, + onClose: function(dateText, dp_inst) { + if (tp_inst.timeDefined === true && $input.val() != '') + tp_inst._updateDateTime(dp_inst); + if ($.isFunction(o.onClose)) + o.onClose.call($input[0], dateText, dp_inst, tp_inst); + }, + timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); + }); + tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { return val.toUpperCase() }); + tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { return val.toUpperCase() }); + + if (tp_inst._defaults.timezoneList === null) { + var timezoneList = []; + for (var i = -11; i <= 12; i++) + timezoneList.push((i >= 0 ? '+' : '-') + ('0' + Math.abs(i).toString()).slice(-2) + '00'); + if (tp_inst._defaults.timezoneIso8609) + timezoneList = $.map(timezoneList, function(val) { + return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3)); + }); + tp_inst._defaults.timezoneList = timezoneList; + } + + tp_inst.hour = tp_inst._defaults.hour; + tp_inst.minute = tp_inst._defaults.minute; + tp_inst.second = tp_inst._defaults.second; + tp_inst.millisec = tp_inst._defaults.millisec; + tp_inst.ampm = ''; + tp_inst.$input = $input; + + if (o.altField) + tp_inst.$altInput = $(o.altField) + .css({ cursor: 'pointer' }) + .focus(function(){ $input.trigger("focus"); }); + + if(tp_inst._defaults.minDate==0 || tp_inst._defaults.minDateTime==0) + { + tp_inst._defaults.minDate=new Date(); + } + if(tp_inst._defaults.maxDate==0 || tp_inst._defaults.maxDateTime==0) + { + tp_inst._defaults.maxDate=new Date(); + } + + // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. + if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) + tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); + if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) + tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); + if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) + tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); + if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) + tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); + return tp_inst; + }, + + //######################################################################## + // add our sliders to the calendar + //######################################################################## + _addTimePicker: function(dp_inst) { + var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? + this.$input.val() + ' ' + this.$altInput.val() : + this.$input.val(); + + this.timeDefined = this._parseTime(currDT); + this._limitMinMaxDateTime(dp_inst, false); + this._injectTimePicker(); + }, + + //######################################################################## + // parse the time string from input value or _setTime + //######################################################################## + _parseTime: function(timeString, withDate) { + var regstr = this._defaults.timeFormat.toString() + .replace(/h{1,2}/ig, '(\\d?\\d)') + .replace(/m{1,2}/ig, '(\\d?\\d)') + .replace(/s{1,2}/ig, '(\\d?\\d)') + .replace(/l{1}/ig, '(\\d?\\d?\\d)') + .replace(/t{1,2}/ig, this._getPatternAmpm()) + .replace(/z{1}/ig, '(z|[-+]\\d\\d:?\\d\\d)?') + .replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$', + order = this._getFormatPositions(), + ampm = '', + treg; + + if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]); + + if (withDate || !this._defaults.timeOnly) { + // the time should come after x number of characters and a space. + // x = at least the length of text specified by the date format + var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); + // escape special regex characters in the seperator + var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); + regstr = '^.{' + dp_dateFormat.length + ',}?' + this._defaults.separator.replace(specials, "\\$&") + regstr; + } + + treg = timeString.match(new RegExp(regstr, 'i')); + + if (treg) { + if (order.t !== -1) { + if (treg[order.t] === undefined || treg[order.t].length === 0) { + ampm = ''; + this.ampm = ''; + } else { + ampm = $.inArray(treg[order.t].toUpperCase(), this.amNames) !== -1 ? 'AM' : 'PM'; + this.ampm = this._defaults[ampm == 'AM' ? 'amNames' : 'pmNames'][0]; + } + } + + if (order.h !== -1) { + if (ampm == 'AM' && treg[order.h] == '12') + this.hour = 0; // 12am = 0 hour + else if (ampm == 'PM' && treg[order.h] != '12') + this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12 + else this.hour = Number(treg[order.h]); + } + + if (order.m !== -1) this.minute = Number(treg[order.m]); + if (order.s !== -1) this.second = Number(treg[order.s]); + if (order.l !== -1) this.millisec = Number(treg[order.l]); + if (order.z !== -1 && treg[order.z] !== undefined) { + var tz = treg[order.z].toUpperCase(); + switch (tz.length) { + case 1: // Z + tz = this._defaults.timezoneIso8609 ? 'Z' : '+0000'; + break; + case 5: // +hhmm + if (this._defaults.timezoneIso8609) + tz = tz.substring(1) == '0000' + ? 'Z' + : tz.substring(0, 3) + ':' + tz.substring(3); + break; + case 6: // +hh:mm + if (!this._defaults.timezoneIso8609) + tz = tz == 'Z' || tz.substring(1) == '00:00' + ? '+0000' + : tz.replace(/:/, ''); + else if (tz.substring(1) == '00:00') + tz = 'Z'; + break; + } + this.timezone = tz; + } + + return true; + + } + return false; + }, + + //######################################################################## + // pattern for standard and localized AM/PM markers + //######################################################################## + _getPatternAmpm: function() { + var markers = []; + o = this._defaults; + if (o.amNames) + $.merge(markers, o.amNames); + if (o.pmNames) + $.merge(markers, o.pmNames); + markers = $.map(markers, function(val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') }); + return '(' + markers.join('|') + ')?'; + }, + + //######################################################################## + // figure out position of time elements.. cause js cant do named captures + //######################################################################## + _getFormatPositions: function() { + var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z)/g), + orders = { h: -1, m: -1, s: -1, l: -1, t: -1, z: -1 }; + + if (finds) + for (var i = 0; i < finds.length; i++) + if (orders[finds[i].toString().charAt(0)] == -1) + orders[finds[i].toString().charAt(0)] = i + 1; + + return orders; + }, + + //######################################################################## + // generate and inject html for timepicker into ui datepicker + //######################################################################## + _injectTimePicker: function() { + var $dp = this.inst.dpDiv, + o = this._defaults, + tp_inst = this, + // Added by Peter Medeiros: + // - Figure out what the hour/minute/second max should be based on the step values. + // - Example: if stepMinute is 15, then minMax is 45. + hourMax = parseInt((o.hourMax - ((o.hourMax - o.hourMin) % o.stepHour)) ,10), + minMax = parseInt((o.minuteMax - ((o.minuteMax - o.minuteMin) % o.stepMinute)) ,10), + secMax = parseInt((o.secondMax - ((o.secondMax - o.secondMin) % o.stepSecond)) ,10), + millisecMax = parseInt((o.millisecMax - ((o.millisecMax - o.millisecMin) % o.stepMillisec)) ,10), + dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, ''); + + // Prevent displaying twice + //if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) { + if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) { + var noDisplay = ' style="display:none;"', + html = '
      ' + + '
      ' + o.timeText + '
      ' + + '
      ' + + '
      ' + o.hourText + '
      ', + hourGridSize = 0, + minuteGridSize = 0, + secondGridSize = 0, + millisecGridSize = 0, + size; + + // Hours + html += '
      '; + if (o.showHour && o.hourGrid > 0) { + html += '
      '; + + for (var h = o.hourMin; h <= hourMax; h += parseInt(o.hourGrid,10)) { + hourGridSize++; + var tmph = (o.ampm && h > 12) ? h-12 : h; + if (tmph < 10) tmph = '0' + tmph; + if (o.ampm) { + if (h == 0) tmph = 12 +'a'; + else if (h < 12) tmph += 'a'; + else tmph += 'p'; + } + html += ''; + } + + html += '
      ' + tmph + '
      '; + } + html += '
      '; + + // Minutes + html += '
      ' + o.minuteText + '
      '+ + '
      '; + + if (o.showMinute && o.minuteGrid > 0) { + html += '
      '; + + for (var m = o.minuteMin; m <= minMax; m += parseInt(o.minuteGrid,10)) { + minuteGridSize++; + html += ''; + } + + html += '
      ' + ((m < 10) ? '0' : '') + m + '
      '; + } + html += '
      '; + + // Seconds + html += '
      ' + o.secondText + '
      '+ + '
      '; + + if (o.showSecond && o.secondGrid > 0) { + html += '
      '; + + for (var s = o.secondMin; s <= secMax; s += parseInt(o.secondGrid,10)) { + secondGridSize++; + html += ''; + } + + html += '
      ' + ((s < 10) ? '0' : '') + s + '
      '; + } + html += '
      '; + + // Milliseconds + html += '
      ' + o.millisecText + '
      '+ + '
      '; + + if (o.showMillisec && o.millisecGrid > 0) { + html += '
      '; + + for (var l = o.millisecMin; l <= millisecMax; l += parseInt(o.millisecGrid,10)) { + millisecGridSize++; + html += ''; + } + + html += '
      ' + ((l < 10) ? '0' : '') + l + '
      '; + } + html += '
      '; + + // Timezone + html += '
      ' + o.timezoneText + '
      '; + html += '
      '; + + html += '
      '; + $tp = $(html); + + // if we only want time picker... + if (o.timeOnly === true) { + $tp.prepend( + '
      ' + + '
      ' + o.timeOnlyTitle + '
      ' + + '
      '); + $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); + } + + this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({ + orientation: "horizontal", + value: this.hour, + min: o.hourMin, + max: hourMax, + step: o.stepHour, + slide: function(event, ui) { + tp_inst.hour_slider.slider( "option", "value", ui.value); + tp_inst._onTimeChange(); + } + }); + + + // Updated by Peter Medeiros: + // - Pass in Event and UI instance into slide function + this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({ + orientation: "horizontal", + value: this.minute, + min: o.minuteMin, + max: minMax, + step: o.stepMinute, + slide: function(event, ui) { + tp_inst.minute_slider.slider( "option", "value", ui.value); + tp_inst._onTimeChange(); + } + }); + + this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({ + orientation: "horizontal", + value: this.second, + min: o.secondMin, + max: secMax, + step: o.stepSecond, + slide: function(event, ui) { + tp_inst.second_slider.slider( "option", "value", ui.value); + tp_inst._onTimeChange(); + } + }); + + this.millisec_slider = $tp.find('#ui_tpicker_millisec_'+ dp_id).slider({ + orientation: "horizontal", + value: this.millisec, + min: o.millisecMin, + max: millisecMax, + step: o.stepMillisec, + slide: function(event, ui) { + tp_inst.millisec_slider.slider( "option", "value", ui.value); + tp_inst._onTimeChange(); + } + }); + + this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('').find("select"); + $.fn.append.apply(this.timezone_select, + $.map(o.timezoneList, function(val, idx) { + return $("
      + +{% endblock %} + +{% block head %} + + + + {% endblock %} diff --git a/tpl/base.html b/tpl/base.html index caa974f..9eddf8e 100644 --- a/tpl/base.html +++ b/tpl/base.html @@ -1,4 +1,6 @@ {% include 'base/head.html' %} +{% block head %}{% endblock %} + {% include 'base/sidebar.html' %}
      diff --git a/tpl/base/head.html b/tpl/base/head.html index 00ddddf..75a331b 100644 --- a/tpl/base/head.html +++ b/tpl/base/head.html @@ -5,5 +5,4 @@ {% if title %}{{ title }} - {% endif %}{{ page.settings['site_title'] }} - {% block head %}{% endblock %} - + From 6a67995d9575229b5d352df9f993aa590aac3f41 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Fri, 16 Mar 2012 03:04:28 +0800 Subject: [PATCH 23/56] contest page --- api.py | 27 ++++++++ backstage.py | 13 ++-- contest.py | 7 +- handlers.py | 9 ++- judge/db/__init__.py | 28 +++++--- less/style.less | 32 ++++----- problem.py | 6 +- static/css/style.css | 26 ++++---- tpl/backstage/add_contest.html | 18 +++-- tpl/backstage/add_problem.html | 2 +- tpl/base/head.html | 1 + tpl/contest.html | 118 +++++++++++++++++++++++++++++++++ tpl/problem.html | 13 ++-- 13 files changed, 234 insertions(+), 66 deletions(-) create mode 100644 api.py create mode 100644 tpl/contest.html diff --git a/api.py b/api.py new file mode 100644 index 0000000..a051f44 --- /dev/null +++ b/api.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: api.py +# CREATED: 00:26:38 16/03/2012 +# MODIFIED: 00:30:53 16/03/2012 + +from tornado.web import HTTPError +from tornado.web import authenticated + +from judge.db import Problem +from judge.db import ProblemDBMixin +from judge.base import BaseHandler + +class GetProblemHandler(BaseHandler, ProblemDBMixin): + @authenticated + def get(self, pid): + try: + pid = int(pid) + except ValueError: + raise HTTPError(404) + problem = self.select_problem_by_id(pid) + if not problem: + raise HTTPError(404) + self.write(problem.title) + self.finish() + +__all__ = ["GetProblemHandler"] diff --git a/backstage.py b/backstage.py index f1781ba..5ff6c96 100644 --- a/backstage.py +++ b/backstage.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: backstage.py # CREATED: 02:43:49 15/03/2012 -# MODIFIED: 15:53:23 15/03/2012 +# MODIFIED: 03:02:17 16/03/2012 import datetime import functools @@ -95,10 +95,7 @@ def get(self): if cid: contest = self.select_contest_by_id(cid) title = self._("Edit Contest") - related_problem_id = self.select_contest_problem_by_contest_id(contest.id) - related_problem = [] - for pid in related_problem_id: - related_problem.append(self.select_problem_by_id(pid)) + related_problem = self.select_contest_problem_by_contest_id(contest.id) self.render("backstage/add_contest.html", locals()) @backstage def post(self): @@ -139,11 +136,11 @@ def post(self): contest.end_time = end_datetime if contest.id: self.update_contest(contest) - self.delete_contest_problem_by_cid(contest.id) + self.delete_contest_problem_by_contest_id(contest.id) else: self.insert_contest(contest) for pid in contest.related_problem: - self.insert_contest_problem(cid = contest.id, pid = pid) + self.insert_contest_problem(contest.id, pid) self.redirect("/contest/%d" % int(contest.id)) -__all__ = ["AddProblemHandler", "AddContestHandler"] +__all__ = ["backstage", "AddProblemHandler", "AddContestHandler"] diff --git a/contest.py b/contest.py index e040188..95ed1bb 100644 --- a/contest.py +++ b/contest.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: contest.py # CREATED: 15:46:17 15/03/2012 -# MODIFIED: 15:46:36 15/03/2012 +# MODIFIED: 02:48:49 16/03/2012 import datetime @@ -24,6 +24,9 @@ def get(self, cid): if not contest: raise HTTPError(404) now = datetime.datetime.now() + problems = self.select_contest_problem_by_contest_id(cid) + for problem in problems: + problem.submit = self.select_contest_submit_by_contest_id_problem_id_user_id(cid, problem.problem_id) self.render("contest.html", locals()) class ListContestHandlder(BaseHandler, ContestDBMixin): @@ -43,4 +46,4 @@ def get(self): pages = self.get_page_count(count) self.render("contest_list.html", locals()) -__all__ = ["ViewContestHandler"] +__all__ = ["ViewContestHandler", "ListContestHandlder"] diff --git a/handlers.py b/handlers.py index 6bd87fc..24dd8fb 100644 --- a/handlers.py +++ b/handlers.py @@ -2,13 +2,15 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 15:54:23 15/03/2012 +# MODIFIED: 01:14:36 16/03/2012 # DESCRIPTION: URL Route +from api import * from home import * from lang import * from member import * from problem import * +from contest import * from backstage import * ''' @@ -24,8 +26,11 @@ (r'/settings/changepass', ChangePasswordHandler), (r'/member/(.*)', MemberHandler), (r'/lang/(.*)', SetLanguageHandler), - (r'/problem', ProblemListHandler), + (r'/problem', ListProblemHandler), (r'/problem/([\d]*)', ViewProblemHandler), (r'/backstage/problem/add', AddProblemHandler), (r'/backstage/contest/add', AddContestHandler), + (r'/contest', ListContestHandlder), + (r'/contest/([\d]*)', ViewContestHandler), + (r'/api/problem/get/([\d]*)', GetProblemHandler), ] diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 0385359..eeaadb4 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 15:53:03 15/03/2012 +# MODIFIED: 02:50:48 16/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -349,7 +349,11 @@ def _new_contest(self, row): def _new_contest_problem(self, row): contest_problem = ContestProblem() contest_problem._init_row(row) - return contest + return contest_problem + def _new_contest_submit(self, row): + contest_submit = ContestSubmit() + contest_submit._init_row(row) + return contest_submit ''' COUNT ''' def count_contest(self): row = self.db.get("""SELECT COUNT(*) FROM `contest`""") @@ -358,17 +362,25 @@ def count_visible_contest(self): row = self.db.get("""SELECT COUNT(*) FROM `contest` WHERE invisible = 0""") return row["COUNT(*)"] ''' SELECT ''' - def select_countest_by_id(contest_id): + def select_contest_by_id(self, contest_id): row = self.db.get("""SELECT * FROM `contest` WHERE `id` = %s""", contest_id) if row: return self._new_contest(row) return None - def select_contest_problem_by_contest_id(contest_id): - rows = self.db.query("""SELECT * FROM `contest_problem` WHERE `contest_id` = %s""", contest_id) + def select_contest_problem_by_contest_id(self, contest_id): + rows = self.db.query("""SELECT *, `problem`.* FROM `contest_problem` + LEFT JOIN `problem` ON `contest_problem`.`problem_id` = `problem`.`id` + WHERE `contest_id` = %s""", contest_id) result = [] for row in rows: result.append(self._new_contest_problem(row)) return result + def select_contest_submit_by_contest_id_problem_id_user_id(self, contest_id, problem_id): + row = self.db.get("""SELECT * FROM `contest_submit` WHERE `contest_id` = %s AND `problem_id` = %s AND `member_id` = %s""", \ + contest_id, problem_id, self.current_user.id) + if row: + return self._new_contest_submit(row) + return None def select_countest(self, start = 0, count = 20): rows = self.db.query("""SELECT * FROM `contest` LIMIT %s, %s""", start, count) result = [] @@ -388,8 +400,8 @@ def insert_contest(self, contest): VALUES (%s, %s, %s, %s, %s, UTC_TIMESTAMP())""", \ contest.title, contest.description, contest.start_time, contest.end_time, \ contest.invisible) - def insert_contest_problem(self, contest_problem): - self.db.execute("""INSERT INTO `contest_problem` (`contest_id`, `problem_id`) VALUES (%s, %s)""", int(cid), int(pid)) + def insert_contest_problem(self, contest_id, problem_id): + self.db.execute("""INSERT INTO `contest_problem` (`contest_id`, `problem_id`) VALUES (%s, %s)""", int(contest_id), int(problem_id)) ''' UPDATE ''' def update_contest(self, contest): self.db.execute("""UPDATE `contest` SET `title` = %s, @@ -402,6 +414,6 @@ def update_contest(self, contest): contest.invisible, contest.id) ''' DELETE ''' def delete_contest_problem_by_contest_id(self, contest_id): - self.db.execute("""DELETE FROM `contest_problem` WHERE `cid` = %s""", cid) + self.db.execute("""DELETE FROM `contest_problem` WHERE `contest_id` = %s""", contest_id) ''' OTHER ''' diff --git a/less/style.less b/less/style.less index bd93403..93d47c3 100644 --- a/less/style.less +++ b/less/style.less @@ -149,7 +149,7 @@ form.cell fieldset .title { padding-top: 20px; } -.tagclound { +.tagcloud { list-style: none; margin-left: 0; margin-top: 10px; @@ -176,6 +176,20 @@ form.cell fieldset .title { } } +.table-info tr { + + &:hover { + td, th { + background-color: #FAFAFA; + } + } + + th { + text-align: right; + width: 13%; + } + } + /* Navigator Style */ nav { @@ -310,25 +324,11 @@ nav { .signleproblem { - .table tr { - - &:hover { - td, th { - background-color: #FAFAFA; - } - } - - th { - text-align: right; - width: 13%; - } - } - .title { padding-left: 20px; } - .tagclound { + .tagcloud { margin-top: 0; .tag { diff --git a/problem.py b/problem.py index f64f4af..a1f9be7 100644 --- a/problem.py +++ b/problem.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 14:19:53 15/03/2012 +# MODIFIED: 01:14:52 16/03/2012 from tornado.web import HTTPError @@ -29,7 +29,7 @@ def get(self, pid): tags = self.select_problem_tag_by_problem_id(problem.id) self.render("problem.html", locals()) -class ProblemListHandler(BaseHandler, ProblemDBMixin): +class ListProblemHandler(BaseHandler, ProblemDBMixin): def get(self): start = self.get_argument("start", default = 0) try: @@ -49,4 +49,4 @@ def get(self): pages = self.get_page_count(count) self.render("problem_list.html", locals()) -__all__ = ["ViewProblemHandler", "ProblemListHandler"] +__all__ = ["ViewProblemHandler", "ListProblemHandler"] diff --git a/static/css/style.css b/static/css/style.css index a8444f7..38bbadc 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3816,12 +3816,12 @@ form.cell fieldset .title { padding-left: 20px; padding-top: 20px; } -.tagclound { +.tagcloud { list-style: none; margin-left: 0; margin-top: 10px; } -.tagclound .tag { +.tagcloud .tag { -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; @@ -3831,7 +3831,7 @@ form.cell fieldset .title { margin-right: 4px; margin-bottom: 5px; } -.tagclound .tag a { +.tagcloud .tag a { color: black; } .pagination { @@ -3840,6 +3840,14 @@ form.cell fieldset .title { .pagination ul { background-color: white; } +.table-info tr:hover td, +.table-info tr:hover th { + background-color: #FAFAFA; +} +.table-info tr th { + text-align: right; + width: 13%; +} /* Navigator Style */ nav { -webkit-box-shadow: 0px 0px 5px #000000; @@ -3967,21 +3975,13 @@ nav .copyright a { text-align: right; } /* Single Problem Page Style */ -.signleproblem .table tr:hover td, -.signleproblem .table tr:hover th { - background-color: #FAFAFA; -} -.signleproblem .table tr th { - text-align: right; - width: 13%; -} .signleproblem .title { padding-left: 20px; } -.signleproblem .tagclound { +.signleproblem .tagcloud { margin-top: 0; } -.signleproblem .tagclound .tag { +.signleproblem .tagcloud .tag { padding-right: 10px; } /* Member Page */ diff --git a/tpl/backstage/add_contest.html b/tpl/backstage/add_contest.html index 20abd2a..8fa0b79 100644 --- a/tpl/backstage/add_contest.html +++ b/tpl/backstage/add_contest.html @@ -33,11 +33,11 @@
      {{ _('Add') }} -
      {% if user %}
      From 424bf4b534a85672f6d15d7502249bdefbe1b34a Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Fri, 16 Mar 2012 03:20:45 +0800 Subject: [PATCH 24/56] contest list --- contest.py | 9 ++++++++- judge/db/__init__.py | 4 ++-- tpl/contest_list.html | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 tpl/contest_list.html diff --git a/contest.py b/contest.py index 95ed1bb..573d375 100644 --- a/contest.py +++ b/contest.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: contest.py # CREATED: 15:46:17 15/03/2012 -# MODIFIED: 02:48:49 16/03/2012 +# MODIFIED: 03:19:13 16/03/2012 import datetime @@ -27,6 +27,10 @@ def get(self, cid): problems = self.select_contest_problem_by_contest_id(cid) for problem in problems: problem.submit = self.select_contest_submit_by_contest_id_problem_id_user_id(cid, problem.problem_id) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Contest'), '/contest')) + breadcrumb.append((contest.title, '/contest/%d' % contest.id)) self.render("contest.html", locals()) class ListContestHandlder(BaseHandler, ContestDBMixin): @@ -43,6 +47,9 @@ def get(self): else: count = self.count_visible_contest() contests = self.select_visible_contest(start = start) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Contest'), '/contest')) pages = self.get_page_count(count) self.render("contest_list.html", locals()) diff --git a/judge/db/__init__.py b/judge/db/__init__.py index eeaadb4..8fccf2a 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 02:50:48 16/03/2012 +# MODIFIED: 03:13:19 16/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -381,7 +381,7 @@ def select_contest_submit_by_contest_id_problem_id_user_id(self, contest_id, pro if row: return self._new_contest_submit(row) return None - def select_countest(self, start = 0, count = 20): + def select_contest(self, start = 0, count = 20): rows = self.db.query("""SELECT * FROM `contest` LIMIT %s, %s""", start, count) result = [] for row in rows: diff --git a/tpl/contest_list.html b/tpl/contest_list.html new file mode 100644 index 0000000..76683d5 --- /dev/null +++ b/tpl/contest_list.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} + +{% block body %} +
      +
      {{ _('Contest List') }}
      +
      + + + + + + + + + + + + {% for contest in contests %} + {% if contest.invisible == 0 or user.admin == 1%} + + + + + + + + {% endif %} + {% endfor %} + +
      #{{ _('Title') }}{{ _('Start Time') }}{{ _('End time') }}{{ _('Status') }}
      {{ contest.id }}{{ contest.title }}{{ contest.start_time }}{{ contest.end_time }}
      +
      +
      +{% include 'count.html' %} +{% endblock %} From 8c61cfa8f43086818eb3aa7d3ac9fddc7ba762fc Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Fri, 16 Mar 2012 21:52:57 +0800 Subject: [PATCH 25/56] finish status icon --- contest.py | 20 +++++++++++++++++++- handlers.py | 2 +- judge/db/__init__.py | 12 +++++++++++- judge/filters/__init__.py | 31 ++++++++++++++++++++++++++++++- problem.py | 7 +++++-- tpl/contest.html | 4 ++-- tpl/contest_list.html | 2 +- tpl/macros.html | 4 +++- tpl/problem_list.html | 2 ++ 9 files changed, 74 insertions(+), 10 deletions(-) diff --git a/contest.py b/contest.py index 573d375..2e7820c 100644 --- a/contest.py +++ b/contest.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: contest.py # CREATED: 15:46:17 15/03/2012 -# MODIFIED: 03:19:13 16/03/2012 +# MODIFIED: 14:50:32 16/03/2012 import datetime @@ -13,6 +13,21 @@ from judge.db import ContestDBMixin from judge.base import BaseHandler +def get_contest_status(contest): + status = 0 + now = datetime.datetime.now() + if now >= contest.start_time and now <= contest.end_time: + status = 1 #"Running" + elif now <= contest.start_time: + status = 2 #"Waiting" + elif now >= contest.end_time: + status = 3 #"Finished" + if contest.invisible: + status = 4 #"Invisible" + if not status: + status = 5 #"Unknown" + return status + class ViewContestHandler(BaseHandler, ContestDBMixin): @authenticated def get(self, cid): @@ -24,6 +39,7 @@ def get(self, cid): if not contest: raise HTTPError(404) now = datetime.datetime.now() + contest.status = get_contest_status(contest) problems = self.select_contest_problem_by_contest_id(cid) for problem in problems: problem.submit = self.select_contest_submit_by_contest_id_problem_id_user_id(cid, problem.problem_id) @@ -51,6 +67,8 @@ def get(self): breadcrumb.append((self._('Home'), '/')) breadcrumb.append((self._('Contest'), '/contest')) pages = self.get_page_count(count) + for contest in contests: + contest.status = get_contest_status(contest) self.render("contest_list.html", locals()) __all__ = ["ViewContestHandler", "ListContestHandlder"] diff --git a/handlers.py b/handlers.py index 24dd8fb..2b38f4b 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 01:14:36 16/03/2012 +# MODIFIED: 21:52:34 16/03/2012 # DESCRIPTION: URL Route from api import * diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 8fccf2a..f0ae2fc 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 03:13:19 16/03/2012 +# MODIFIED: 14:00:26 16/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -238,6 +238,10 @@ def _new_problem_tag(self, row): problem_tag = ProblemTag() problem_tag._init_row(row) return problem_tag + def _new_submit(self, row): + submit = Submit() + submit._init_row(row) + return submit ''' COUNT ''' def count_problem(self): count = self.db.get("""SELECT COUNT(*) FROM `problem`""") @@ -272,6 +276,12 @@ def select_visible_problem_order_by_id(self, count = 10, start = 0): for row in rows: result.append(self._new_problem(row)) return result + def select_last_submit_by_problem_id_member_id(self, problem_id): + row = self.db.get("""SELECT * FROM `submit` WHERE `problem_id` = %s AND `member_id` = %s ORDER BY `id` DESC LIMIT 1""", \ + problem_id, self.current_user.id) + if row: + return self._new_submit(row) + return None ''' INSERT ''' def insert_problem(self, problem): problem.id = self.db.execute("""INSERT INTO `problem` (`title`, `shortname`, `content`, \ diff --git a/judge/filters/__init__.py b/judge/filters/__init__.py index 0ec7f90..852155e 100644 --- a/judge/filters/__init__.py +++ b/judge/filters/__init__.py @@ -2,11 +2,12 @@ # AUTHOR: Zeray Rice # FILE: judge/filters/__init__.py # CREATED: 01:48:10 08/03/2012 -# MODIFIED: 16:00:06 15/03/2012 +# MODIFIED: 14:50:10 16/03/2012 # DESCRIPTION: jinja2 filters import re import string +import datetime # Configuration for urlize() function LEADING_PUNCTUATION = ['(', '<', '<'] @@ -21,6 +22,23 @@ '|'.join([re.escape(x) for x in TRAILING_PUNCTUATION]))) simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$') +CONTEST_STATUS = { + 1 : ("success", "Running"), + 2 : ("info", "Waiting"), + 3 : ("default", "Finished"), + 4 : ("warning", "Invisible"), + 5 : ("important", "Unknown"), +} +SUBMIT_STATUS = { + 0 : ("info", "Pending"), + 1 : ("success", "Accepted"), + 2 : ("important", "Wrong Answer"), + 3 : ("warning", "Time Limit Exceeded"), + 4 : ("warning", "Memory Limit Exceeded"), + 5 : ("inverse", "Runtime Error"), + 6 : ("default", "Compile Error"), +} + def autolink(text, trim_url_limit=None, nofollow=False): """ Converts any URLs in text into clickable links. Works on http://, https:// and @@ -99,6 +117,15 @@ def get_page_nav(pages, start): def datetimeformat(value, format='%m/%d/%Y %H:%M'): return value.strftime(format) +def get_contest_status(contest): + return "%s" % (CONTEST_STATUS[contest.status]) + +def get_submit_status(submit): + if not submit: + return "-" + cla, status = SUBMIT_STATUS[submit.status] + return "%s" % (cla, status) + filters = { 'autolink' : autolink, 'avatar_img' : avatar_img, @@ -106,4 +133,6 @@ def datetimeformat(value, format='%m/%d/%Y %H:%M'): 'get_next_page' : get_next_page, 'get_page_nav' : get_page_nav, 'datetimeformat' : datetimeformat, + 'get_contest_status' : get_contest_status, + 'get_submit_status' : get_submit_status, } diff --git a/problem.py b/problem.py index a1f9be7..e0ca594 100644 --- a/problem.py +++ b/problem.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 01:14:52 16/03/2012 +# MODIFIED: 14:00:51 16/03/2012 from tornado.web import HTTPError @@ -45,8 +45,11 @@ def get(self): problems = self.select_problem_order_by_id(10, start) else: count = self.count_visible_problem() - problems = self.select_problem_order_by_id_visible(10, start) + problems = self.select_visible_problem_order_by_id(10, start) pages = self.get_page_count(count) + if self.current_user: + for problem in problems: + problem.submit = self.select_last_submit_by_problem_id_member_id(problem.id) self.render("problem_list.html", locals()) __all__ = ["ViewProblemHandler", "ListProblemHandler"] diff --git a/tpl/contest.html b/tpl/contest.html index 8a4747b..00e01f8 100644 --- a/tpl/contest.html +++ b/tpl/contest.html @@ -25,7 +25,7 @@ {{ _('Status') }} - + {{ contest | get_contest_status }}
      @@ -67,7 +67,7 @@ -{% if user %} +{% if (user and contest.status == 1) or user.admin %}
      {{ _('Submit Problem') }}
      diff --git a/tpl/contest_list.html b/tpl/contest_list.html index 76683d5..3164613 100644 --- a/tpl/contest_list.html +++ b/tpl/contest_list.html @@ -22,7 +22,7 @@ {{ contest.title }} {{ contest.start_time }} {{ contest.end_time }} - + {{ contest | get_contest_status }} {% endif %} {% endfor %} diff --git a/tpl/macros.html b/tpl/macros.html index 22766a6..5c84fab 100644 --- a/tpl/macros.html +++ b/tpl/macros.html @@ -1,3 +1,5 @@ +{#================ List ================#} + {% macro show_error_list(error) %} {%- if error -%}
      @@ -35,7 +37,7 @@ {% macro show_contest_list(contest_list) %} {% endmacro %} -{#================ Form ================#} +{#================ Form ================#} {% macro input(name, label, value = '', type = 'TEXT', class = 'input-xlarge', default = '', addon = '') %}
      diff --git a/tpl/problem_list.html b/tpl/problem_list.html index dab6674..2b56fb2 100644 --- a/tpl/problem_list.html +++ b/tpl/problem_list.html @@ -12,6 +12,7 @@ {{ _('Time') }} {{ _('Memory') }} {{ _('Short Name') }} + {% if user %}{{ _('Status') }}{% endif %} @@ -23,6 +24,7 @@ {{ problem.timelimit }} ms {{ problem.memlimit }} MB {{ problem.shortname }} + {% if user %}{{ problem.submit | get_submit_status }}{% endif %} {% endif %} {% endfor %} From 18405d31cc2c60445513fa77a58f86777b37245f Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Sun, 18 Mar 2012 03:07:20 +0800 Subject: [PATCH 26/56] start write judge daemon --- .gitignore | 2 + backstage.py | 61 ++++++++++++++++++++++++++++++- daemons/celeryconfig.example.py | 11 ++++++ daemons/config.example.py | 17 +++++++++ daemons/daemons.py | 41 +++++++++++++++++++++ daemons/tasks.py | 65 +++++++++++++++++++++++++++++++++ handlers.py | 4 +- judge/base/__init__.py | 10 ++++- judge/db/__init__.py | 48 +++++++++++++++++++++++- less/style.less | 24 ++++++++---- static/css/style.css | 40 +++++++++++++++----- tpl/backstage/add_judger.html | 21 +++++++++++ tpl/backstage/judger.html | 35 ++++++++++++++++++ tpl/base/sidebar.html | 6 +++ 14 files changed, 363 insertions(+), 22 deletions(-) create mode 100644 daemons/celeryconfig.example.py create mode 100644 daemons/config.example.py create mode 100644 daemons/daemons.py create mode 100644 daemons/tasks.py create mode 100644 tpl/backstage/add_judger.html create mode 100644 tpl/backstage/judger.html diff --git a/.gitignore b/.gitignore index 83fff87..57468a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.pyc config.py +celeryconfig.py +privekey.key upload/ diff --git a/backstage.py b/backstage.py index 5ff6c96..f676e1c 100644 --- a/backstage.py +++ b/backstage.py @@ -2,15 +2,18 @@ # AUTHOR: Zeray Rice # FILE: backstage.py # CREATED: 02:43:49 15/03/2012 -# MODIFIED: 03:02:17 16/03/2012 +# MODIFIED: 02:13:40 18/03/2012 +import re import datetime import functools from tornado.web import HTTPError +from judge.db import Judger from judge.db import Contest from judge.db import Problem +from judge.db import JudgerDBMixin from judge.db import ContestDBMixin from judge.db import ProblemDBMixin from judge.base import BaseHandler @@ -143,4 +146,58 @@ def post(self): self.insert_contest_problem(contest.id, pid) self.redirect("/contest/%d" % int(contest.id)) -__all__ = ["backstage", "AddProblemHandler", "AddContestHandler"] +class ManageJudgerHandler(BaseHandler, JudgerDBMixin): + @backstage + def get(self): + title = self._("Judger Manage") + judgers = self.select_judgers() + self.render("backstage/judger.html", locals()) + +class AddJudgerHandler(BaseHandler, JudgerDBMixin): + @backstage + def get(self): + title = self._("Add Judger") + jid = self.get_argument("jid", default = 0) + judger = None + try: + jid = int(jid) + except ValueError: + raise HTTPError(404) + if jid: + judger = self.select_judger_by_id(jid) + if not judger: + raise HTTPError(404) + title = self._("Edit Judger") + self.render("backstage/add_judger.html", locals()) + @backstage + def post(self): + name = self.get_argument("name", default = "") + description = self.get_argument("description", default = "") + path = self.get_argument("path", default = "") + priority = self.get_argument("priority", default = 0) + pubkey = self.get_argument("pubkey", default = "") + jid = self.get_argument("jid", default = 0) + judger = Judger() + error = [] + error.extend(self.check_text_value(name, self._("Name"), required = True, min = 1, max = 100)) + error.extend(self.check_text_value(description, self._("Description"), max = 5000)) + error.extend(self.check_text_value(path, self._("Path"), required = True, regex = re.compile(r"^http://(.*)"), max = 200)) + error.extend(self.check_text_value(priority, self._("Priority"), is_num = True)) + error.extend(self.check_text_value(pubkey, self._("RSA Public Key"), required = True)) + judger.id = jid + judger.name = self.xhtml_escape(name) + judger.description = self.xhtml_escape(description) + judger.path = self.xhtml_escape(path) + judger.priority = priority + judger.pubkey = self.xhtml_escape(pubkey) + if error: + title = self._("Edit Judger") + self.render("backstage/add_judger.html", locals()) + return + if judger.id: + self.update_judger(judger) + else: + self.insert_judger(judger) + self.redirect("/backstage/judger") + +__all__ = ["backstage", "AddProblemHandler", "AddContestHandler", "ManageJudgerHandler", "AddJudgerHandler"] diff --git a/daemons/celeryconfig.example.py b/daemons/celeryconfig.example.py new file mode 100644 index 0000000..b9b859f --- /dev/null +++ b/daemons/celeryconfig.example.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: celeryconfig.py +# CREATED: 02:26:56 17/03/2012 +# MODIFIED: 02:58:41 17/03/2012 + +CELERY_RESULT_BACKEND = "amqp" +CELERYD_CONCURRENCY = 1 +BROKER_URL = "amqp://guest:guest@localhost:5672/" + +CELERY_IMPORTS = ("tasks", ) diff --git a/daemons/config.example.py b/daemons/config.example.py new file mode 100644 index 0000000..96675b0 --- /dev/null +++ b/daemons/config.example.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: config.py +# CREATED: 02:35:44 18/03/2012 +# MODIFIED: 03:05:45 18/03/2012 + +import rsa + +COMPILE_DIR = "" +TESTDATA_DIR = "" +DAEMON_PORT = 8889 + +RSA_PRIVKEY_PATH = "" +RSA_PRIVKEY = "" + +with open(RSA_PRIVKEY_PATH, "r") as rsafp: + RSA_PRIVKEY = rsa.PrivateKey.load_pkcs1(rsafp.read()) diff --git a/daemons/daemons.py b/daemons/daemons.py new file mode 100644 index 0000000..32ba723 --- /dev/null +++ b/daemons/daemons.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: daemons.py +# CREATED: 02:48:06 18/03/2012 +# MODIFIED: 02:59:28 18/03/2012 + +import rsa +import simplejson + +import tornado.web +import tornado.ioloop +from tornado.web import HTTPError + +from tasks import judge +from config import DAEMON_PORT +from config import RSA_PRIVKEY + +REQURED_ARGS = ["code", "lang", "filename", "shortname", "timelimit", "memlimit"] + +class ReceiveQueryHandler(tornado.web.RequestHandler): + def post(self): + query = self.get_argument("query", default = None) + if not query: + raise HTTPError(404) + try: + query = rsa.decrypt(query, RSA_PRIVKEY) + except: + raise HTTPError(404) + query = simplejson.loads(query) + for key in REQURED_ARGS: + if key not in query.keys(): + raise HTTPError(404) + judge.delay(query) + +application = tornado.web.Application([ + (r"/", ReceiveQueryHandler), +]) + +if __name__ == "__main__": + application.listen(int(DAEMON_PORT)) + tornado.ioloop.IOLoop.instance().start() diff --git a/daemons/tasks.py b/daemons/tasks.py new file mode 100644 index 0000000..d7cd90f --- /dev/null +++ b/daemons/tasks.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: tasks.py +# CREATED: 02:27:12 17/03/2012 +# MODIFIED: 03:02:01 18/03/2012 + +import os +import subprocess +from time import sleep +from celery.task import task + +from config import COMPILE_DIR +from config import TESTDATA_DIR + +def _clean(dir_path): + for root, dirs, files in os.walk(dir_path): + for name in files: + os.remove(os.path.join(root, name)) + +def _compile_cmd(lang, filename): + lang = int(lang) + if lang == 1: + return "fpc %s -So -XS -v0 -O1 -o\"a.out\"" % filename + elif lang == 2: + return "gcc %s -lm -w -static -o a.out" % filename + elif lang == 3: + return "g++ %s -lm -static -o a.out" % filename + +def _compile(result, query): + _clean(COMPILE_DIR) + os.chdir(COMPILE_DIR) + with open(COMPILE_DIR + query['filename'], "w+") as code: + code.write(query['code']) + cmd = " ".join(["timeout 30", _compile_cmd(query['lang'], query['filename'])]) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + (stdoutput,erroutput) = proc.communicate() + result['msg'] = "".join(["STDOUT:\n--------\n", stdoutput, "\n--------\nSTDERR\n--------\n", erroutput]) + result['cmd'] = cmd + if proc.returncode != 0: + result["compilesucc"] = 0 + else: + result["compilesucc"] = 1 + return result + +def _run(result, query): + pass + +''' + +Query String Format: + +code - Required. Code file content. +lang - Required. Code language. ( 1 - Pascal, 2 - C, 3 - C++ ) +filename - Required. Code file filename. +shortname - Required. Problem shortname. +timelimit - Required. Problem time limit. (MB) +memlimit - Required. Problem memory limit.(ms) + +''' + +@task +def judge(query): + result = {} + _compile(result, query) + return 0 diff --git a/handlers.py b/handlers.py index 2b38f4b..24e9ffb 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 21:52:34 16/03/2012 +# MODIFIED: 01:36:47 18/03/2012 # DESCRIPTION: URL Route from api import * @@ -30,6 +30,8 @@ (r'/problem/([\d]*)', ViewProblemHandler), (r'/backstage/problem/add', AddProblemHandler), (r'/backstage/contest/add', AddContestHandler), + (r'/backstage/judger', ManageJudgerHandler), + (r'/backstage/judger/add', AddJudgerHandler), (r'/contest', ListContestHandlder), (r'/contest/([\d]*)', ViewContestHandler), (r'/api/problem/get/([\d]*)', GetProblemHandler), diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 7388d3f..a41e754 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,10 +2,12 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 15:41:54 15/03/2012 +# MODIFIED: 02:26:46 18/03/2012 # DESCRIPTION: Base handler import re +import rsa +import urllib import hashlib import httplib import datetime @@ -14,6 +16,7 @@ import tornado.web import tornado.escape +from tornado.httpclient import AsyncHTTPClient from judge.db import Member from judge.utils import _len @@ -152,6 +155,11 @@ def check_email(self, email, queryDB = False): def get_gravatar_url(self, email): gravatar_id = hashlib.md5(email.lower()).hexdigest() return "http://www.gravatar.com/avatar/%s?d=mm" % (gravatar_id) + def post_to_judger(self, post_arg, judger, callback = None): + query_string = "&".join(["%s=%s" % (k,a[k]) for k in a.keys()]) + encrypt = rsa.encrypt(query_string, rsa.PublicKey.load_pkcs1(judger.pubkey)) + http_client = AsyncHTTPClient() + http_client.fetch(judger.path, method = "POST", body = urllib.urlencode({"query" : encrypt}), callback = callback) @property def db(self): return self.application.db diff --git a/judge/db/__init__.py b/judge/db/__init__.py index f0ae2fc..0471d8d 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 14:00:26 16/03/2012 +# MODIFIED: 02:08:56 18/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -427,3 +427,49 @@ def delete_contest_problem_by_contest_id(self, contest_id): self.db.execute("""DELETE FROM `contest_problem` WHERE `contest_id` = %s""", contest_id) ''' OTHER ''' +class Judger(BaseDBObject): + '''Contest problem table''' + __tablename__ = "judge" + id = 0 + name = "" + description = "" + path = "" # support HTTP protocol + priority = 0 + queue_num = 0 + pubkey = "" + create = None + +class JudgerDBMixin(BaseDBMixin): + ''' New Data Model ''' + def _new_judger(self, row): + judger = Judger() + judger._init_row(row) + return judger + ''' SELECT ''' + def select_judgers(self): + rows = self.db.query("""SELECT * FROM `judger`""") + result = [] + for row in rows: + result.append(self._new_judger(row)) + return result + def select_judger_by_id(self, juder_id): + row = self.db.get("""SELECT * FROM `judger` WHERE `id` = %s""", juder_id) + if row: + return self._new_judger(row) + return None + ''' INSERT ''' + def insert_judger(self, judger): + judger.id = self.db.execute("""INSERT INTO `judger` (`name`, `description`, `path`, `priority`, `queue_num`, `pubkey`, `create`) + VALUES (%s, %s, %s, 0, %s, UTC_TIMESTAMP())""", \ + judger.name, judger.description, judger.path, judger.pubkey) + ''' UPDATE ''' + def update_judger(self, judger): + self.db.execute("""UPDATE `judger` SET `name` = %s, + `description` = %s, + `path` = %s, + `priority` = %s, + `pubkey` = %s + WHERE `id` = %s""", \ + judger.name, judger.description, judger.path, judger.priority, judger.pubkey, judger.id) + def update_judger_count(self, judger): + self.db.execute("""UPDATE `judger` SET `queue_num` = 0 WHERE `id` = %s""", judger.id) diff --git a/less/style.less b/less/style.less index 93d47c3..de7adae 100644 --- a/less/style.less +++ b/less/style.less @@ -98,26 +98,37 @@ body { height: 30px; } +.breadcrumb { + #gradient > .vertical(rgb(235,235,235), rgb(229,229,229)); +} + .cell { .border-radius(4px); - .box-shadow(0px 1px 2px rgba(0, 0, 0, 0.15)); - border: 2px solid #EEE; + .box-shadow(0px 1px 3px rgba(0, 0, 0, 0.2)); margin-bottom: 30px; background-color: white; + border-top: 1px solid #FAFAFA; .title { - .top-border-radius(4px); + .top-border-radius(4px); + #gradient > .vertical(rgb(235,235,235), rgb(229,229,229)); font-size: 16px; font-weight: bold; line-height: 30px; padding-left: 10px; padding-top: 5px; - border-bottom: 1px solid #DDD; + color: #898989; + text-shadow: 0 1px 0 #fff; .fr { float: right; margin-right: 10px; font-weight: normal; + + a { + color: #898989; + font-size: 14px; + } } } @@ -145,8 +156,8 @@ body { } form.cell fieldset .title { - padding-left: 20px; - padding-top: 20px; +// padding-left: 20px; +// padding-top: 20px; } .tagcloud { @@ -276,7 +287,6 @@ nav { &:hover { background: rgba(0, 0, 0, 0.2); - color: white; text-shadow: 0px 1px 1px black; } } diff --git a/static/css/style.css b/static/css/style.css index 38bbadc..fda9272 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3763,16 +3763,27 @@ body { .sep30 { height: 30px; } +.breadcrumb { + background-color: #e9e9e9; + background-image: -moz-linear-gradient(top, #ebebeb, #e5e5e5); + background-image: -ms-linear-gradient(top, #ebebeb, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ebebeb), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #ebebeb, #e5e5e5); + background-image: -o-linear-gradient(top, #ebebeb, #e5e5e5); + background-image: linear-gradient(top, #ebebeb, #e5e5e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb', endColorstr='#e5e5e5', GradientType=0); +} .cell { -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; - -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15); - box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15); - border: 2px solid #EEE; + -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2); + box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2); margin-bottom: 30px; background-color: white; + border-top: 1px solid #FAFAFA; } .cell .title { -webkit-border-top-left-radius: 4px; @@ -3781,18 +3792,32 @@ body { -moz-border-radius-topright: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; + background-color: #e9e9e9; + background-image: -moz-linear-gradient(top, #ebebeb, #e5e5e5); + background-image: -ms-linear-gradient(top, #ebebeb, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ebebeb), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #ebebeb, #e5e5e5); + background-image: -o-linear-gradient(top, #ebebeb, #e5e5e5); + background-image: linear-gradient(top, #ebebeb, #e5e5e5); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb', endColorstr='#e5e5e5', GradientType=0); font-size: 16px; font-weight: bold; line-height: 30px; padding-left: 10px; padding-top: 5px; - border-bottom: 1px solid #DDD; + color: #898989; + text-shadow: 0 1px 0 #fff; } .cell .title .fr { float: right; margin-right: 10px; font-weight: normal; } +.cell .title .fr a { + color: #898989; + font-size: 14px; +} .cell .table { -webkit-border-radius: 0px; -moz-border-radius: 0px; @@ -3812,10 +3837,6 @@ body { .cell .line { border-bottom: 1px solid #DDD; } -form.cell fieldset .title { - padding-left: 20px; - padding-top: 20px; -} .tagcloud { list-style: none; margin-left: 0; @@ -3942,7 +3963,6 @@ nav .nav li > a { } nav .nav li > a:hover { background: rgba(0, 0, 0, 0.2); - color: white; text-shadow: 0px 1px 1px black; } nav .sep { diff --git a/tpl/backstage/add_judger.html b/tpl/backstage/add_judger.html new file mode 100644 index 0000000..f850d8c --- /dev/null +++ b/tpl/backstage/add_judger.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% from "macros.html" import input %} +{% from "macros.html" import textarea %} +{% from "macros.html" import form_actions %} + +{% block body %} + +
      +
      {{ title }}
      + {{ page.xsrf_form_html() }} + +
      + {{ input("name", _("Name"), value=judger.name) }} + {{ input("path", _("Path"), value=judger.path, default="http://") }} + {{ input("priority", _("Priority"), value=judger.priority, default="0", class="input-mini")}} + {{ textarea("description", _("Description"), value=judger.description, style="width: 400px; height: 200px; ") }} + {{ textarea("pubkey", _("RSA Public Key"), value=judger.pubkey, style="width: 400px; height: 200px; ") }} + {{ form_actions(_("Submit")) }} +
      + +{% endblock %} diff --git a/tpl/backstage/judger.html b/tpl/backstage/judger.html new file mode 100644 index 0000000..a40aef6 --- /dev/null +++ b/tpl/backstage/judger.html @@ -0,0 +1,35 @@ +{% extends "base.html" %} + +{% block body %} +
      +
      + + {{ _('Judger List') }} +
      +
      + + + + + + + + + + {% for judger in judgers %} + + + + + + + + + {% endfor %} +
      #{{ _('Name') }}{{ _('Path') }}{{ _('Priority') }}{{ _('Queue') }}{{ _('Edit') }}
      {{ judger.id }}{{ judger.name }}{{ judger.path }}{{ judger.priority }}{{ judger.queue_num }} + {{ _('Edit') }} | + Reset +
      +
      +
      +{% endblock %} diff --git a/tpl/base/sidebar.html b/tpl/base/sidebar.html index 4dcc934..2502f8a 100644 --- a/tpl/base/sidebar.html +++ b/tpl/base/sidebar.html @@ -105,6 +105,12 @@ {{ _('Add Node') }} +
    • + + + {{ _('Judger Manage') }} + +
    • {% endif %} {% else %}
    • From 1c000fb9184b90a8779a79e5579de0388543a051 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Sun, 18 Mar 2012 03:08:55 +0800 Subject: [PATCH 27/56] change urlcode style to json --- judge/base/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/judge/base/__init__.py b/judge/base/__init__.py index a41e754..1262113 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 02:26:46 18/03/2012 +# MODIFIED: 03:08:32 18/03/2012 # DESCRIPTION: Base handler import re @@ -13,6 +13,7 @@ import datetime import functools import traceback +import simplejson import tornado.web import tornado.escape @@ -156,7 +157,7 @@ def get_gravatar_url(self, email): gravatar_id = hashlib.md5(email.lower()).hexdigest() return "http://www.gravatar.com/avatar/%s?d=mm" % (gravatar_id) def post_to_judger(self, post_arg, judger, callback = None): - query_string = "&".join(["%s=%s" % (k,a[k]) for k in a.keys()]) + query_string = simplejson.dumps(post_arg) # use json encrypt = rsa.encrypt(query_string, rsa.PublicKey.load_pkcs1(judger.pubkey)) http_client = AsyncHTTPClient() http_client.fetch(judger.path, method = "POST", body = urllib.urlencode({"query" : encrypt}), callback = callback) From 62a3e01d20648380c263fd2e360c4ceefc5ed644 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Mon, 19 Mar 2012 00:05:50 +0800 Subject: [PATCH 28/56] finish judger daemon --- daemons/config.example.py | 20 +++--- daemons/daemons.py | 37 ++++++++--- daemons/tasks.py | 125 +++++++++++++++++++++++++++++++++++++- 3 files changed, 159 insertions(+), 23 deletions(-) diff --git a/daemons/config.example.py b/daemons/config.example.py index 96675b0..4d5fb28 100644 --- a/daemons/config.example.py +++ b/daemons/config.example.py @@ -2,16 +2,16 @@ # AUTHOR: Zeray Rice # FILE: config.py # CREATED: 02:35:44 18/03/2012 -# MODIFIED: 03:05:45 18/03/2012 +# MODIFIED: 00:04:42 19/03/2012 -import rsa - -COMPILE_DIR = "" -TESTDATA_DIR = "" +COMPILE_DIR = "/home/fanzeyi/cogs_data/comp/" +TESTDATA_DIR = "/home/fanzeyi/cogs_data/testdata/" +CARETAKER_PATH = "/usr/local/bin/taker" DAEMON_PORT = 8889 +SALT = "" -RSA_PRIVKEY_PATH = "" -RSA_PRIVKEY = "" - -with open(RSA_PRIVKEY_PATH, "r") as rsafp: - RSA_PRIVKEY = rsa.PrivateKey.load_pkcs1(rsafp.read()) +MYSQL_HOST = "" +MYSQL_PORT = 3306 +MYSQL_USER = "" +MYSQL_PASS = "" +MYSQL_DB = "" diff --git a/daemons/daemons.py b/daemons/daemons.py index 32ba723..e8f385b 100644 --- a/daemons/daemons.py +++ b/daemons/daemons.py @@ -2,34 +2,51 @@ # AUTHOR: Zeray Rice # FILE: daemons.py # CREATED: 02:48:06 18/03/2012 -# MODIFIED: 02:59:28 18/03/2012 +# MODIFIED: 20:11:11 18/03/2012 -import rsa -import simplejson +import time +import hashlib +import logging +import simplejson as json +from operator import itemgetter import tornado.web import tornado.ioloop +import tornado.options from tornado.web import HTTPError +tornado.options.parse_command_line() + from tasks import judge +from config import SALT from config import DAEMON_PORT -from config import RSA_PRIVKEY -REQURED_ARGS = ["code", "lang", "filename", "shortname", "timelimit", "memlimit"] +REQURED_ARGS = ["code", "lang", "filename", "shortname", "timelimit", "memlimit", "testpoint", "sign", "time"] class ReceiveQueryHandler(tornado.web.RequestHandler): def post(self): query = self.get_argument("query", default = None) if not query: + logging.error("Invalid Post Query.") raise HTTPError(404) - try: - query = rsa.decrypt(query, RSA_PRIVKEY) - except: - raise HTTPError(404) - query = simplejson.loads(query) + query = json.loads(query) for key in REQURED_ARGS: if key not in query.keys(): + logging.error("Require key %s is missing" % key) raise HTTPError(404) + query_sign = query["sign"] + query.pop("sign") + now = time.time() + if abs(now - query["time"]) > 300: + logging.error("Time is invalid!") + raise HTTPError(404) + query = dict(sorted(query.iteritems(), key=itemgetter(1), reverse=True)) + sign = hashlib.sha1(json.dumps(query) + SALT).hexdigest() + if not sign == query_sign: + logging.error("Signature is invalid") + raise HTTPError(404) + print sign + print query_sign judge.delay(query) application = tornado.web.Application([ diff --git a/daemons/tasks.py b/daemons/tasks.py index d7cd90f..2468d85 100644 --- a/daemons/tasks.py +++ b/daemons/tasks.py @@ -2,15 +2,33 @@ # AUTHOR: Zeray Rice # FILE: tasks.py # CREATED: 02:27:12 17/03/2012 -# MODIFIED: 03:02:01 18/03/2012 +# MODIFIED: 00:05:00 19/03/2012 import os +import MySQLdb import subprocess from time import sleep from celery.task import task from config import COMPILE_DIR from config import TESTDATA_DIR +from config import CARETAKER_PATH + +from config import MYSQL_DB +from config import MYSQL_HOST +from config import MYSQL_PORT +from config import MYSQL_USER +from config import MYSQL_PASS + +STATUS_DICT = { + "A" : 1, + "W" : 2, + "T" : 3, + "M" : 4, + "R" : 5, + "C" : 6, + "N" : 7, +} def _clean(dir_path): for root, dirs, files in os.walk(dir_path): @@ -42,19 +60,112 @@ def _compile(result, query): result["compilesucc"] = 1 return result -def _run(result, query): - pass +def _get_input_file(tp, shortname): + with open(os.path.join(TESTDATA_DIR, shortname, shortname + str(tp+1) + ".in")) as input_data_p: + input_data = input_data_p.read() + with open(os.path.join(COMPILE_DIR, shortname + ".in"), "w") as input_data_p: + input_data_p.write(input_data) + +def _run(result, query, tp): + shortname = query["shortname"] + os.chdir(COMPILE_DIR) + cmd = " ".join([CARETAKER_PATH, "--input=%s.in" % query["shortname"], \ + "--output=%s.out" % query["shortname"], \ + "--time=%s" % str(query["timelimit"]), \ + "--memory=%s" % str(query["memlimit"] * 1024), \ + "a.out"]) + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + (stdoutput,erroutput) = proc.communicate() + testresult = "" + wexit, time, memory = stdoutput.split("\n")[-2].split(" ") + wexit = int(wexit) + time = int(time) + memory = int(memory) + if wexit != 0: + testresult = "W" + elif proc.returncode: + if proc.returncode == 251: + testresult = "T" + elif proc.returncode == 252: + testresult = "M" + elif proc.returncode == 253: + testresult = "R" + else: + # cmp output + with open(os.path.join(TESTDATA_DIR, shortname, shortname + str(tp+1) + ".ans")) as answer_fp: + answer = answer_fp.read() + try: + with open(os.path.join(COMPILE_DIR, shortname + ".out")) as prg_answer_fp: + prg_answer = prg_answer_fp.read() + except IOError: + testresult = "N" + else: + if _compare(answer, prg_answer): + testresult = "A" + result["score"] = result["score"] + 10 + else: + testresult = "W" + result["testpoint"].append((testresult, time, memory)) + +def _compare(fout, fans): + out = [line.strip() for line in fout if line.strip()] + ans = [line.strip() for line in fans if line.strip()] + return ans == out + +def _get_status(testpoint): + for tp in testpoint: + if tp != "A": + return STATUS_DICT[tp] + return STATUS_DICT["A"] + +def _return_result(result, query): + # connect to server + conn = MySQLdb.connect(host = MYSQL_HOST, user = MYSQL_USER, passwd = MYSQL_PASS, db = MYSQL_DB) + cur = conn.cursor() + # update + testpoint = [] + timecost = [] + memorycost = [] + totaltime = 0 + totalmemory = 0 + for tp in result["testpoint"]: + testpoint.append(tp[0]) + timecost.append(str(tp[1])) + memorycost.append(str(tp[2])) + totaltime = totaltime + tp[1] + totalmemory = totalmemory + tp[2] + testpoint = "".join(testpoint) + timecost = ",".join(timecost) + memorycost = ",".join(memorycost) + status = _get_status(testpoint) + cur.execute("""UPDATE `submit` SET `status` = %s, + `testpoint` = %s, + `testpoint_time` = %s, + `testpoint_memory` = %s, + `score` = %s, + `costtime` = %s, + `costmemory` = %s, + `msg` = %s, + WHERE `id` = %s""", (status, testpoint, timecost, memorycost, \ + result["score"], totaltime, totalmemory, result["msg"], + query["id"])) + conn.commit() + cur.close() ''' Query String Format: +id - Required. Submit id. code - Required. Code file content. lang - Required. Code language. ( 1 - Pascal, 2 - C, 3 - C++ ) filename - Required. Code file filename. shortname - Required. Problem shortname. timelimit - Required. Problem time limit. (MB) memlimit - Required. Problem memory limit.(ms) +testpoint - Required. Problem testpoint number. +sign - Signature. +time - For signature. ''' @@ -62,4 +173,12 @@ def _run(result, query): def judge(query): result = {} _compile(result, query) + print result + result["testpoint"] = [] + result["score"] = 0 + if result["compilesucc"]: + for tp in range(query["testpoint"]): + _get_input_file(tp, query["shortname"]) + _run(result, query, tp) + _return_result(result, query) return 0 From 365cb5ccff5c4cdc932e324a2e03eab952951c14 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Mon, 19 Mar 2012 04:25:49 +0800 Subject: [PATCH 29/56] finish daemons & submit page & submit detail --- .gitignore | 1 + daemons/daemons.py | 6 +- daemons/tasks.py | 52 +++--- handlers.py | 4 +- judge/base/__init__.py | 33 +++- judge/db/__init__.py | 38 ++++- judge/filters/__init__.py | 35 ++++- less/style.less | 110 ++++++++++++- member.py | 4 +- problem.py | 121 +++++++++++++- static/css/style.css | 322 +++++++++++++++++++++++++++++++++++++- tpl/problem.html | 5 +- tpl/signin.html | 2 +- tpl/submit.html | 103 ++++++++++++ tpl/submit_list.html | 38 +++++ 15 files changed, 830 insertions(+), 44 deletions(-) create mode 100644 tpl/submit.html create mode 100644 tpl/submit_list.html diff --git a/.gitignore b/.gitignore index 57468a7..68c3634 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ config.py celeryconfig.py privekey.key upload/ +test.py diff --git a/daemons/daemons.py b/daemons/daemons.py index e8f385b..aefff55 100644 --- a/daemons/daemons.py +++ b/daemons/daemons.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: daemons.py # CREATED: 02:48:06 18/03/2012 -# MODIFIED: 20:11:11 18/03/2012 +# MODIFIED: 01:35:35 19/03/2012 import time import hashlib @@ -40,8 +40,10 @@ def post(self): if abs(now - query["time"]) > 300: logging.error("Time is invalid!") raise HTTPError(404) - query = dict(sorted(query.iteritems(), key=itemgetter(1), reverse=True)) + query = dict(sorted(query.iteritems(), key=itemgetter(1))) sign = hashlib.sha1(json.dumps(query) + SALT).hexdigest() + print json.dumps(query) + print SALT if not sign == query_sign: logging.error("Signature is invalid") raise HTTPError(404) diff --git a/daemons/tasks.py b/daemons/tasks.py index 2468d85..1116e22 100644 --- a/daemons/tasks.py +++ b/daemons/tasks.py @@ -2,13 +2,14 @@ # AUTHOR: Zeray Rice # FILE: tasks.py # CREATED: 02:27:12 17/03/2012 -# MODIFIED: 00:05:00 19/03/2012 +# MODIFIED: 03:43:04 19/03/2012 import os import MySQLdb import subprocess from time import sleep from celery.task import task +from MySQLdb import escape_string from config import COMPILE_DIR from config import TESTDATA_DIR @@ -29,6 +30,7 @@ "C" : 6, "N" : 7, } +_e = lambda a: escape_string(str(a)) def _clean(dir_path): for root, dirs, files in os.walk(dir_path): @@ -122,22 +124,30 @@ def _return_result(result, query): # connect to server conn = MySQLdb.connect(host = MYSQL_HOST, user = MYSQL_USER, passwd = MYSQL_PASS, db = MYSQL_DB) cur = conn.cursor() - # update - testpoint = [] - timecost = [] - memorycost = [] + testpoint = "" + timecost = "" + memorycost = "" totaltime = 0 totalmemory = 0 - for tp in result["testpoint"]: - testpoint.append(tp[0]) - timecost.append(str(tp[1])) - memorycost.append(str(tp[2])) - totaltime = totaltime + tp[1] - totalmemory = totalmemory + tp[2] - testpoint = "".join(testpoint) - timecost = ",".join(timecost) - memorycost = ",".join(memorycost) - status = _get_status(testpoint) + if result["compilesucc"] == 0: + status = 6 + else: + # update + testpoint = [] + timecost = [] + memorycost = [] + totaltime = 0 + totalmemory = 0 + for tp in result["testpoint"]: + testpoint.append(tp[0]) + timecost.append(str(tp[1])) + memorycost.append(str(tp[2])) + totaltime = totaltime + tp[1] + totalmemory = totalmemory + tp[2] + testpoint = "".join(testpoint) + timecost = ",".join(timecost) + memorycost = ",".join(memorycost) + status = _get_status(testpoint) cur.execute("""UPDATE `submit` SET `status` = %s, `testpoint` = %s, `testpoint_time` = %s, @@ -145,10 +155,10 @@ def _return_result(result, query): `score` = %s, `costtime` = %s, `costmemory` = %s, - `msg` = %s, - WHERE `id` = %s""", (status, testpoint, timecost, memorycost, \ - result["score"], totaltime, totalmemory, result["msg"], - query["id"])) + `msg` = %s + WHERE `id` = %s """, (_e(status), _e(testpoint), _e(timecost), _e(memorycost), \ + _e(result["score"]), _e(totaltime), _e(totalmemory), \ + _e(result["msg"]), _e(query["id"]))) conn.commit() cur.close() @@ -173,7 +183,9 @@ def _return_result(result, query): def judge(query): result = {} _compile(result, query) - print result + if result["compilesucc"] == 0: + result["score"] = 0 + _return_result(result, query) result["testpoint"] = [] result["score"] = 0 if result["compilesucc"]: diff --git a/handlers.py b/handlers.py index 24e9ffb..8dc79bb 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 01:36:47 18/03/2012 +# MODIFIED: 02:24:35 19/03/2012 # DESCRIPTION: URL Route from api import * @@ -28,6 +28,8 @@ (r'/lang/(.*)', SetLanguageHandler), (r'/problem', ListProblemHandler), (r'/problem/([\d]*)', ViewProblemHandler), + (r'/submit', ListSubmitHandler), + (r'/submit/(.*)', ViewSubmitHandler), (r'/backstage/problem/add', AddProblemHandler), (r'/backstage/contest/add', AddContestHandler), (r'/backstage/judger', ManageJudgerHandler), diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 1262113..5f566d0 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,18 +2,24 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 03:08:32 18/03/2012 +# MODIFIED: 03:15:40 19/03/2012 # DESCRIPTION: Base handler import re -import rsa +import time import urllib import hashlib import httplib import datetime import functools import traceback -import simplejson +import simplejson as json +from operator import itemgetter +from pygments import highlight +from pygments.lexers import CLexer +from pygments.lexers import CppLexer +from pygments.lexers import DelphiLexer +from pygments.formatters import HtmlFormatter import tornado.web import tornado.escape @@ -22,6 +28,12 @@ from judge.db import Member from judge.utils import _len +CODE_LEXER = { + 1 : DelphiLexer, + 2 : CLexer, + 3 : CppLexer, +} + def unauthenticated(method): """Decorate methods with this to require that user be NOT logged in""" @functools.wraps(method) @@ -156,11 +168,18 @@ def check_email(self, email, queryDB = False): def get_gravatar_url(self, email): gravatar_id = hashlib.md5(email.lower()).hexdigest() return "http://www.gravatar.com/avatar/%s?d=mm" % (gravatar_id) - def post_to_judger(self, post_arg, judger, callback = None): - query_string = simplejson.dumps(post_arg) # use json - encrypt = rsa.encrypt(query_string, rsa.PublicKey.load_pkcs1(judger.pubkey)) + def post_to_judger(self, query, judger, callback = None): + query["time"] = time.time() + query = dict(sorted(query.iteritems(), key=itemgetter(1))) + jsondump = json.dumps(query) + print jsondump + print judger.pubkey.strip() + sign = hashlib.sha1(jsondump + judger.pubkey.strip()).hexdigest() + query["sign"] = sign http_client = AsyncHTTPClient() - http_client.fetch(judger.path, method = "POST", body = urllib.urlencode({"query" : encrypt}), callback = callback) + http_client.fetch(judger.path, method = "POST", body = urllib.urlencode({"query" : json.dumps(query)}), callback = callback) + def highlight_code(self, code, lang): + return highlight(code, CODE_LEXER[lang](), HtmlFormatter(linenos=True)) @property def db(self): return self.application.db diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 0471d8d..4404959 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 02:08:56 18/03/2012 +# MODIFIED: 02:29:19 19/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -216,8 +216,11 @@ class Submit(BaseDBObject): id = 0 problem_id = 0 member_id = 0 + code = "" status = 0 - testpoint = "" + testpoint = 0 + testpoint_time = "" + testpoint_memory = "" score = 0 costtime = 0 costmemory = 0 @@ -252,6 +255,9 @@ def count_visible_problem(self): def count_problem_by_tagname(self, tagname): count = self.db.get("""SELECT COUNT(*) FROM `problem_tag` WHERE `tagname` = %s""", tagname) return count["COUNT(*)"] + def count_submit(self): + count = self.db.get("""SELECT COUNT(*) FROM `submit`""") + return count["COUNT(*)"] ''' SELECT ''' def select_problem_by_id(self, id): row = self.db.get("""SELECT * FROM `problem` WHERE `id` = %s LIMIT 1""", id) @@ -282,6 +288,23 @@ def select_last_submit_by_problem_id_member_id(self, problem_id): if row: return self._new_submit(row) return None + def select_submit_by_id(self, sid): + row = self.db.get("""SELECT `submit`.*, `member`.`username`, `problem`.`title` FROM `submit` + LEFT JOIN `member` ON `submit`.`member_id` = `member`.`id` + LEFT JOIN `problem` ON `submit`.`problem_id` = `problem`.`id` + WHERE `submit`.`id` = %s LIMIT 1""", int(sid)) + if row: + return self._new_submit(row) + return None + def select_submit_order_by_id(self, count = 10, start = 0): + rows = self.db.query("""SELECT `submit`.*, `member`.`username`, `problem`.`title` FROM `submit` + LEFT JOIN `member` ON `submit`.`member_id` = `member`.`id` + LEFT JOIN `problem` ON `submit`.`problem_id` = `problem`.`id` + ORDER BY `submit`.`id` DESC LIMIT %s, %s""", int(start), int(count)) + result = [] + for row in rows: + result.append(self._new_submit(row)) + return result ''' INSERT ''' def insert_problem(self, problem): problem.id = self.db.execute("""INSERT INTO `problem` (`title`, `shortname`, `content`, \ @@ -291,6 +314,12 @@ def insert_problem(self, problem): int(problem.timelimit), int(problem.memlimit), int(problem.testpoint), int(problem.invisible)) def insert_problem_tag(self, tagname, problem_id): self.db.execute("""INSERT INTO `problem_tag` (`tagname`, `problem_id`) VAlUES (%s, %s)""", tagname, int(problem_id)) + def insert_submit(self, submit): + submit.id = self.db.execute("""INSERT INTO `submit` (`problem_id`, `member_id`, `code`, `timestamp`, + `lang`, `user_agent`, `ip`, `create`) + VALUES (%s, %s, %s, %s, %s, %s, %s, UTC_TIMESTAMP())""", \ + submit.problem_id, submit.member_id, submit.code, submit.timestamp, \ + submit.lang, submit.user_agent, submit.ip) ''' UPDATE ''' def update_problem(self, problem): self.db.execute("""UPDATE `problem` SET `title` = %s, @@ -457,6 +486,11 @@ def select_judger_by_id(self, juder_id): if row: return self._new_judger(row) return None + def select_judger_by_queue(self): + row = self.db.get("""SELECT * FROM `judger` ORDER BY `queue_num`, `priority` LIMIT 1""") + if row: + return self._new_judger(row) + return None ''' INSERT ''' def insert_judger(self, judger): judger.id = self.db.execute("""INSERT INTO `judger` (`name`, `description`, `path`, `priority`, `queue_num`, `pubkey`, `create`) diff --git a/judge/filters/__init__.py b/judge/filters/__init__.py index 852155e..da3616a 100644 --- a/judge/filters/__init__.py +++ b/judge/filters/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/filters/__init__.py # CREATED: 01:48:10 08/03/2012 -# MODIFIED: 14:50:10 16/03/2012 +# MODIFIED: 04:21:53 19/03/2012 # DESCRIPTION: jinja2 filters import re @@ -37,6 +37,16 @@ 4 : ("warning", "Memory Limit Exceeded"), 5 : ("inverse", "Runtime Error"), 6 : ("default", "Compile Error"), + 7 : ("default", "No Output"), +} +ALPHA_STATUS = { + "a" : 1, + "w" : 2, + "t" : 3, + "m" : 4, + "r" : 5, + "c" : 6, + "n" : 7, } def autolink(text, trim_url_limit=None, nofollow=False): @@ -126,6 +136,26 @@ def get_submit_status(submit): cla, status = SUBMIT_STATUS[submit.status] return "%s" % (cla, status) +def lang2text(lang): + if lang == 1: + return "pascal" + elif lang == 2: + return "c" + elif lang == 3: + return "cpp" + +def lang2humantext(lang): + if lang == 1: + return "Pascal" + elif lang == 2: + return "C" + elif lang == 3: + return "C++" + +def alpha2status(alpha): + cla, status = SUBMIT_STATUS[ALPHA_STATUS[str(alpha.lower())]] + return "%s" % (cla, status) + filters = { 'autolink' : autolink, 'avatar_img' : avatar_img, @@ -135,4 +165,7 @@ def get_submit_status(submit): 'datetimeformat' : datetimeformat, 'get_contest_status' : get_contest_status, 'get_submit_status' : get_submit_status, + 'lang2text' : lang2text, + 'lang2humantext' : lang2humantext, + 'alpha2status' : alpha2status, } diff --git a/less/style.less b/less/style.less index de7adae..487124c 100644 --- a/less/style.less +++ b/less/style.less @@ -72,6 +72,12 @@ body { margin-bottom: @bottomBlank; } +a { + &.nounderline:hover { + text-decoration: none; + } +} + ::selection { color: rgba(255, 255, 255, .75); background: rgba(0, 0, 0, .5); @@ -117,8 +123,8 @@ body { line-height: 30px; padding-left: 10px; padding-top: 5px; - color: #898989; - text-shadow: 0 1px 0 #fff; + color: #454545; + text-shadow: 0 -1px 0 #fff; .fr { float: right; @@ -388,3 +394,103 @@ nav { } } } + +/* Submit Detail Style */ + +.submitdetail tr { + th, td { + .border-radius(0) !important; + border-bottom: 1px solid #DDD; + } +} + +.highlighttable { + width: 100%; + + pre { + margin: 0; + } + + tr td { + padding: 0; + } + + .linenos { + pre { + .border-radius(4px 0 0 4px); + border-right: none; + } + + width: 40px; + margin: 0; + padding: 0; + text-align: right; + border-right: 0; + } + + .highlight pre { + .border-radius(0 4px 4px 0); + } +} + +.highlight .hll { background-color: #ffffcc } +.highlight { background: #ffffff; } +.highlight .c { color: #888888 } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { color: #008800; font-weight: bold } /* Keyword */ +.highlight .cm { color: #888888 } /* Comment.Multiline */ +.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #888888 } /* Comment.Single */ +.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #303030 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #606060 } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008800 } /* Keyword.Pseudo */ +.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ +.highlight .na { color: #336699 } /* Name.Attribute */ +.highlight .nb { color: #003388 } /* Name.Builtin */ +.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ +.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ +.highlight .nd { color: #555555 } /* Name.Decorator */ +.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ +.highlight .nl { color: #336699; font-style: italic } /* Name.Label */ +.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ +.highlight .py { color: #336699; font-weight: bold } /* Name.Property */ +.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #336699 } /* Name.Variable */ +.highlight .ow { color: #008800 } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ +.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ +.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ +.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ +.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ +.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ +.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ +.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ +.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ +.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ +.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ +.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #336699 } /* Name.Variable.Class */ +.highlight .vg { color: #dd7700 } /* Name.Variable.Global */ +.highlight .vi { color: #3333bb } /* Name.Variable.Instance */ +.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ diff --git a/member.py b/member.py index 758b1b0..24b1d4c 100644 --- a/member.py +++ b/member.py @@ -2,13 +2,14 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 14:51:21 15/03/2012 +# MODIFIED: 04:22:54 19/03/2012 # DESCRIPTION: member handlers import re import copy import bcrypt +from tornado.web import HTTPError from tornado.web import authenticated from judge.db import Member @@ -40,6 +41,7 @@ def post(self): self.set_secure_cookie("auth", auth.secret) self.set_secure_cookie("uid", str(auth.member_id)) go_next = self.get_argument("next", default = None) + print go_next if go_next: self.redirect(go_next) return diff --git a/problem.py b/problem.py index e0ca594..0c1d934 100644 --- a/problem.py +++ b/problem.py @@ -2,15 +2,35 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 14:00:51 16/03/2012 +# MODIFIED: 03:10:26 19/03/2012 + +import os +import time from tornado.web import HTTPError +from tornado.web import asynchronous +from tornado.web import authenticated +from judge.db import Judger +from judge.db import Submit from judge.db import Problem +from judge.db import JudgerDBMixin from judge.db import ProblemDBMixin from judge.base import BaseHandler -class ViewProblemHandler(BaseHandler, ProblemDBMixin): +LANG_DICT = { + "pascal" : 1, + "c" : 2, + "cpp" : 3, +} + +LANG_EXT = { + "pascal" : ".pas", + "c" : ".c", + "cpp" : ".cc", +} + +class ViewProblemHandler(BaseHandler, ProblemDBMixin, JudgerDBMixin): def get(self, pid): try: pid = int(pid) @@ -28,6 +48,65 @@ def get(self, pid): title = problem.title tags = self.select_problem_tag_by_problem_id(problem.id) self.render("problem.html", locals()) + @authenticated + @asynchronous + def post(self, pid): + try: + pid = int(pid) + except ValueError: + raise HTTPError(404) + problem = self.select_problem_by_id(pid) + if not problem: + raise HTTPError(404) + if problem.invisible and (self.current_user == None or self.current_user.admin == 0): + raise HTTPError(404) + lang = self.get_argument("lang", default = 0) + error = [] + try: + codefile = self.request.files['codefile'][0] + except KeyError: + error.append(self._('Please Choose Your Code File')) + else: + filename, fileext = os.path.splitext(codefile.filename) + if fileext not in ['.c', '.cc', '.cpp', '.cxx', '.pas']: + error.append(self._('File Type Error!')) + else: + if lang not in ["c", "cpp", "pascal"]: + error.append(self._('Error Code Language Select')) + else: + judger = self.select_judger_by_queue() + if not judger: + error.append(self._("No Judger Seted!")) + if error: + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Problem'), '/problem')) + breadcrumb.append((problem.title, '/problem/%d' % problem.id)) + title = problem.title + tags = self.select_problem_tag_by_problem_id(problem.id) + self.render("problem.html", locals()) + return + submit = Submit() + submit.problem_id = problem.id + submit.member_id = self.current_user.id + submit.status = 0 + submit.timestamp = int(time.time()) + submit.code = codefile.body + submit.user_agent = self.request.headers['User-Agent'] + submit.ip = self.request.remote_ip + submit.lang = LANG_DICT[lang] + self.insert_submit(submit) + query = {} + query["id"] = submit.id + query["code"] = submit.code + query["lang"] = submit.lang + query["filename"] = problem.shortname + LANG_EXT[lang] + query["shortname"] = problem.shortname + query["timelimit"] = problem.timelimit + query["memlimit"] = problem.memlimit + query["testpoint"] = problem.testpoint + self.post_to_judger(query, judger) + self.redirect("/submit") class ListProblemHandler(BaseHandler, ProblemDBMixin): def get(self): @@ -52,4 +131,40 @@ def get(self): problem.submit = self.select_last_submit_by_problem_id_member_id(problem.id) self.render("problem_list.html", locals()) -__all__ = ["ViewProblemHandler", "ListProblemHandler"] +class ListSubmitHandler(BaseHandler, ProblemDBMixin): + def get(self): + start = self.get_argument("start", default = 0) + try: + start = int(start) + except ValueError: + start = 0 + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Submit'), '/submit')) + title = self._("Submit List") + count = self.count_submit() + submits = self.select_submit_order_by_id(10, start) + pages = self.get_page_count(count) + self.render("submit_list.html", locals()) + +class ViewSubmitHandler(BaseHandler, ProblemDBMixin): + @authenticated + def get(self, sid): + try: + sid = int(sid) + except ValueError: + raise HTTPError(404) + submit = self.select_submit_by_id(sid) + if not submit: + raise HTTPError(404) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Submit'), '/submit')) + breadcrumb.append(("# %d" % submit.id, '/submit/%d' % submit.id)) + title = self._("Submit #%d - %s") % (submit.id, submit.title) + testpoint = zip(range(1, len(submit.testpoint) + 1), submit.testpoint, \ + submit.testpoint_time.split(","), submit.testpoint_memory.split(",")) + code_highlighted = self.highlight_code(submit.code, submit.lang) + self.render("submit.html", locals()) + +__all__ = ["ViewProblemHandler", "ListProblemHandler", "ListSubmitHandler", "ViewSubmitHandler"] diff --git a/static/css/style.css b/static/css/style.css index fda9272..44aaade 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3741,6 +3741,9 @@ body { margin-left: 260px; margin-bottom: 20px; } +a.nounderline:hover { + text-decoration: none; +} ::selection { color: rgba(255, 255, 255, 0.75); background: rgba(0, 0, 0, 0.5); @@ -3806,8 +3809,8 @@ body { line-height: 30px; padding-left: 10px; padding-top: 5px; - color: #898989; - text-shadow: 0 1px 0 #fff; + color: #454545; + text-shadow: 0 -1px 0 #ffffff; } .cell .title .fr { float: right; @@ -4040,3 +4043,318 @@ nav .copyright a { .member-top .profile .website i { margin-right: 5px; } +/* Submit Detail Style */ +.submitdetail tr th, +.submitdetail tr td { + -webkit-border-radius: 0 !important; + -moz-border-radius: 0 !important; + border-radius: 0 !important; + border-bottom: 1px solid #DDD; +} +.highlighttable { + width: 100%; +} +.highlighttable pre { + margin: 0; +} +.highlighttable tr td { + padding: 0; +} +.highlighttable .linenos { + width: 40px; + margin: 0; + padding: 0; + text-align: right; + border-right: 0; +} +.highlighttable .linenos pre { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; + border-right: none; +} +.highlighttable .highlight pre { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} +.highlight .hll { + background-color: #ffffcc; +} +.highlight { + background: #ffffff; +} +.highlight .c { + color: #888888; +} +/* Comment */ +.highlight .err { + color: #a61717; + background-color: #e3d2d2; +} +/* Error */ +.highlight .k { + color: #008800; + font-weight: bold; +} +/* Keyword */ +.highlight .cm { + color: #888888; +} +/* Comment.Multiline */ +.highlight .cp { + color: #cc0000; + font-weight: bold; +} +/* Comment.Preproc */ +.highlight .c1 { + color: #888888; +} +/* Comment.Single */ +.highlight .cs { + color: #cc0000; + font-weight: bold; + background-color: #fff0f0; +} +/* Comment.Special */ +.highlight .gd { + color: #000000; + background-color: #ffdddd; +} +/* Generic.Deleted */ +.highlight .ge { + font-style: italic; +} +/* Generic.Emph */ +.highlight .gr { + color: #aa0000; +} +/* Generic.Error */ +.highlight .gh { + color: #303030; +} +/* Generic.Heading */ +.highlight .gi { + color: #000000; + background-color: #ddffdd; +} +/* Generic.Inserted */ +.highlight .go { + color: #888888; +} +/* Generic.Output */ +.highlight .gp { + color: #555555; +} +/* Generic.Prompt */ +.highlight .gs { + font-weight: bold; +} +/* Generic.Strong */ +.highlight .gu { + color: #606060; +} +/* Generic.Subheading */ +.highlight .gt { + color: #aa0000; +} +/* Generic.Traceback */ +.highlight .kc { + color: #008800; + font-weight: bold; +} +/* Keyword.Constant */ +.highlight .kd { + color: #008800; + font-weight: bold; +} +/* Keyword.Declaration */ +.highlight .kn { + color: #008800; + font-weight: bold; +} +/* Keyword.Namespace */ +.highlight .kp { + color: #008800; +} +/* Keyword.Pseudo */ +.highlight .kr { + color: #008800; + font-weight: bold; +} +/* Keyword.Reserved */ +.highlight .kt { + color: #888888; + font-weight: bold; +} +/* Keyword.Type */ +.highlight .m { + color: #0000DD; + font-weight: bold; +} +/* Literal.Number */ +.highlight .s { + color: #dd2200; + background-color: #fff0f0; +} +/* Literal.String */ +.highlight .na { + color: #336699; +} +/* Name.Attribute */ +.highlight .nb { + color: #003388; +} +/* Name.Builtin */ +.highlight .nc { + color: #bb0066; + font-weight: bold; +} +/* Name.Class */ +.highlight .no { + color: #003366; + font-weight: bold; +} +/* Name.Constant */ +.highlight .nd { + color: #555555; +} +/* Name.Decorator */ +.highlight .ne { + color: #bb0066; + font-weight: bold; +} +/* Name.Exception */ +.highlight .nf { + color: #0066bb; + font-weight: bold; +} +/* Name.Function */ +.highlight .nl { + color: #336699; + font-style: italic; +} +/* Name.Label */ +.highlight .nn { + color: #bb0066; + font-weight: bold; +} +/* Name.Namespace */ +.highlight .py { + color: #336699; + font-weight: bold; +} +/* Name.Property */ +.highlight .nt { + color: #bb0066; + font-weight: bold; +} +/* Name.Tag */ +.highlight .nv { + color: #336699; +} +/* Name.Variable */ +.highlight .ow { + color: #008800; +} +/* Operator.Word */ +.highlight .w { + color: #bbbbbb; +} +/* Text.Whitespace */ +.highlight .mf { + color: #0000DD; + font-weight: bold; +} +/* Literal.Number.Float */ +.highlight .mh { + color: #0000DD; + font-weight: bold; +} +/* Literal.Number.Hex */ +.highlight .mi { + color: #0000DD; + font-weight: bold; +} +/* Literal.Number.Integer */ +.highlight .mo { + color: #0000DD; + font-weight: bold; +} +/* Literal.Number.Oct */ +.highlight .sb { + color: #dd2200; + background-color: #fff0f0; +} +/* Literal.String.Backtick */ +.highlight .sc { + color: #dd2200; + background-color: #fff0f0; +} +/* Literal.String.Char */ +.highlight .sd { + color: #dd2200; + background-color: #fff0f0; +} +/* Literal.String.Doc */ +.highlight .s2 { + color: #dd2200; + background-color: #fff0f0; +} +/* Literal.String.Double */ +.highlight .se { + color: #0044dd; + background-color: #fff0f0; +} +/* Literal.String.Escape */ +.highlight .sh { + color: #dd2200; + background-color: #fff0f0; +} +/* Literal.String.Heredoc */ +.highlight .si { + color: #3333bb; + background-color: #fff0f0; +} +/* Literal.String.Interpol */ +.highlight .sx { + color: #22bb22; + background-color: #f0fff0; +} +/* Literal.String.Other */ +.highlight .sr { + color: #008800; + background-color: #fff0ff; +} +/* Literal.String.Regex */ +.highlight .s1 { + color: #dd2200; + background-color: #fff0f0; +} +/* Literal.String.Single */ +.highlight .ss { + color: #aa6600; + background-color: #fff0f0; +} +/* Literal.String.Symbol */ +.highlight .bp { + color: #003388; +} +/* Name.Builtin.Pseudo */ +.highlight .vc { + color: #336699; +} +/* Name.Variable.Class */ +.highlight .vg { + color: #dd7700; +} +/* Name.Variable.Global */ +.highlight .vi { + color: #3333bb; +} +/* Name.Variable.Instance */ +.highlight .il { + color: #0000DD; + font-weight: bold; +} +/* Literal.Number.Integer.Long */ diff --git a/tpl/problem.html b/tpl/problem.html index 865b972..067ade8 100644 --- a/tpl/problem.html +++ b/tpl/problem.html @@ -48,10 +48,11 @@
    • {% if user %} -
      +
      {{ _('Submit Problem') }}
      + {{ page.xsrf_form_html() }}
      @@ -60,7 +61,7 @@
      - +
      Pascal C diff --git a/tpl/signin.html b/tpl/signin.html index edc663f..a485106 100644 --- a/tpl/signin.html +++ b/tpl/signin.html @@ -25,7 +25,7 @@
      {% endif %} - + {{ page.xsrf_form_html() }}
      diff --git a/tpl/submit.html b/tpl/submit.html new file mode 100644 index 0000000..f12cd0a --- /dev/null +++ b/tpl/submit.html @@ -0,0 +1,103 @@ +{% extends "base.html" %} + +{% block body %} +
      +
      {{ _('Submit Detail') }}
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% if user.admin %} + + + + + + + + + {% endif %} +
      ID{{ submit.id }}
      {{ _('Problem') }}{{ submit.title }}
      {{ _('Member') }}{{ submit.username }}
      {{ _('Status') }}{{ submit | get_submit_status }}
      {{ _('Language') }}{{ submit.lang | lang2humantext }}
      {{ _('Score') }}{{ submit.score }}
      {{ _('Cost Time') }}{{ submit.costtime }} ms
      {{ _('Cost Memory') }}{{ submit.costmemory }} KB
      {{ _('Submit Time') }}{{ submit.create }}
      {{ _('IP') }}{{ submit.ip }}
      {{ _('User-Agent') }}{{ submit.user_agent }}
      +
      +
      +{% if submit.status == 6%} +
      +
      {{ _('Compile Output') }}
      +
      +
      {{ submit.msg.replace("\\n", "\n") | e}}
      +
      +
      +{% else %} +
      +
      +
      +
      {{ _('Test Point') }}
      +
      + + + + + + + + + + + {% for tp in testpoint %} + + + + + + + {% endfor %} + +
      #{{ _('Status') }}{{ _('Time') }}{{ _('Memory') }}
      {{ tp[0] }}{{ tp[1] | alpha2status }}{{ tp[2] }} ms{{ tp[3] }} KB
      +
      +
      +
      +
      +
      +
      {{ _('Code') }}
      +
      + {{ code_highlighted }} +
      +
      +
      +
      +{% endif %} +{% endblock %} diff --git a/tpl/submit_list.html b/tpl/submit_list.html new file mode 100644 index 0000000..05877ef --- /dev/null +++ b/tpl/submit_list.html @@ -0,0 +1,38 @@ +{% extends "base.html" %} + +{% block body %} +
      +
      {{ _('Submit List') }}
      +
      + + + + + + + + + + + + + + + {% for submit in submits %} + + + + + + + + + + + {% endfor %} + +
      #{{ _('Status') }}{{ _('Problem') }}{{ _('User') }}{{ _('Time') }}{{ _('Memory') }}{{ _('Testpoint') }}{{ _('Score') }}
      {{ submit.id }}{{ submit | get_submit_status }}{{ submit.title }}{{ submit.username }}{{ submit.costtime }} ms{{ submit.costmemory }} KB{% if submit.testpoint %}{{ submit.testpoint }}{% endif %}{{ submit.score }}
      +
      +
      +{% include 'count.html' %} +{% endblock %} From c494ea98809ece9496b17f7088a9480d88630f8b Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Mon, 19 Mar 2012 20:21:48 +0800 Subject: [PATCH 30/56] some ui fix --- daemons/tasks.py | 44 +++++++++++++++++++++++-------------------- home.py | 14 ++++++++++---- judge/db/__init__.py | 12 +++++++++--- less/style.less | 14 +++++++++++--- less/vars.less | 2 +- problem.py | 9 +++++---- static/css/style.css | 14 +++++++++++--- tpl/base/sidebar.html | 8 ++++---- tpl/home.html | 6 ++---- tpl/macros.html | 26 ++++++++++++++++++++++--- tpl/problem_list.html | 4 ++-- tpl/submit.html | 19 +++++++++++++++++++ tpl/submit_list.html | 6 +++--- 13 files changed, 124 insertions(+), 54 deletions(-) diff --git a/daemons/tasks.py b/daemons/tasks.py index 1116e22..c2a1bfb 100644 --- a/daemons/tasks.py +++ b/daemons/tasks.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: tasks.py # CREATED: 02:27:12 17/03/2012 -# MODIFIED: 03:43:04 19/03/2012 +# MODIFIED: 14:26:12 19/03/2012 import os import MySQLdb @@ -79,13 +79,10 @@ def _run(result, query, tp): proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) (stdoutput,erroutput) = proc.communicate() testresult = "" - wexit, time, memory = stdoutput.split("\n")[-2].split(" ") - wexit = int(wexit) - time = int(time) - memory = int(memory) - if wexit != 0: - testresult = "W" - elif proc.returncode: + wexit = 0 + time = 0 + memory = 0 + if proc.returncode: if proc.returncode == 251: testresult = "T" elif proc.returncode == 252: @@ -93,20 +90,27 @@ def _run(result, query, tp): elif proc.returncode == 253: testresult = "R" else: - # cmp output - with open(os.path.join(TESTDATA_DIR, shortname, shortname + str(tp+1) + ".ans")) as answer_fp: - answer = answer_fp.read() - try: - with open(os.path.join(COMPILE_DIR, shortname + ".out")) as prg_answer_fp: - prg_answer = prg_answer_fp.read() - except IOError: - testresult = "N" + wexit, time, memory = stdoutput.split("\n")[-2].split(" ") + wexit = int(wexit) + time = int(time) + memory = int(memory) + if wexit != 0: + testresult = "W" else: - if _compare(answer, prg_answer): - testresult = "A" - result["score"] = result["score"] + 10 + # cmp output + with open(os.path.join(TESTDATA_DIR, shortname, shortname + str(tp+1) + ".ans")) as answer_fp: + answer = answer_fp.read() + try: + with open(os.path.join(COMPILE_DIR, shortname + ".out")) as prg_answer_fp: + prg_answer = prg_answer_fp.read() + except IOError: + testresult = "N" else: - testresult = "W" + if _compare(answer, prg_answer): + testresult = "A" + result["score"] = result["score"] + 10 + else: + testresult = "W" result["testpoint"].append((testresult, time, memory)) def _compare(fout, fans): diff --git a/home.py b/home.py index cf5b23b..99bfefe 100644 --- a/home.py +++ b/home.py @@ -2,18 +2,24 @@ # AUTHOR: Zeray Rice # FILE: home.py # CREATED: 02:00:16 08/03/2012 -# MODIFIED: 19:38:23 10/03/2012 +# MODIFIED: 19:51:24 19/03/2012 # DESCRIPTION: Home handler +from contest import get_contest_status + +from judge.db import ContestDBMixin +from judge.db import ProblemDBMixin from judge.base import BaseHandler -class HomeHandler(BaseHandler): +class HomeHandler(BaseHandler, ProblemDBMixin, ContestDBMixin): def get(self): title = self._("Home") breadcrumb = [] breadcrumb.append((self._("Home"), "/")) - latest_problem = [] - latest_contest = [] + latest_problem = self.select_latest_visible_problem_order_by_id() + latest_contest = self.select_visible_contest(count = 5) + for contest in latest_contest: + contest.status = get_contest_status(contest) latest_topic = [] count_problem = 0 count_topic = 0 diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 4404959..d43b24e 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 02:29:19 19/03/2012 +# MODIFIED: 19:49:56 19/03/2012 # DESCRIPTION: Database Table Object import uuid @@ -282,6 +282,12 @@ def select_visible_problem_order_by_id(self, count = 10, start = 0): for row in rows: result.append(self._new_problem(row)) return result + def select_latest_visible_problem_order_by_id(self, count = 10): + rows = self.db.query("""SELECT * FROM `problem` WHERE `invisible` = 0 ORDER BY `id` DESC LIMIT %s""", int(count)) + result = [] + for row in rows: + result.append(self._new_problem(row)) + return result def select_last_submit_by_problem_id_member_id(self, problem_id): row = self.db.get("""SELECT * FROM `submit` WHERE `problem_id` = %s AND `member_id` = %s ORDER BY `id` DESC LIMIT 1""", \ problem_id, self.current_user.id) @@ -421,13 +427,13 @@ def select_contest_submit_by_contest_id_problem_id_user_id(self, contest_id, pro return self._new_contest_submit(row) return None def select_contest(self, start = 0, count = 20): - rows = self.db.query("""SELECT * FROM `contest` LIMIT %s, %s""", start, count) + rows = self.db.query("""SELECT * FROM `contest` ORDER BY `id` DESC LIMIT %s, %s""", start, count) result = [] for row in rows: result.append(self._new_contest(row)) return result def select_visible_contest(self, start = 0, count = 20): - rows = self.db.query("""SELECT * FROM `contest` WHERE `invisible` = 0 LIMIT %s, %s""", start, count) + rows = self.db.query("""SELECT * FROM `contest` WHERE `invisible` = 0 ORDER BY `id` DESC LIMIT %s, %s""", start, count) result = [] for row in rows: result.append(self._new_contest(row)) diff --git a/less/style.less b/less/style.less index 487124c..194c2da 100644 --- a/less/style.less +++ b/less/style.less @@ -161,9 +161,8 @@ a { } } -form.cell fieldset .title { -// padding-left: 20px; -// padding-top: 20px; +.label { + white-space: nowrap; } .tagcloud { @@ -494,3 +493,12 @@ nav { .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ + +.onecol { + .row-fluid { + .span4, .span8 { + width: 100%; + margin-left: 0; + } + } +} diff --git a/less/vars.less b/less/vars.less index 766669e..63384fa 100644 --- a/less/vars.less +++ b/less/vars.less @@ -16,7 +16,7 @@ /* Sidebar Const Var */ -@sidebarWidth: 240px; +@sidebarWidth: 220px; @sidebarLineTopColor: #1D1E21; @sidebarLineBottomColor: #4A4A54; diff --git a/problem.py b/problem.py index 0c1d934..e7114a4 100644 --- a/problem.py +++ b/problem.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 03:10:26 19/03/2012 +# MODIFIED: 15:28:24 19/03/2012 import os import time @@ -148,7 +148,6 @@ def get(self): self.render("submit_list.html", locals()) class ViewSubmitHandler(BaseHandler, ProblemDBMixin): - @authenticated def get(self, sid): try: sid = int(sid) @@ -162,8 +161,10 @@ def get(self, sid): breadcrumb.append((self._('Submit'), '/submit')) breadcrumb.append(("# %d" % submit.id, '/submit/%d' % submit.id)) title = self._("Submit #%d - %s") % (submit.id, submit.title) - testpoint = zip(range(1, len(submit.testpoint) + 1), submit.testpoint, \ - submit.testpoint_time.split(","), submit.testpoint_memory.split(",")) + testpoint = [] + if submit.testpoint: + testpoint = zip(range(1, len(submit.testpoint) + 1), submit.testpoint, \ + submit.testpoint_time.split(","), submit.testpoint_memory.split(",")) code_highlighted = self.highlight_code(submit.code, submit.lang) self.render("submit.html", locals()) diff --git a/static/css/style.css b/static/css/style.css index 44aaade..9e46b0b 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3738,7 +3738,7 @@ body { } /* Common Page Style */ body { - margin-left: 260px; + margin-left: 240px; margin-bottom: 20px; } a.nounderline:hover { @@ -3840,6 +3840,9 @@ a.nounderline:hover { .cell .line { border-bottom: 1px solid #DDD; } +.label { + white-space: nowrap; +} .tagcloud { list-style: none; margin-left: 0; @@ -3880,7 +3883,7 @@ nav { color: white; background: #2B2B2B; background-image: url("/static/img/lines.jpg"); - width: 240px; + width: 220px; height: 100%; position: fixed; top: 0; @@ -3981,7 +3984,7 @@ nav .copyright { font-size: 10px; text-shadow: black 0px 1px 1px; padding-top: 20px; - width: 212px; + width: 192px; } nav .copyright a { color: white; @@ -4358,3 +4361,8 @@ nav .copyright a { font-weight: bold; } /* Literal.Number.Integer.Long */ +.onecol .row-fluid .span4, +.onecol .row-fluid .span8 { + width: 100%; + margin-left: 0; +} diff --git a/tpl/base/sidebar.html b/tpl/base/sidebar.html index 2502f8a..8751fd4 100644 --- a/tpl/base/sidebar.html +++ b/tpl/base/sidebar.html @@ -52,7 +52,7 @@ {{ _('Submit') }} -
    • + {% if user %} -
    • +
    • diff --git a/tpl/home.html b/tpl/home.html index 4dec764..0806008 100644 --- a/tpl/home.html +++ b/tpl/home.html @@ -9,24 +9,22 @@
      {{ _('Latest Problem') }}
      - {% set latest_problem = "" %} {{ show_problem_list(latest_problem) }}
      {{ _('Latest Contest') }}
      - {% set latest_contest = "" %} {{ show_contest_list(latest_contest) }}
      -
      + {#
      {{ _('Latest Discuss') }}
      {% set latest_topic = "" %} {{ show_topic_list(latest_topic) }}
      -
      +
      #}
    • diff --git a/tpl/macros.html b/tpl/macros.html index 5c84fab..edf0d68 100644 --- a/tpl/macros.html +++ b/tpl/macros.html @@ -22,11 +22,13 @@ + {% for problem in problem_list %} - 1 - Hello World - helloworld + {{ problem.id }} + {{ problem.title }} + {{ problem.shortname }} + {% endfor %} {% endmacro %} @@ -35,6 +37,24 @@ {% endmacro %} {% macro show_contest_list(contest_list) %} + + + + + + + + + + {% for contest in contest_list %} + + + + + + {% endfor %} + +
      #TitleStatus
      {{ contest.id }}{{ contest.title }}{{ contest | get_contest_status }}
      {% endmacro %} {#================ Form ================#} diff --git a/tpl/problem_list.html b/tpl/problem_list.html index 2b56fb2..27278f5 100644 --- a/tpl/problem_list.html +++ b/tpl/problem_list.html @@ -12,7 +12,7 @@ {{ _('Time') }} {{ _('Memory') }} {{ _('Short Name') }} - {% if user %}{{ _('Status') }}{% endif %} + {% if user %}{{ _('Status') }}{% endif %} @@ -24,7 +24,7 @@ {{ problem.timelimit }} ms {{ problem.memlimit }} MB {{ problem.shortname }} - {% if user %}{{ problem.submit | get_submit_status }}{% endif %} + {% if user %}{{ problem.submit | get_submit_status }}{% endif %} {% endif %} {% endfor %} diff --git a/tpl/submit.html b/tpl/submit.html index f12cd0a..f6d4dcb 100644 --- a/tpl/submit.html +++ b/tpl/submit.html @@ -94,10 +94,29 @@
      {{ _('Code') }}
      + {% if submit.member_id == user.id or user.admin %} {{ code_highlighted }} + {% else %} +
      {{ _("You dont have permissions to view this code.") }}
      + {% endif %}
      {% endif %} + {% endblock %} diff --git a/tpl/submit_list.html b/tpl/submit_list.html index 05877ef..b141a00 100644 --- a/tpl/submit_list.html +++ b/tpl/submit_list.html @@ -8,13 +8,13 @@ # - {{ _('Status') }} + {{ _('Status') }} {{ _('Problem') }} {{ _('User') }} + {{ _('Language') }} {{ _('Time') }} {{ _('Memory') }} {{ _('Testpoint') }} - {{ _('Score') }} @@ -24,10 +24,10 @@ {{ submit | get_submit_status }} {{ submit.title }} {{ submit.username }} + {{ submit.lang | lang2humantext }} {{ submit.costtime }} ms {{ submit.costmemory }} KB {% if submit.testpoint %}{{ submit.testpoint }}{% endif %} - {{ submit.score }} {% endfor %} From 7a1fb9f3f0802c24411038579440420ab7097d9a Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Tue, 20 Mar 2012 04:16:06 +0800 Subject: [PATCH 31/56] add BSD LICENSES --- LICENSES | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 LICENSES diff --git a/LICENSES b/LICENSES new file mode 100644 index 0000000..2335f14 --- /dev/null +++ b/LICENSES @@ -0,0 +1,24 @@ +Copyright (c) 2012, Zeray Rice & Bob Robot. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 6a763dd37b3059ad543eeed337f55704d31b57b7 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 22 Mar 2012 19:16:34 +0800 Subject: [PATCH 32/56] fix db error --- judge/db/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/judge/db/__init__.py b/judge/db/__init__.py index d43b24e..05d0428 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -499,9 +499,10 @@ def select_judger_by_queue(self): return None ''' INSERT ''' def insert_judger(self, judger): - judger.id = self.db.execute("""INSERT INTO `judger` (`name`, `description`, `path`, `priority`, `queue_num`, `pubkey`, `create`) - VALUES (%s, %s, %s, 0, %s, UTC_TIMESTAMP())""", \ - judger.name, judger.description, judger.path, judger.pubkey) + judger.id = self.db.execute("""INSERT INTO `judger` (`name`, `description`, `path`, \ + `priority`, `queue_num`, `pubkey`, `create`) + VALUES (%s, %s, %s, %s, 0, %s, UTC_TIMESTAMP())""", \ + judger.name, judger.description, judger.path, judger.priority, judger.pubkey) ''' UPDATE ''' def update_judger(self, judger): self.db.execute("""UPDATE `judger` SET `name` = %s, From b5d7d9184dccdf3b66db02e4309643357992d031 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 22 Mar 2012 20:37:48 +0800 Subject: [PATCH 33/56] add language translate --- i18n/message.po | 473 ++++++++++++++++++++++++++ i18n/message_cn.po | 473 ++++++++++++++++++++++++++ i18n/zh_CN/LC_MESSAGES/message_cn.po | 473 ++++++++++++++++++++++++++ i18n/zh_CN/LC_MESSAGES/vulpix.mo | Bin 0 -> 5435 bytes i18n/zh_TW/LC_MESSAGES/message_tw.po | 474 +++++++++++++++++++++++++++ i18n/zh_TW/LC_MESSAGES/vulpix.mo | Bin 0 -> 5441 bytes judge/base/__init__.py | 14 +- 7 files changed, 1900 insertions(+), 7 deletions(-) create mode 100644 i18n/message.po create mode 100644 i18n/message_cn.po create mode 100644 i18n/zh_CN/LC_MESSAGES/message_cn.po create mode 100644 i18n/zh_CN/LC_MESSAGES/vulpix.mo create mode 100644 i18n/zh_TW/LC_MESSAGES/message_tw.po create mode 100644 i18n/zh_TW/LC_MESSAGES/vulpix.mo diff --git a/i18n/message.po b/i18n/message.po new file mode 100644 index 0000000..087a94e --- /dev/null +++ b/i18n/message.po @@ -0,0 +1,473 @@ +# Vulpix Translate File. +# Copyright (C) 2012 Zeray Rice +# This file is distributed under the same license as the Vulpix package. +# Zeray Rice , 2012. +# +#, +msgid "" +msgstr "" +"Project-Id-Version: 1.0 beta\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-03-22 19:52+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: problem.py:45 problem.py:82 problem.py:119 problem.py:142 problem.py:160 +#: contest.py:47 contest.py:67 home.py:16 home.py:18 member.py:107 +#: member.py:134 member.py:177 tpl/base/sidebar.html:34 +msgid "Home" +msgstr "" + +#: problem.py:46 problem.py:83 problem.py:120 problem.py:121 +#: tpl/submit.html:13 tpl/submit_list.html:12 tpl/base/sidebar.html:40 +#: tpl/contest.html:76 +msgid "Problem" +msgstr "" + +#: problem.py:68 +msgid "Please Choose Your Code File" +msgstr "" + +#: problem.py:72 +msgid "File Type Error!" +msgstr "" + +#: problem.py:75 +msgid "Error Code Language Select" +msgstr "" + +#: problem.py:79 +msgid "No Judger Seted!" +msgstr "" + +#: problem.py:143 problem.py:161 tpl/backstage/add_judger.html:18 +#: tpl/backstage/add_problem.html:40 tpl/backstage/add_contest.html:53 +#: tpl/problem.html:71 tpl/base/sidebar.html:52 tpl/contest.html:103 +msgid "Submit" +msgstr "" + +#: problem.py:144 tpl/submit_list.html:5 +msgid "Submit List" +msgstr "" + +#: problem.py:163 +#, python-format +msgid "Submit #%d - %s" +msgstr "" + +#: contest.py:48 contest.py:68 tpl/base/sidebar.html:46 +msgid "Contest" +msgstr "" + +#: contest.py:55 tpl/contest_list.html:5 +msgid "Contest List" +msgstr "" + +#: backstage.py:34 tpl/base/sidebar.html:93 +msgid "Add Problem" +msgstr "" + +#: backstage.py:38 backstage.py:79 +msgid "Edit Problem" +msgstr "" + +#: backstage.py:62 backstage.py:115 tpl/backstage/add_problem.html:16 +#: tpl/backstage/add_contest.html:16 tpl/contest_list.html:11 +#: tpl/problem_list.html:11 +msgid "Title" +msgstr "" + +#: backstage.py:63 tpl/backstage/add_problem.html:17 tpl/problem.html:24 +#: tpl/problem_list.html:14 tpl/contest.html:43 +msgid "Short Name" +msgstr "" + +#: backstage.py:64 tpl/backstage/add_problem.html:18 +msgid "Time Limit" +msgstr "" + +#: backstage.py:65 tpl/backstage/add_problem.html:19 +msgid "Memory Limit" +msgstr "" + +#: backstage.py:66 tpl/submit_list.html:17 +msgid "Testpoint" +msgstr "" + +#: backstage.py:67 tpl/backstage/add_problem.html:21 +#: tpl/backstage/add_contest.html:29 +msgid "Invisible" +msgstr "" + +#: backstage.py:68 tpl/backstage/add_problem.html:22 +msgid "Content" +msgstr "" + +#: backstage.py:69 tpl/backstage/add_problem.html:20 tpl/submit.html:68 +msgid "Test Point" +msgstr "" + +#: backstage.py:95 backstage.py:132 tpl/base/sidebar.html:99 +msgid "Add Contest" +msgstr "" + +#: backstage.py:100 +msgid "Edit Contest" +msgstr "" + +#: backstage.py:116 backstage.py:183 tpl/backstage/add_judger.html:16 +#: tpl/backstage/add_contest.html:30 +msgid "Description" +msgstr "" + +#: backstage.py:121 +msgid "Start/End Time Format is Invalid." +msgstr "" + +#: backstage.py:124 +msgid "Start/End Time is invalid." +msgstr "" + +#: backstage.py:152 tpl/base/sidebar.html:111 +msgid "Judger Manage" +msgstr "" + +#: backstage.py:159 tpl/backstage/judger.html:6 +msgid "Add Judger" +msgstr "" + +#: backstage.py:170 backstage.py:194 +msgid "Edit Judger" +msgstr "" + +#: backstage.py:182 tpl/backstage/add_judger.html:13 +#: tpl/backstage/judger.html:13 tpl/contest.html:42 +msgid "Name" +msgstr "" + +#: backstage.py:184 tpl/backstage/add_judger.html:14 +#: tpl/backstage/judger.html:14 +msgid "Path" +msgstr "" + +#: backstage.py:185 tpl/backstage/add_judger.html:15 +#: tpl/backstage/judger.html:15 +msgid "Priority" +msgstr "" + +#: backstage.py:186 tpl/backstage/add_judger.html:17 +msgid "RSA Public Key" +msgstr "" + +#: judge/base/__init__.py:122 +#, python-format +msgid "%s is required" +msgstr "" + +#: judge/base/__init__.py:128 +#, python-format +msgid "%s must be a number." +msgstr "" + +#: judge/base/__init__.py:131 judge/base/__init__.py:142 +#: judge/base/__init__.py:144 +#, python-format +msgid "%s is invalid." +msgstr "" + +#: judge/base/__init__.py:134 +#, python-format +msgid "%s is too long." +msgstr "" + +#: judge/base/__init__.py:136 +#, python-format +msgid "%s is too short." +msgstr "" + +#: judge/base/__init__.py:148 +msgid "Username" +msgstr "" + +#: judge/base/__init__.py:150 +msgid "A username can only contain letters and digits." +msgstr "" + +#: judge/base/__init__.py:154 +msgid "That username is taken. Please choose another." +msgstr "" + +#: judge/base/__init__.py:157 +msgid "Password" +msgstr "" + +#: judge/base/__init__.py:160 +msgid "E-mail" +msgstr "" + +#: judge/base/__init__.py:162 +msgid "Your Email address is invalid." +msgstr "" + +#: judge/base/__init__.py:166 +msgid "That Email is taken. Please choose another." +msgstr "" + +#: member.py:36 +msgid "Wrong Username and password combination." +msgstr "" + +#: member.py:101 member.py:109 member.py:132 member.py:136 +#: tpl/base/sidebar.html:77 +msgid "Settings" +msgstr "" + +#: member.py:121 tpl/settings.html:20 +msgid "Website" +msgstr "" + +#: member.py:123 tpl/settings.html:21 +msgid "Tagline" +msgstr "" + +#: member.py:124 tpl/settings.html:23 +msgid "Code Language" +msgstr "" + +#: member.py:125 tpl/settings.html:32 +msgid "Bio" +msgstr "" + +#: member.py:141 +msgid "Settings Updated." +msgstr "" + +#: member.py:154 +msgid "Wrong Passowrd" +msgstr "" + +#: member.py:156 tpl/settings_changepass.html:10 +#: tpl/settings_changepass.html:15 tpl/settings.html:39 tpl/settings.html:44 +msgid "Change Password" +msgstr "" + +#: member.py:166 +msgid "Password Updated." +msgstr "" + +#: tpl/backstage/judger.html:7 +msgid "Judger List" +msgstr "" + +#: tpl/backstage/judger.html:16 +msgid "Queue" +msgstr "" + +#: tpl/backstage/judger.html:17 tpl/backstage/judger.html:27 +msgid "Edit" +msgstr "" + +#: tpl/backstage/add_problem.html:24 +msgid "Problem Tag" +msgstr "" + +#: tpl/backstage/add_problem.html:27 tpl/backstage/add_contest.html:35 +msgid "Add" +msgstr "" + +#: tpl/backstage/add_contest.html:18 tpl/contest_list.html:12 +#: tpl/contest.html:19 +msgid "Start Time" +msgstr "" + +#: tpl/backstage/add_contest.html:24 tpl/contest.html:23 +msgid "End Time" +msgstr "" + +#: tpl/backstage/add_contest.html:32 +msgid "Related Problem" +msgstr "" + +#: tpl/member.html:12 +msgid "ID:" +msgstr "" + +#: tpl/member.html:12 +msgid "Joined at" +msgstr "" + +#: tpl/problem.html:7 +msgid "This Problem is Invisible!" +msgstr "" + +#: tpl/problem.html:28 tpl/submit.html:75 tpl/submit_list.html:15 +#: tpl/problem_list.html:12 +msgid "Time" +msgstr "" + +#: tpl/problem.html:32 tpl/submit.html:76 tpl/submit_list.html:16 +#: tpl/problem_list.html:13 +msgid "Memory" +msgstr "" + +#: tpl/problem.html:36 +msgid "Tags" +msgstr "" + +#: tpl/problem.html:53 tpl/contest.html:73 +msgid "Submit Problem" +msgstr "" + +#: tpl/problem.html:57 tpl/contest.html:89 +msgid "Code File" +msgstr "" + +#: tpl/problem.html:63 tpl/submit.html:25 tpl/submit_list.html:14 +#: tpl/contest.html:44 tpl/contest.html:95 +msgid "Language" +msgstr "" + +#: tpl/submit.html:5 +msgid "Submit Detail" +msgstr "" + +#: tpl/submit.html:17 +msgid "Member" +msgstr "" + +#: tpl/submit.html:21 tpl/submit.html:74 tpl/submit_list.html:11 +#: tpl/contest_list.html:14 tpl/problem_list.html:15 tpl/contest.html:27 +#: tpl/contest.html:46 +msgid "Status" +msgstr "" + +#: tpl/submit.html:29 tpl/contest.html:47 +msgid "Score" +msgstr "" + +#: tpl/submit.html:33 +msgid "Cost Time" +msgstr "" + +#: tpl/submit.html:37 +msgid "Cost Memory" +msgstr "" + +#: tpl/submit.html:41 tpl/contest.html:45 +msgid "Submit Time" +msgstr "" + +#: tpl/submit.html:46 +msgid "IP" +msgstr "" + +#: tpl/submit.html:50 +msgid "User-Agent" +msgstr "" + +#: tpl/submit.html:59 +msgid "Compile Output" +msgstr "" + +#: tpl/submit.html:95 +msgid "Code" +msgstr "" + +#: tpl/submit.html:100 +msgid "You dont have permissions to view this code." +msgstr "" + +#: tpl/home.html:10 +msgid "Latest Problem" +msgstr "" + +#: tpl/home.html:16 +msgid "Latest Contest" +msgstr "" + +#: tpl/home.html:22 +msgid "Latest Discuss" +msgstr "" + +#: tpl/home.html:31 +msgid "Notice" +msgstr "" + +#: tpl/home.html:37 +msgid "Site Count" +msgstr "" + +#: tpl/submit_list.html:13 +msgid "User" +msgstr "" + +#: tpl/settings_changepass.html:13 tpl/settings.html:42 +msgid "Current Password" +msgstr "" + +#: tpl/settings_changepass.html:14 tpl/settings.html:43 +msgid "New Password" +msgstr "" + +#: tpl/contest_list.html:13 +msgid "End time" +msgstr "" + +#: tpl/base/sidebar.html:58 +msgid "Forum" +msgstr "" + +#: tpl/base/sidebar.html:64 +msgid "List" +msgstr "" + +#: tpl/base/sidebar.html:71 +msgid "Notes" +msgstr "" + +#: tpl/base/sidebar.html:83 +msgid "Sign Out" +msgstr "" + +#: tpl/base/sidebar.html:88 +msgid "Backstage" +msgstr "" + +#: tpl/base/sidebar.html:105 +msgid "Add Node" +msgstr "" + +#: tpl/base/sidebar.html:119 tpl/signup.html:46 tpl/signin.html:5 +#: tpl/signin.html:39 +msgid "Sign In" +msgstr "" + +#: tpl/base/sidebar.html:125 tpl/signup.html:5 tpl/signup.html:43 +#: tpl/signin.html:42 +msgid "Sign Up" +msgstr "" + +#: tpl/base/sidebar.html:136 +msgid "Help" +msgstr "" + +#: tpl/settings.html:16 +msgid "Basic Settings" +msgstr "" + +#: tpl/settings.html:19 +msgid "Email" +msgstr "" + +#: tpl/settings.html:33 +msgid "Save Changes" +msgstr "" + +#: tpl/problem_list.html:5 tpl/contest.html:37 +msgid "Problem List" +msgstr "" diff --git a/i18n/message_cn.po b/i18n/message_cn.po new file mode 100644 index 0000000..625ea3d --- /dev/null +++ b/i18n/message_cn.po @@ -0,0 +1,473 @@ +# Vulpix Translate File. +# Copyright (C) 2012 Zeray Rice +# This file is distributed under the same license as the Vulpix package. +# Zeray Rice , 2012. +# +#, +msgid "" +msgstr "" +"Project-Id-Version: 1.0 beta\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-03-22 19:52+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: problem.py:45 problem.py:82 problem.py:119 problem.py:142 problem.py:160 +#: contest.py:47 contest.py:67 home.py:16 home.py:18 member.py:107 +#: member.py:134 member.py:177 tpl/base/sidebar.html:34 +msgid "Home" +msgstr "首页" + +#: problem.py:46 problem.py:83 problem.py:120 problem.py:121 +#: tpl/submit.html:13 tpl/submit_list.html:12 tpl/base/sidebar.html:40 +#: tpl/contest.html:76 +msgid "Problem" +msgstr "题目" + +#: problem.py:68 +msgid "Please Choose Your Code File" +msgstr "请选择一个代码文件" + +#: problem.py:72 +msgid "File Type Error!" +msgstr "文件类型错误" + +#: problem.py:75 +msgid "Error Code Language Select" +msgstr "语言选项错误" + +#: problem.py:79 +msgid "No Judger Seted!" +msgstr "没有设置评测机" + +#: problem.py:143 problem.py:161 tpl/backstage/add_judger.html:18 +#: tpl/backstage/add_problem.html:40 tpl/backstage/add_contest.html:53 +#: tpl/problem.html:71 tpl/base/sidebar.html:52 tpl/contest.html:103 +msgid "Submit" +msgstr "提交" + +#: problem.py:144 tpl/submit_list.html:5 +msgid "Submit List" +msgstr "提交列表" + +#: problem.py:163 +#, python-format +msgid "Submit #%d - %s" +msgstr "提交 #%d - %s" + +#: contest.py:48 contest.py:68 tpl/base/sidebar.html:46 +msgid "Contest" +msgstr "比赛" + +#: contest.py:55 tpl/contest_list.html:5 +msgid "Contest List" +msgstr "比赛列表" + +#: backstage.py:34 tpl/base/sidebar.html:93 +msgid "Add Problem" +msgstr "添加题目" + +#: backstage.py:38 backstage.py:79 +msgid "Edit Problem" +msgstr "编辑题目" + +#: backstage.py:62 backstage.py:115 tpl/backstage/add_problem.html:16 +#: tpl/backstage/add_contest.html:16 tpl/contest_list.html:11 +#: tpl/problem_list.html:11 +msgid "Title" +msgstr "标题" + +#: backstage.py:63 tpl/backstage/add_problem.html:17 tpl/problem.html:24 +#: tpl/problem_list.html:14 tpl/contest.html:43 +msgid "Short Name" +msgstr "名称" + +#: backstage.py:64 tpl/backstage/add_problem.html:18 +msgid "Time Limit" +msgstr "时间限制" + +#: backstage.py:65 tpl/backstage/add_problem.html:19 +msgid "Memory Limit" +msgstr "空间限制" + +#: backstage.py:66 tpl/submit_list.html:17 +msgid "Testpoint" +msgstr "测试点数" + +#: backstage.py:67 tpl/backstage/add_problem.html:21 +#: tpl/backstage/add_contest.html:29 +msgid "Invisible" +msgstr "不可见" + +#: backstage.py:68 tpl/backstage/add_problem.html:22 +msgid "Content" +msgstr "正文" + +#: backstage.py:69 tpl/backstage/add_problem.html:20 tpl/submit.html:68 +msgid "Test Point" +msgstr "测试点" + +#: backstage.py:95 backstage.py:132 tpl/base/sidebar.html:99 +msgid "Add Contest" +msgstr "添加比赛" + +#: backstage.py:100 +msgid "Edit Contest" +msgstr "编辑比赛" + +#: backstage.py:116 backstage.py:183 tpl/backstage/add_judger.html:16 +#: tpl/backstage/add_contest.html:30 +msgid "Description" +msgstr "描述" + +#: backstage.py:121 +msgid "Start/End Time Format is Invalid." +msgstr "开始/结束时间格式不正确。" + +#: backstage.py:124 +msgid "Start/End Time is invalid." +msgstr "开始/结束时间不正确。" + +#: backstage.py:152 tpl/base/sidebar.html:111 +msgid "Judger Manage" +msgstr "评测机管理" + +#: backstage.py:159 tpl/backstage/judger.html:6 +msgid "Add Judger" +msgstr "添加评测机" + +#: backstage.py:170 backstage.py:194 +msgid "Edit Judger" +msgstr "编辑评测机" + +#: backstage.py:182 tpl/backstage/add_judger.html:13 +#: tpl/backstage/judger.html:13 tpl/contest.html:42 +msgid "Name" +msgstr "名称" + +#: backstage.py:184 tpl/backstage/add_judger.html:14 +#: tpl/backstage/judger.html:14 +msgid "Path" +msgstr "路径" + +#: backstage.py:185 tpl/backstage/add_judger.html:15 +#: tpl/backstage/judger.html:15 +msgid "Priority" +msgstr "优先级" + +#: backstage.py:186 tpl/backstage/add_judger.html:17 +msgid "RSA Public Key" +msgstr "RSA 公钥" + +#: judge/base/__init__.py:122 +#, python-format +msgid "%s is required" +msgstr "要求填写 %s。" + +#: judge/base/__init__.py:128 +#, python-format +msgid "%s must be a number." +msgstr "%s 必须为数字。" + +#: judge/base/__init__.py:131 judge/base/__init__.py:142 +#: judge/base/__init__.py:144 +#, python-format +msgid "%s is invalid." +msgstr "%s " + +#: judge/base/__init__.py:134 +#, python-format +msgid "%s is too long." +msgstr "%s 过长。" + +#: judge/base/__init__.py:136 +#, python-format +msgid "%s is too short." +msgstr "%s 过短。" + +#: judge/base/__init__.py:148 +msgid "Username" +msgstr "用户名" + +#: judge/base/__init__.py:150 +msgid "A username can only contain letters and digits." +msgstr "用户名只允许包含数字和字母。" + +#: judge/base/__init__.py:154 +msgid "That username is taken. Please choose another." +msgstr "用户名已被使用,请换一个。" + +#: judge/base/__init__.py:157 +msgid "Password" +msgstr "密码" + +#: judge/base/__init__.py:160 +msgid "E-mail" +msgstr "邮箱" + +#: judge/base/__init__.py:162 +msgid "Your Email address is invalid." +msgstr "邮箱地址不正确。" + +#: judge/base/__init__.py:166 +msgid "That Email is taken. Please choose another." +msgstr "邮箱已被使用,请换一个。" + +#: member.py:36 +msgid "Wrong Username and password combination." +msgstr "用户名或密码错误。" + +#: member.py:101 member.py:109 member.py:132 member.py:136 +#: tpl/base/sidebar.html:77 +msgid "Settings" +msgstr "设置" + +#: member.py:121 tpl/settings.html:20 +msgid "Website" +msgstr "网站" + +#: member.py:123 tpl/settings.html:21 +msgid "Tagline" +msgstr "签名" + +#: member.py:124 tpl/settings.html:23 +msgid "Code Language" +msgstr "编程语言" + +#: member.py:125 tpl/settings.html:32 +msgid "Bio" +msgstr "个人信息" + +#: member.py:141 +msgid "Settings Updated." +msgstr "设置已更新。" + +#: member.py:154 +msgid "Wrong Passowrd" +msgstr "密码错误" + +#: member.py:156 tpl/settings_changepass.html:10 +#: tpl/settings_changepass.html:15 tpl/settings.html:39 tpl/settings.html:44 +msgid "Change Password" +msgstr "更改密码" + +#: member.py:166 +msgid "Password Updated." +msgstr "密码已更新" + +#: tpl/backstage/judger.html:7 +msgid "Judger List" +msgstr "评测机列表" + +#: tpl/backstage/judger.html:16 +msgid "Queue" +msgstr "队列" + +#: tpl/backstage/judger.html:17 tpl/backstage/judger.html:27 +msgid "Edit" +msgstr "编辑" + +#: tpl/backstage/add_problem.html:24 +msgid "Problem Tag" +msgstr "题目标签" + +#: tpl/backstage/add_problem.html:27 tpl/backstage/add_contest.html:35 +msgid "Add" +msgstr "添加" + +#: tpl/backstage/add_contest.html:18 tpl/contest_list.html:12 +#: tpl/contest.html:19 +msgid "Start Time" +msgstr "开始时间" + +#: tpl/backstage/add_contest.html:24 tpl/contest.html:23 +msgid "End Time" +msgstr "结束时间" + +#: tpl/backstage/add_contest.html:32 +msgid "Related Problem" +msgstr "关联题目" + +#: tpl/member.html:12 +msgid "ID:" +msgstr "编号:" + +#: tpl/member.html:12 +msgid "Joined at" +msgstr "加入时间" + +#: tpl/problem.html:7 +msgid "This Problem is Invisible!" +msgstr "题目不可用!" + +#: tpl/problem.html:28 tpl/submit.html:75 tpl/submit_list.html:15 +#: tpl/problem_list.html:12 +msgid "Time" +msgstr "时间" + +#: tpl/problem.html:32 tpl/submit.html:76 tpl/submit_list.html:16 +#: tpl/problem_list.html:13 +msgid "Memory" +msgstr "内存" + +#: tpl/problem.html:36 +msgid "Tags" +msgstr "标签" + +#: tpl/problem.html:53 tpl/contest.html:73 +msgid "Submit Problem" +msgstr "提交题目" + +#: tpl/problem.html:57 tpl/contest.html:89 +msgid "Code File" +msgstr "代码文件" + +#: tpl/problem.html:63 tpl/submit.html:25 tpl/submit_list.html:14 +#: tpl/contest.html:44 tpl/contest.html:95 +msgid "Language" +msgstr "编程语言" + +#: tpl/submit.html:5 +msgid "Submit Detail" +msgstr "提交详情" + +#: tpl/submit.html:17 +msgid "Member" +msgstr "成员" + +#: tpl/submit.html:21 tpl/submit.html:74 tpl/submit_list.html:11 +#: tpl/contest_list.html:14 tpl/problem_list.html:15 tpl/contest.html:27 +#: tpl/contest.html:46 +msgid "Status" +msgstr "状态" + +#: tpl/submit.html:29 tpl/contest.html:47 +msgid "Score" +msgstr "得分" + +#: tpl/submit.html:33 +msgid "Cost Time" +msgstr "用时" + +#: tpl/submit.html:37 +msgid "Cost Memory" +msgstr "内存使用" + +#: tpl/submit.html:41 tpl/contest.html:45 +msgid "Submit Time" +msgstr "提交时间" + +#: tpl/submit.html:46 +msgid "IP" +msgstr "IP 地址" + +#: tpl/submit.html:50 +msgid "User-Agent" +msgstr "访问信息" + +#: tpl/submit.html:59 +msgid "Compile Output" +msgstr "编译输出" + +#: tpl/submit.html:95 +msgid "Code" +msgstr "代码" + +#: tpl/submit.html:100 +msgid "You dont have permissions to view this code." +msgstr "你没有权限查看此代码。" + +#: tpl/home.html:10 +msgid "Latest Problem" +msgstr "最新题目" + +#: tpl/home.html:16 +msgid "Latest Contest" +msgstr "最近比赛" + +#: tpl/home.html:22 +msgid "Latest Discuss" +msgstr "最新讨论" + +#: tpl/home.html:31 +msgid "Notice" +msgstr "公告" + +#: tpl/home.html:37 +msgid "Site Count" +msgstr "站点统计" + +#: tpl/submit_list.html:13 +msgid "User" +msgstr "用户" + +#: tpl/settings_changepass.html:13 tpl/settings.html:42 +msgid "Current Password" +msgstr "当前密码" + +#: tpl/settings_changepass.html:14 tpl/settings.html:43 +msgid "New Password" +msgstr "新建密码" + +#: tpl/contest_list.html:13 +msgid "End time" +msgstr "结束时间" + +#: tpl/base/sidebar.html:58 +msgid "Forum" +msgstr "论坛" + +#: tpl/base/sidebar.html:64 +msgid "List" +msgstr "列表" + +#: tpl/base/sidebar.html:71 +msgid "Notes" +msgstr "笔记" + +#: tpl/base/sidebar.html:83 +msgid "Sign Out" +msgstr "注销" + +#: tpl/base/sidebar.html:88 +msgid "Backstage" +msgstr "后台管理" + +#: tpl/base/sidebar.html:105 +msgid "Add Node" +msgstr "添加节点" + +#: tpl/base/sidebar.html:119 tpl/signup.html:46 tpl/signin.html:5 +#: tpl/signin.html:39 +msgid "Sign In" +msgstr "登录" + +#: tpl/base/sidebar.html:125 tpl/signup.html:5 tpl/signup.html:43 +#: tpl/signin.html:42 +msgid "Sign Up" +msgstr "注册" + +#: tpl/base/sidebar.html:136 +msgid "Help" +msgstr "帮助" + +#: tpl/settings.html:16 +msgid "Basic Settings" +msgstr "基本设置" + +#: tpl/settings.html:19 +msgid "Email" +msgstr "邮箱" + +#: tpl/settings.html:33 +msgid "Save Changes" +msgstr "保存更改" + +#: tpl/problem_list.html:5 tpl/contest.html:37 +msgid "Problem List" +msgstr "题目列表" diff --git a/i18n/zh_CN/LC_MESSAGES/message_cn.po b/i18n/zh_CN/LC_MESSAGES/message_cn.po new file mode 100644 index 0000000..625ea3d --- /dev/null +++ b/i18n/zh_CN/LC_MESSAGES/message_cn.po @@ -0,0 +1,473 @@ +# Vulpix Translate File. +# Copyright (C) 2012 Zeray Rice +# This file is distributed under the same license as the Vulpix package. +# Zeray Rice , 2012. +# +#, +msgid "" +msgstr "" +"Project-Id-Version: 1.0 beta\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-03-22 19:52+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: problem.py:45 problem.py:82 problem.py:119 problem.py:142 problem.py:160 +#: contest.py:47 contest.py:67 home.py:16 home.py:18 member.py:107 +#: member.py:134 member.py:177 tpl/base/sidebar.html:34 +msgid "Home" +msgstr "首页" + +#: problem.py:46 problem.py:83 problem.py:120 problem.py:121 +#: tpl/submit.html:13 tpl/submit_list.html:12 tpl/base/sidebar.html:40 +#: tpl/contest.html:76 +msgid "Problem" +msgstr "题目" + +#: problem.py:68 +msgid "Please Choose Your Code File" +msgstr "请选择一个代码文件" + +#: problem.py:72 +msgid "File Type Error!" +msgstr "文件类型错误" + +#: problem.py:75 +msgid "Error Code Language Select" +msgstr "语言选项错误" + +#: problem.py:79 +msgid "No Judger Seted!" +msgstr "没有设置评测机" + +#: problem.py:143 problem.py:161 tpl/backstage/add_judger.html:18 +#: tpl/backstage/add_problem.html:40 tpl/backstage/add_contest.html:53 +#: tpl/problem.html:71 tpl/base/sidebar.html:52 tpl/contest.html:103 +msgid "Submit" +msgstr "提交" + +#: problem.py:144 tpl/submit_list.html:5 +msgid "Submit List" +msgstr "提交列表" + +#: problem.py:163 +#, python-format +msgid "Submit #%d - %s" +msgstr "提交 #%d - %s" + +#: contest.py:48 contest.py:68 tpl/base/sidebar.html:46 +msgid "Contest" +msgstr "比赛" + +#: contest.py:55 tpl/contest_list.html:5 +msgid "Contest List" +msgstr "比赛列表" + +#: backstage.py:34 tpl/base/sidebar.html:93 +msgid "Add Problem" +msgstr "添加题目" + +#: backstage.py:38 backstage.py:79 +msgid "Edit Problem" +msgstr "编辑题目" + +#: backstage.py:62 backstage.py:115 tpl/backstage/add_problem.html:16 +#: tpl/backstage/add_contest.html:16 tpl/contest_list.html:11 +#: tpl/problem_list.html:11 +msgid "Title" +msgstr "标题" + +#: backstage.py:63 tpl/backstage/add_problem.html:17 tpl/problem.html:24 +#: tpl/problem_list.html:14 tpl/contest.html:43 +msgid "Short Name" +msgstr "名称" + +#: backstage.py:64 tpl/backstage/add_problem.html:18 +msgid "Time Limit" +msgstr "时间限制" + +#: backstage.py:65 tpl/backstage/add_problem.html:19 +msgid "Memory Limit" +msgstr "空间限制" + +#: backstage.py:66 tpl/submit_list.html:17 +msgid "Testpoint" +msgstr "测试点数" + +#: backstage.py:67 tpl/backstage/add_problem.html:21 +#: tpl/backstage/add_contest.html:29 +msgid "Invisible" +msgstr "不可见" + +#: backstage.py:68 tpl/backstage/add_problem.html:22 +msgid "Content" +msgstr "正文" + +#: backstage.py:69 tpl/backstage/add_problem.html:20 tpl/submit.html:68 +msgid "Test Point" +msgstr "测试点" + +#: backstage.py:95 backstage.py:132 tpl/base/sidebar.html:99 +msgid "Add Contest" +msgstr "添加比赛" + +#: backstage.py:100 +msgid "Edit Contest" +msgstr "编辑比赛" + +#: backstage.py:116 backstage.py:183 tpl/backstage/add_judger.html:16 +#: tpl/backstage/add_contest.html:30 +msgid "Description" +msgstr "描述" + +#: backstage.py:121 +msgid "Start/End Time Format is Invalid." +msgstr "开始/结束时间格式不正确。" + +#: backstage.py:124 +msgid "Start/End Time is invalid." +msgstr "开始/结束时间不正确。" + +#: backstage.py:152 tpl/base/sidebar.html:111 +msgid "Judger Manage" +msgstr "评测机管理" + +#: backstage.py:159 tpl/backstage/judger.html:6 +msgid "Add Judger" +msgstr "添加评测机" + +#: backstage.py:170 backstage.py:194 +msgid "Edit Judger" +msgstr "编辑评测机" + +#: backstage.py:182 tpl/backstage/add_judger.html:13 +#: tpl/backstage/judger.html:13 tpl/contest.html:42 +msgid "Name" +msgstr "名称" + +#: backstage.py:184 tpl/backstage/add_judger.html:14 +#: tpl/backstage/judger.html:14 +msgid "Path" +msgstr "路径" + +#: backstage.py:185 tpl/backstage/add_judger.html:15 +#: tpl/backstage/judger.html:15 +msgid "Priority" +msgstr "优先级" + +#: backstage.py:186 tpl/backstage/add_judger.html:17 +msgid "RSA Public Key" +msgstr "RSA 公钥" + +#: judge/base/__init__.py:122 +#, python-format +msgid "%s is required" +msgstr "要求填写 %s。" + +#: judge/base/__init__.py:128 +#, python-format +msgid "%s must be a number." +msgstr "%s 必须为数字。" + +#: judge/base/__init__.py:131 judge/base/__init__.py:142 +#: judge/base/__init__.py:144 +#, python-format +msgid "%s is invalid." +msgstr "%s " + +#: judge/base/__init__.py:134 +#, python-format +msgid "%s is too long." +msgstr "%s 过长。" + +#: judge/base/__init__.py:136 +#, python-format +msgid "%s is too short." +msgstr "%s 过短。" + +#: judge/base/__init__.py:148 +msgid "Username" +msgstr "用户名" + +#: judge/base/__init__.py:150 +msgid "A username can only contain letters and digits." +msgstr "用户名只允许包含数字和字母。" + +#: judge/base/__init__.py:154 +msgid "That username is taken. Please choose another." +msgstr "用户名已被使用,请换一个。" + +#: judge/base/__init__.py:157 +msgid "Password" +msgstr "密码" + +#: judge/base/__init__.py:160 +msgid "E-mail" +msgstr "邮箱" + +#: judge/base/__init__.py:162 +msgid "Your Email address is invalid." +msgstr "邮箱地址不正确。" + +#: judge/base/__init__.py:166 +msgid "That Email is taken. Please choose another." +msgstr "邮箱已被使用,请换一个。" + +#: member.py:36 +msgid "Wrong Username and password combination." +msgstr "用户名或密码错误。" + +#: member.py:101 member.py:109 member.py:132 member.py:136 +#: tpl/base/sidebar.html:77 +msgid "Settings" +msgstr "设置" + +#: member.py:121 tpl/settings.html:20 +msgid "Website" +msgstr "网站" + +#: member.py:123 tpl/settings.html:21 +msgid "Tagline" +msgstr "签名" + +#: member.py:124 tpl/settings.html:23 +msgid "Code Language" +msgstr "编程语言" + +#: member.py:125 tpl/settings.html:32 +msgid "Bio" +msgstr "个人信息" + +#: member.py:141 +msgid "Settings Updated." +msgstr "设置已更新。" + +#: member.py:154 +msgid "Wrong Passowrd" +msgstr "密码错误" + +#: member.py:156 tpl/settings_changepass.html:10 +#: tpl/settings_changepass.html:15 tpl/settings.html:39 tpl/settings.html:44 +msgid "Change Password" +msgstr "更改密码" + +#: member.py:166 +msgid "Password Updated." +msgstr "密码已更新" + +#: tpl/backstage/judger.html:7 +msgid "Judger List" +msgstr "评测机列表" + +#: tpl/backstage/judger.html:16 +msgid "Queue" +msgstr "队列" + +#: tpl/backstage/judger.html:17 tpl/backstage/judger.html:27 +msgid "Edit" +msgstr "编辑" + +#: tpl/backstage/add_problem.html:24 +msgid "Problem Tag" +msgstr "题目标签" + +#: tpl/backstage/add_problem.html:27 tpl/backstage/add_contest.html:35 +msgid "Add" +msgstr "添加" + +#: tpl/backstage/add_contest.html:18 tpl/contest_list.html:12 +#: tpl/contest.html:19 +msgid "Start Time" +msgstr "开始时间" + +#: tpl/backstage/add_contest.html:24 tpl/contest.html:23 +msgid "End Time" +msgstr "结束时间" + +#: tpl/backstage/add_contest.html:32 +msgid "Related Problem" +msgstr "关联题目" + +#: tpl/member.html:12 +msgid "ID:" +msgstr "编号:" + +#: tpl/member.html:12 +msgid "Joined at" +msgstr "加入时间" + +#: tpl/problem.html:7 +msgid "This Problem is Invisible!" +msgstr "题目不可用!" + +#: tpl/problem.html:28 tpl/submit.html:75 tpl/submit_list.html:15 +#: tpl/problem_list.html:12 +msgid "Time" +msgstr "时间" + +#: tpl/problem.html:32 tpl/submit.html:76 tpl/submit_list.html:16 +#: tpl/problem_list.html:13 +msgid "Memory" +msgstr "内存" + +#: tpl/problem.html:36 +msgid "Tags" +msgstr "标签" + +#: tpl/problem.html:53 tpl/contest.html:73 +msgid "Submit Problem" +msgstr "提交题目" + +#: tpl/problem.html:57 tpl/contest.html:89 +msgid "Code File" +msgstr "代码文件" + +#: tpl/problem.html:63 tpl/submit.html:25 tpl/submit_list.html:14 +#: tpl/contest.html:44 tpl/contest.html:95 +msgid "Language" +msgstr "编程语言" + +#: tpl/submit.html:5 +msgid "Submit Detail" +msgstr "提交详情" + +#: tpl/submit.html:17 +msgid "Member" +msgstr "成员" + +#: tpl/submit.html:21 tpl/submit.html:74 tpl/submit_list.html:11 +#: tpl/contest_list.html:14 tpl/problem_list.html:15 tpl/contest.html:27 +#: tpl/contest.html:46 +msgid "Status" +msgstr "状态" + +#: tpl/submit.html:29 tpl/contest.html:47 +msgid "Score" +msgstr "得分" + +#: tpl/submit.html:33 +msgid "Cost Time" +msgstr "用时" + +#: tpl/submit.html:37 +msgid "Cost Memory" +msgstr "内存使用" + +#: tpl/submit.html:41 tpl/contest.html:45 +msgid "Submit Time" +msgstr "提交时间" + +#: tpl/submit.html:46 +msgid "IP" +msgstr "IP 地址" + +#: tpl/submit.html:50 +msgid "User-Agent" +msgstr "访问信息" + +#: tpl/submit.html:59 +msgid "Compile Output" +msgstr "编译输出" + +#: tpl/submit.html:95 +msgid "Code" +msgstr "代码" + +#: tpl/submit.html:100 +msgid "You dont have permissions to view this code." +msgstr "你没有权限查看此代码。" + +#: tpl/home.html:10 +msgid "Latest Problem" +msgstr "最新题目" + +#: tpl/home.html:16 +msgid "Latest Contest" +msgstr "最近比赛" + +#: tpl/home.html:22 +msgid "Latest Discuss" +msgstr "最新讨论" + +#: tpl/home.html:31 +msgid "Notice" +msgstr "公告" + +#: tpl/home.html:37 +msgid "Site Count" +msgstr "站点统计" + +#: tpl/submit_list.html:13 +msgid "User" +msgstr "用户" + +#: tpl/settings_changepass.html:13 tpl/settings.html:42 +msgid "Current Password" +msgstr "当前密码" + +#: tpl/settings_changepass.html:14 tpl/settings.html:43 +msgid "New Password" +msgstr "新建密码" + +#: tpl/contest_list.html:13 +msgid "End time" +msgstr "结束时间" + +#: tpl/base/sidebar.html:58 +msgid "Forum" +msgstr "论坛" + +#: tpl/base/sidebar.html:64 +msgid "List" +msgstr "列表" + +#: tpl/base/sidebar.html:71 +msgid "Notes" +msgstr "笔记" + +#: tpl/base/sidebar.html:83 +msgid "Sign Out" +msgstr "注销" + +#: tpl/base/sidebar.html:88 +msgid "Backstage" +msgstr "后台管理" + +#: tpl/base/sidebar.html:105 +msgid "Add Node" +msgstr "添加节点" + +#: tpl/base/sidebar.html:119 tpl/signup.html:46 tpl/signin.html:5 +#: tpl/signin.html:39 +msgid "Sign In" +msgstr "登录" + +#: tpl/base/sidebar.html:125 tpl/signup.html:5 tpl/signup.html:43 +#: tpl/signin.html:42 +msgid "Sign Up" +msgstr "注册" + +#: tpl/base/sidebar.html:136 +msgid "Help" +msgstr "帮助" + +#: tpl/settings.html:16 +msgid "Basic Settings" +msgstr "基本设置" + +#: tpl/settings.html:19 +msgid "Email" +msgstr "邮箱" + +#: tpl/settings.html:33 +msgid "Save Changes" +msgstr "保存更改" + +#: tpl/problem_list.html:5 tpl/contest.html:37 +msgid "Problem List" +msgstr "题目列表" diff --git a/i18n/zh_CN/LC_MESSAGES/vulpix.mo b/i18n/zh_CN/LC_MESSAGES/vulpix.mo new file mode 100644 index 0000000000000000000000000000000000000000..432bebd7784e96f142f10886c5d9508226bf86a2 GIT binary patch literal 5435 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 +# This file is distributed under the same license as the Vulpix package. +# Zeray Rice , 2012. +# +#, +msgid "" +msgstr "" +"Project-Id-Version: 1.0 beta\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-03-22 19:52+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: problem.py:45 problem.py:82 problem.py:119 problem.py:142 problem.py:160 +#: contest.py:47 contest.py:67 home.py:16 home.py:18 member.py:107 +#: member.py:134 member.py:177 tpl/base/sidebar.html:34 +msgid "Home" +msgstr "首頁" + +#: problem.py:46 problem.py:83 problem.py:120 problem.py:121 +#: tpl/submit.html:13 tpl/submit_list.html:12 tpl/base/sidebar.html:40 +#: tpl/contest.html:76 +msgid "Problem" +msgstr "題目" + +#: problem.py:68 +msgid "Please Choose Your Code File" +msgstr "請選擇一個代碼文件" + +#: problem.py:72 +msgid "File Type Error!" +msgstr "文件類型錯誤" + +#: problem.py:75 +msgid "Error Code Language Select" +msgstr "語言選項錯誤" + +#: problem.py:79 +msgid "No Judger Seted!" +msgstr "沒有設置評測機" + +#: problem.py:143 problem.py:161 tpl/backstage/add_judger.html:18 +#: tpl/backstage/add_problem.html:40 tpl/backstage/add_contest.html:53 +#: tpl/problem.html:71 tpl/base/sidebar.html:52 tpl/contest.html:103 +msgid "Submit" +msgstr "提交" + +#: problem.py:144 tpl/submit_list.html:5 +msgid "Submit List" +msgstr "提交列表" + +#: problem.py:163 +#, python-format +msgid "Submit #%d - %s" +msgstr "提交 #%d - %s" + +#: contest.py:48 contest.py:68 tpl/base/sidebar.html:46 +msgid "Contest" +msgstr "比賽" + +#: contest.py:55 tpl/contest_list.html:5 +msgid "Contest List" +msgstr "比賽列表" + +#: backstage.py:34 tpl/base/sidebar.html:93 +msgid "Add Problem" +msgstr "添加題目" + +#: backstage.py:38 backstage.py:79 +msgid "Edit Problem" +msgstr "編輯題目" + +#: backstage.py:62 backstage.py:115 tpl/backstage/add_problem.html:16 +#: tpl/backstage/add_contest.html:16 tpl/contest_list.html:11 +#: tpl/problem_list.html:11 +msgid "Title" +msgstr "標題" + +#: backstage.py:63 tpl/backstage/add_problem.html:17 tpl/problem.html:24 +#: tpl/problem_list.html:14 tpl/contest.html:43 +msgid "Short Name" +msgstr "名稱" + +#: backstage.py:64 tpl/backstage/add_problem.html:18 +msgid "Time Limit" +msgstr "時間限制" + +#: backstage.py:65 tpl/backstage/add_problem.html:19 +msgid "Memory Limit" +msgstr "空間限制" + +#: backstage.py:66 tpl/submit_list.html:17 +msgid "Testpoint" +msgstr "測試點數" + +#: backstage.py:67 tpl/backstage/add_problem.html:21 +#: tpl/backstage/add_contest.html:29 +msgid "Invisible" +msgstr "不可見" + +#: backstage.py:68 tpl/backstage/add_problem.html:22 +msgid "Content" +msgstr "正文" + +#: backstage.py:69 tpl/backstage/add_problem.html:20 tpl/submit.html:68 +msgid "Test Point" +msgstr "測試點" + +#: backstage.py:95 backstage.py:132 tpl/base/sidebar.html:99 +msgid "Add Contest" +msgstr "添加比賽" + +#: backstage.py:100 +msgid "Edit Contest" +msgstr "編輯比賽" + +#: backstage.py:116 backstage.py:183 tpl/backstage/add_judger.html:16 +#: tpl/backstage/add_contest.html:30 +msgid "Description" +msgstr "描述" + +#: backstage.py:121 +msgid "Start/End Time Format is Invalid." +msgstr "開始/結束時間格式不正確。" + +#: backstage.py:124 +msgid "Start/End Time is invalid." +msgstr "開始/結束時間不正確。" + +#: backstage.py:152 tpl/base/sidebar.html:111 +msgid "Judger Manage" +msgstr "評測機管理" + +#: backstage.py:159 tpl/backstage/judger.html:6 +msgid "Add Judger" +msgstr "添加評測機" + +#: backstage.py:170 backstage.py:194 +msgid "Edit Judger" +msgstr "編輯評測機" + +#: backstage.py:182 tpl/backstage/add_judger.html:13 +#: tpl/backstage/judger.html:13 tpl/contest.html:42 +msgid "Name" +msgstr "名稱" + +#: backstage.py:184 tpl/backstage/add_judger.html:14 +#: tpl/backstage/judger.html:14 +msgid "Path" +msgstr "路徑" + +#: backstage.py:185 tpl/backstage/add_judger.html:15 +#: tpl/backstage/judger.html:15 +msgid "Priority" +msgstr "優先順序" + +#: backstage.py:186 tpl/backstage/add_judger.html:17 +msgid "RSA Public Key" +msgstr "RSA 公鑰" + +#: judge/base/__init__.py:122 +#, python-format +msgid "%s is required" +msgstr "要求填寫 %s。" + +#: judge/base/__init__.py:128 +#, python-format +msgid "%s must be a number." +msgstr "%s 必須為數字。" + +#: judge/base/__init__.py:131 judge/base/__init__.py:142 +#: judge/base/__init__.py:144 +#, python-format +msgid "%s is invalid." +msgstr "%s " + +#: judge/base/__init__.py:134 +#, python-format +msgid "%s is too long." +msgstr "%s 過長。" + +#: judge/base/__init__.py:136 +#, python-format +msgid "%s is too short." +msgstr "%s 過短。" + +#: judge/base/__init__.py:148 +msgid "Username" +msgstr "用戶名" + +#: judge/base/__init__.py:150 +msgid "A username can only contain letters and digits." +msgstr "用戶名只允許包含數字和字母。" + +#: judge/base/__init__.py:154 +msgid "That username is taken. Please choose another." +msgstr "用戶名已被使用,請換一個。" + +#: judge/base/__init__.py:157 +msgid "Password" +msgstr "密碼" + +#: judge/base/__init__.py:160 +msgid "E-mail" +msgstr "郵箱" + +#: judge/base/__init__.py:162 +msgid "Your Email address is invalid." +msgstr "郵箱地址不正確。" + +#: judge/base/__init__.py:166 +msgid "That Email is taken. Please choose another." +msgstr "郵箱已被使用,請換一個。" + +#: member.py:36 +msgid "Wrong Username and password combination." +msgstr "用戶名或密碼錯誤。" + +#: member.py:101 member.py:109 member.py:132 member.py:136 +#: tpl/base/sidebar.html:77 +msgid "Settings" +msgstr "設置" + +#: member.py:121 tpl/settings.html:20 +msgid "Website" +msgstr "網站" + +#: member.py:123 tpl/settings.html:21 +msgid "Tagline" +msgstr "簽名" + +#: member.py:124 tpl/settings.html:23 +msgid "Code Language" +msgstr "編程語言" + +#: member.py:125 tpl/settings.html:32 +msgid "Bio" +msgstr "個人資訊" + +#: member.py:141 +msgid "Settings Updated." +msgstr "設置已更新。" + +#: member.py:154 +msgid "Wrong Passowrd" +msgstr "密碼錯誤" + +#: member.py:156 tpl/settings_changepass.html:10 +#: tpl/settings_changepass.html:15 tpl/settings.html:39 tpl/settings.html:44 +msgid "Change Password" +msgstr "更改密碼" + +#: member.py:166 +msgid "Password Updated." +msgstr "密碼已更新" + +#: tpl/backstage/judger.html:7 +msgid "Judger List" +msgstr "評測機列表" + +#: tpl/backstage/judger.html:16 +msgid "Queue" +msgstr "隊列" + +#: tpl/backstage/judger.html:17 tpl/backstage/judger.html:27 +msgid "Edit" +msgstr "編輯" + +#: tpl/backstage/add_problem.html:24 +msgid "Problem Tag" +msgstr "題目標籤" + +#: tpl/backstage/add_problem.html:27 tpl/backstage/add_contest.html:35 +msgid "Add" +msgstr "添加" + +#: tpl/backstage/add_contest.html:18 tpl/contest_list.html:12 +#: tpl/contest.html:19 +msgid "Start Time" +msgstr "開始時間" + +#: tpl/backstage/add_contest.html:24 tpl/contest.html:23 +msgid "End Time" +msgstr "結束時間" + +#: tpl/backstage/add_contest.html:32 +msgid "Related Problem" +msgstr "關聯題目" + +#: tpl/member.html:12 +msgid "ID:" +msgstr "編號:" + +#: tpl/member.html:12 +msgid "Joined at" +msgstr "加入時間" + +#: tpl/problem.html:7 +msgid "This Problem is Invisible!" +msgstr "題目不可用!" + +#: tpl/problem.html:28 tpl/submit.html:75 tpl/submit_list.html:15 +#: tpl/problem_list.html:12 +msgid "Time" +msgstr "時間" + +#: tpl/problem.html:32 tpl/submit.html:76 tpl/submit_list.html:16 +#: tpl/problem_list.html:13 +msgid "Memory" +msgstr "內存" + +#: tpl/problem.html:36 +msgid "Tags" +msgstr "標籤" + +#: tpl/problem.html:53 tpl/contest.html:73 +msgid "Submit Problem" +msgstr "提交題目" + +#: tpl/problem.html:57 tpl/contest.html:89 +msgid "Code File" +msgstr "代碼文件" + +#: tpl/problem.html:63 tpl/submit.html:25 tpl/submit_list.html:14 +#: tpl/contest.html:44 tpl/contest.html:95 +msgid "Language" +msgstr "編程語言" + +#: tpl/submit.html:5 +msgid "Submit Detail" +msgstr "提交詳情" + +#: tpl/submit.html:17 +msgid "Member" +msgstr "成員" + +#: tpl/submit.html:21 tpl/submit.html:74 tpl/submit_list.html:11 +#: tpl/contest_list.html:14 tpl/problem_list.html:15 tpl/contest.html:27 +#: tpl/contest.html:46 +msgid "Status" +msgstr "狀態" + +#: tpl/submit.html:29 tpl/contest.html:47 +msgid "Score" +msgstr "得分" + +#: tpl/submit.html:33 +msgid "Cost Time" +msgstr "用時" + +#: tpl/submit.html:37 +msgid "Cost Memory" +msgstr "內存使用" + +#: tpl/submit.html:41 tpl/contest.html:45 +msgid "Submit Time" +msgstr "提交時間" + +#: tpl/submit.html:46 +msgid "IP" +msgstr "IP 地址" + +#: tpl/submit.html:50 +msgid "User-Agent" +msgstr "訪問資訊" + +#: tpl/submit.html:59 +msgid "Compile Output" +msgstr "編譯輸出" + +#: tpl/submit.html:95 +msgid "Code" +msgstr "代碼" + +#: tpl/submit.html:100 +msgid "You dont have permissions to view this code." +msgstr "你沒有許可權查看此代碼。" + +#: tpl/home.html:10 +msgid "Latest Problem" +msgstr "最新題目" + +#: tpl/home.html:16 +msgid "Latest Contest" +msgstr "最近比賽" + +#: tpl/home.html:22 +msgid "Latest Discuss" +msgstr "最新討論" + +#: tpl/home.html:31 +msgid "Notice" +msgstr "公告" + +#: tpl/home.html:37 +msgid "Site Count" +msgstr "站點統計" + +#: tpl/submit_list.html:13 +msgid "User" +msgstr "用戶" + +#: tpl/settings_changepass.html:13 tpl/settings.html:42 +msgid "Current Password" +msgstr "當前密碼" + +#: tpl/settings_changepass.html:14 tpl/settings.html:43 +msgid "New Password" +msgstr "新建密碼" + +#: tpl/contest_list.html:13 +msgid "End time" +msgstr "結束時間" + +#: tpl/base/sidebar.html:58 +msgid "Forum" +msgstr "論壇" + +#: tpl/base/sidebar.html:64 +msgid "List" +msgstr "列表" + +#: tpl/base/sidebar.html:71 +msgid "Notes" +msgstr "筆記" + +#: tpl/base/sidebar.html:83 +msgid "Sign Out" +msgstr "註銷" + +#: tpl/base/sidebar.html:88 +msgid "Backstage" +msgstr "後臺管理" + +#: tpl/base/sidebar.html:105 +msgid "Add Node" +msgstr "添加節點" + +#: tpl/base/sidebar.html:119 tpl/signup.html:46 tpl/signin.html:5 +#: tpl/signin.html:39 +msgid "Sign In" +msgstr "登錄" + +#: tpl/base/sidebar.html:125 tpl/signup.html:5 tpl/signup.html:43 +#: tpl/signin.html:42 +msgid "Sign Up" +msgstr "註冊" + +#: tpl/base/sidebar.html:136 +msgid "Help" +msgstr "幫助" + +#: tpl/settings.html:16 +msgid "Basic Settings" +msgstr "基本設置" + +#: tpl/settings.html:19 +msgid "Email" +msgstr "郵箱" + +#: tpl/settings.html:33 +msgid "Save Changes" +msgstr "儲存更改" + +#: tpl/problem_list.html:5 tpl/contest.html:37 +msgid "Problem List" +msgstr "題目列表" + diff --git a/i18n/zh_TW/LC_MESSAGES/vulpix.mo b/i18n/zh_TW/LC_MESSAGES/vulpix.mo new file mode 100644 index 0000000000000000000000000000000000000000..0ba5e3d0e017e84e8138f284373790a332f84375 GIT binary patch literal 5441 zcma)-e{fXQ6~`}%)y7}N)>^IAn^LSTYzSBt;x9t7Kp?-&5AnCY>^?V7cK5CCy@fKJ zItdaIlVF09U@$@=h#Nvk0s=7!;*9@j$Ii6VI-S~?YHQxxx6`TGj?>QApWpM|c}eJW zI=!>!eeStG&pqedyT83^VUIxB0=XVyT_^-Ky!R!1P~?||xB|>)7J^qozX$vZSOtC! zd>mX3ra>$rUIi}&hrm4W6nF{v7Pr3(;wRq6ht~fPqkj8xu(t2Mo{{_-{7Q&bdz)L`~=Thd?Ab#RTeCS+DLE2|ENatJ2yqEbn zNbBn$*>5p_1d{zbxW9|_y&%~)2$Fp#K$c97QH$^D(I_i+Eq%nX>1 zaVJ6Y_xm8({~7bIAnp54ko@>$iinUkOO(+ys&x)gZ;=A#f?Ef(76n zkoJ2Er18H2Y5YeZo$C+W{wHq#3rOc&fK6$iJdpOk3ZI+7d~g}K5xfE12CiNpL@!AB z@iQFaD)5&ejv}(m&%vvqFF+8#4_*V(`PYIpt_;KwaUbhXFimC?b2oE8^EHsxd7bqs z<~z*yx&Qaf9JhbQ{0Fz^A*f`>B9PX*fw_dajQei^$<8&bS9AX(tVfwof#ip$nR`H5 z_b_vqc><)ky}^8&`BRYW`4vd}%`iXb_Jvs7vzK`Tb16vstYY57T*v(ttUt)Q0#aO( z+`g09!F(R1{rgxS0>24;45a=>zNOOv~Pr&0+&GlF?b_*2&8r2X8r^u`+pA7yx%cDVg8MI2_Ai#cQx~Rkm9l! zq}>^U-hPnA4YGcmd5YVoL0a!!ZvO?he*ls{vmmX1A%gJ@@MaL# zO56=8hrmqlK2oeIA*GP{rfvkg6Kx!dWZh_Q6REUJY{h|Sa=T9t# z+y(g-WI3b^(g^YL6Qn{hdK_{e1W%v$_5ofg!gn**36w9CBby);<6_7PNKkG=jr4afryaOVZm{P+pxmAg4 z(E?Tt^{KRGs8LoeU6*k^84J2eHyd@s@){Cp(~=FURAe%pXi$v;Q7qG@Y9y6}DkDl# z>dE+a8PSuLq9tWqwJg;zrIL)ws20;K6XT;%5?O*Vs%d%kjp=AiHN0x29#y?cwV^k} z)r459M7Efg5>rt#wTP_6np!euinW?9N*a}9OqJD&X>QYvs3@V?^pWedIM>QCBu(>6 z^h64+vMOz*(iT)0kYvITHb|Cho`Q2$s0rQJjt#iDJ(hM^mnj$;JIPqUA_P*)q8ZfMqa5m?9cj~gg;N=)3F zR@17esV$b(>4rEmYLmKM)TnXVNd~iPm94ZBWtS;xBf6oA*~AMfbLQ33{gB>yYqeNX zmL-KpWSU>8Pk|Oz)YHhgT1&xjFXmo#IYpjSiD)Jii!LbwsCbw3KSs>Izv!~kFfZLe z?)D)UFNw;KToN?PQWaM*9`t%KlQ>^^&hlL3=T@C&A-C)C@_3(6 zag44q>GTqb&1!=Qe~ZlqUNSHL^lf+^d^H&5JxeKmI`C#C8nmQBSGhnSxnvaYgKVTc zNU26bGfnj1z`ES3A*ZcI7#P77^#&X45hWTmRP+2-76*C~S2t7^4c&*w5UUi)6$OQO zMJ*+-Mol4gLKS9Ai-y*wV`ivMFOqrHRdt~fL-ni)l_E2XD3ayHmFw$^*JE6H`I@*^pc}Ed zF)+2FtRj5g!SeWF4bd}IBrWxa*78(b(UNz_NTXtys&!X=-MY}Kxp8FH6RHskC*e@M z?L~4`gJ$K?AChp7G&|!v?7?AsbQoFvanlZJ&NV-m>p3&0WDkz8VxMct4YXx)Fw!+|&V9a)X`OmyQej%}%#1~~vIxVtiGTBUrd-Q;tX(GiP8Fi;8?AA%) zj2yxk5m@FKXt(Wi2Q$KMdCeYqapvqf9M?N?A5PwL+J1I7@8ooKx#z}2?wM2B@z1Q^u1%kJu_;* zxktFe9dMWPLhH;#6J>~(3Y-J>PULD^ZeW)^*(HJycxlE5_uHIIUv~Vk$n9@Ov-hWl zopXB-=6(Hc^Js9uohOhRe%>KV_t|Z`1ZSp?S<~ne@L{ukQ@PHa7&nz`KSQv0wTtX< zAJRU1YTV7ViCk}o{aObH##fflPYGvW+Me!0Ad$A&S0-ug|1#>l{%l8+)6yZFuI`yh z3YeJ&H3-h{~qUC;pZ max: - error.append(self._("%s is too long." % valName)) + error.append(self._("%s is too long.") % valName) elif _len(value) < min: - error.append(self._("%s is too short." % valName)) + error.append(self._("%s is too short.") % valName) if regex: if not regex.match(value): if regex_msg: error.append(regex_msg) else: - error.append(self._("%s is invalid." % valName)) + error.append(self._("%s is invalid.") % valName) elif vaild and value not in vaild: - errora.append(self._("%s is invalid." % valName)) + errora.append(self._("%s is invalid.") % valName) return error def check_username(self, usr, queryDB = False): error = [] From 3e2afdc127ed8ebc28b3a4519594085069c9e659 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 5 Apr 2012 16:43:24 +0800 Subject: [PATCH 34/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=20tag=20=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers.py | 3 ++- problem.py | 29 +++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/handlers.py b/handlers.py index 8dc79bb..9d23b7b 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 02:24:35 19/03/2012 +# MODIFIED: 16:36:58 05/04/2012 # DESCRIPTION: URL Route from api import * @@ -28,6 +28,7 @@ (r'/lang/(.*)', SetLanguageHandler), (r'/problem', ListProblemHandler), (r'/problem/([\d]*)', ViewProblemHandler), + (r'/tag/(.*)', ViewTagHandler), (r'/submit', ListSubmitHandler), (r'/submit/(.*)', ViewSubmitHandler), (r'/backstage/problem/add', AddProblemHandler), diff --git a/problem.py b/problem.py index e7114a4..3e7723f 100644 --- a/problem.py +++ b/problem.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 15:28:24 19/03/2012 +# MODIFIED: 16:39:22 05/04/2012 import os import time @@ -131,6 +131,31 @@ def get(self): problem.submit = self.select_last_submit_by_problem_id_member_id(problem.id) self.render("problem_list.html", locals()) +class ViewTagHandler(BaseHandler, ProblemDBMixin): + def get(self, tagname): + start = self.get_argument("start", default = 0) + try: + start = int(start) + except ValueError: + start = 0 + tagname = self.xhtml_escape(tagname) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Tag'), '/problem')) + breadcrumb.append((tagname, '/tag/' + tagname)) + title = self._("Problem") + if self.current_user and self.current_user.admin: + count = self.count_problem_by_tagname(tagname) + problems = self.select_problem_by_tagname(tagname, 10, start) + else: + count = self.count_visible_problem_by_tagname(tagname) + problems = self.select_visible_problem_by_tagname(tagname, 10, start) + pages = self.get_page_count(count) + if self.current_user: + for problem in problems: + problem.submit = self.select_last_submit_by_problem_id_member_id(problem.id) + self.render("problem_list.html", locals()) + class ListSubmitHandler(BaseHandler, ProblemDBMixin): def get(self): start = self.get_argument("start", default = 0) @@ -168,4 +193,4 @@ def get(self, sid): code_highlighted = self.highlight_code(submit.code, submit.lang) self.render("submit.html", locals()) -__all__ = ["ViewProblemHandler", "ListProblemHandler", "ListSubmitHandler", "ViewSubmitHandler"] +__all__ = ["ViewProblemHandler", "ListProblemHandler", "ViewTagHandler", "ListSubmitHandler", "ViewSubmitHandler"] From a888f4702e80a854e43efc655166ff6347070660 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 5 Apr 2012 16:45:19 +0800 Subject: [PATCH 35/56] add website run script --- runner.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100755 runner.sh diff --git a/runner.sh b/runner.sh new file mode 100755 index 0000000..2e3d5b6 --- /dev/null +++ b/runner.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# AUTHOR: Zeray Rice +# FILE: runner.sh +# CREATED: 23:39:04 03/04/2012 +# MODIFIED: 16:44:37 05/04/2012 + +if [ "$(id -u)" != "0" ]; then + echo "This script must be run as root" 1>&2 + exit 1 +fi + +python2 main.py 8080 >> main.log 2>&1 & +echo "Web Server is running: " $! +python2 daemons/daemons.py >> daemons.log 2>&1 & +echo "Judge Server is running: " $! +cd daemons && celeryd -l info -I tasks >> celery.log 2>&1 & +echo "Celery Server is running: " $! From ab130b00214686ca85e5e226f06e4f464aaaf518 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 5 Apr 2012 16:46:07 +0800 Subject: [PATCH 36/56] add tag db control --- judge/db/__init__.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/judge/db/__init__.py b/judge/db/__init__.py index d43b24e..af730f3 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 19:49:56 19/03/2012 +# MODIFIED: 16:41:57 05/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -255,6 +255,11 @@ def count_visible_problem(self): def count_problem_by_tagname(self, tagname): count = self.db.get("""SELECT COUNT(*) FROM `problem_tag` WHERE `tagname` = %s""", tagname) return count["COUNT(*)"] + def count_visible_problem_by_tagname(self, tagname): + count = self.db.get("""SELECT COUNT(*) FROM `problem_tag` + LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` + WHERE `tagname` = %s AND `problem`.`invisible` = 0""", tagname) + return count["COUNT(*)"] def count_submit(self): count = self.db.get("""SELECT COUNT(*) FROM `submit`""") return count["COUNT(*)"] @@ -311,6 +316,26 @@ def select_submit_order_by_id(self, count = 10, start = 0): for row in rows: result.append(self._new_submit(row)) return result + def select_problem_by_tagname(self, tagname, count = 10, start = 0): + rows = self.db.query("""SELECT `problem_tag`.*, `problem`.* FROM `problem_tag` + LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` + WHERE `problem_tag`.`tagname` = %s AND `problem`.`invisible` = 0 + ORDER BY `problem`.`id` ASC + LIMIT %s, %s""", tagname, int(start), int(count)) + result = [] + for row in rows: + result.append(self._new_problem(row)) + return result + def select_visible_problem_by_tagname(self, tagname, count = 10, start = 0): + rows = self.db.query("""SELECT `problem_tag`.*, `problem`.* FROM `problem_tag` + LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` + WHERE `problem_tag`.`tagname` = %s + ORDER BY `problem`.`id` ASC + LIMIT %s, %s""", tagname, int(start), int(count)) + result = [] + for row in rows: + result.append(self._new_problem(row)) + return result ''' INSERT ''' def insert_problem(self, problem): problem.id = self.db.execute("""INSERT INTO `problem` (`title`, `shortname`, `content`, \ From 5e8a4680916745b3fd71c324bfee4c4a9f76613a Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 5 Apr 2012 16:46:37 +0800 Subject: [PATCH 37/56] add *.log to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 68c3634..329db05 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ celeryconfig.py privekey.key upload/ test.py +*.log From 3c8d4afef090b57ba2577453349d56ea59670549 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 5 Apr 2012 16:47:30 +0800 Subject: [PATCH 38/56] add run script to Makefile --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 51dc407..c9a0086 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,9 @@ # Makefile console for config Vulpix # Author: Zeray Rice +runner=$(EUID) + less: lessc less/style.less > static/css/style.css +run: + ./runner.sh From e53534292e59444a89f313eb5a0e692858b04af3 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Thu, 5 Apr 2012 17:11:26 +0800 Subject: [PATCH 39/56] finish home count && change pre list page show problem num --- home.py | 12 ++++++------ judge/base/__init__.py | 6 +++--- judge/db/__init__.py | 6 +++++- problem.py | 14 +++++++------- tpl/widget/count.html | 10 +++------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/home.py b/home.py index 99bfefe..43b5ce8 100644 --- a/home.py +++ b/home.py @@ -2,28 +2,28 @@ # AUTHOR: Zeray Rice # FILE: home.py # CREATED: 02:00:16 08/03/2012 -# MODIFIED: 19:51:24 19/03/2012 +# MODIFIED: 16:58:08 05/04/2012 # DESCRIPTION: Home handler from contest import get_contest_status +from judge.db import MemberDBMixin from judge.db import ContestDBMixin from judge.db import ProblemDBMixin from judge.base import BaseHandler -class HomeHandler(BaseHandler, ProblemDBMixin, ContestDBMixin): +class HomeHandler(BaseHandler, MemberDBMixin, ProblemDBMixin, ContestDBMixin): def get(self): title = self._("Home") breadcrumb = [] breadcrumb.append((self._("Home"), "/")) - latest_problem = self.select_latest_visible_problem_order_by_id() + latest_problem = self.select_latest_visible_problem_order_by_id(count = 5) latest_contest = self.select_visible_contest(count = 5) for contest in latest_contest: contest.status = get_contest_status(contest) latest_topic = [] - count_problem = 0 - count_topic = 0 - count_member = 0 + count_problem = self.count_visible_problem() + count_member = self.count_member() self.render("home.html", locals()) __all__ = ["HomeHandler"] diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 314a9b9..2058f5e 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 03:15:40 19/03/2012 +# MODIFIED: 16:59:00 05/04/2012 # DESCRIPTION: Base handler import re @@ -49,9 +49,9 @@ def wrapper(self, *args, **kwargs): class BaseHandler(tornado.web.RequestHandler): _ = lambda self, text: self.locale.translate(text) # i18n func xhtml_escape = lambda self, text: tornado.escape.xhtml_escape(text) if text else text # xhtml escape - def get_page_count(self, count): + def get_page_count(self, count, pre = 10): '''Return page num by input item num''' - return count / 10 + (1 if count % 10 else 0) + return count / pre + (1 if count % pre else 0) def get_current_user(self): '''Check user is logined''' auth = self.get_secure_cookie("auth") diff --git a/judge/db/__init__.py b/judge/db/__init__.py index a8ee747..7480ecb 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 16:41:57 05/04/2012 +# MODIFIED: 16:57:43 05/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -68,6 +68,10 @@ def _new_member(self, row): member = Member() member._init_row(row) return member + ''' COUNT ''' + def count_member(self): + count = self.db.get("""SELECT COUNT(*) FROM `member`""") + return count["COUNT(*)"] ''' SELECT ''' def select_member_by_username_lower(self, username_lower): row = self.db.get("""SELECT * FROM `member` WHERE `username_lower` = %s LIMIT 1""", username_lower) diff --git a/problem.py b/problem.py index 3e7723f..6899177 100644 --- a/problem.py +++ b/problem.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 16:39:22 05/04/2012 +# MODIFIED: 16:59:41 05/04/2012 import os import time @@ -121,11 +121,11 @@ def get(self): title = self._("Problem") if self.current_user and self.current_user.admin: count = self.count_problem() - problems = self.select_problem_order_by_id(10, start) + problems = self.select_problem_order_by_id(20, start) else: count = self.count_visible_problem() - problems = self.select_visible_problem_order_by_id(10, start) - pages = self.get_page_count(count) + problems = self.select_visible_problem_order_by_id(20, start) + pages = self.get_page_count(count, 20) if self.current_user: for problem in problems: problem.submit = self.select_last_submit_by_problem_id_member_id(problem.id) @@ -146,11 +146,11 @@ def get(self, tagname): title = self._("Problem") if self.current_user and self.current_user.admin: count = self.count_problem_by_tagname(tagname) - problems = self.select_problem_by_tagname(tagname, 10, start) + problems = self.select_problem_by_tagname(tagname, 20, start) else: count = self.count_visible_problem_by_tagname(tagname) - problems = self.select_visible_problem_by_tagname(tagname, 10, start) - pages = self.get_page_count(count) + problems = self.select_visible_problem_by_tagname(tagname, 20, start) + pages = self.get_page_count(count, 20) if self.current_user: for problem in problems: problem.submit = self.select_last_submit_by_problem_id_member_id(problem.id) diff --git a/tpl/widget/count.html b/tpl/widget/count.html index d08f7da..c6cf5cf 100644 --- a/tpl/widget/count.html +++ b/tpl/widget/count.html @@ -2,15 +2,11 @@ Total Problems - 1 + {{ count_problem }} - Total Nodes - 1 - - - Total Topics - 2 + Total Members + {{ count_member }} From a5852e94e6ce0550f2401782681ec81213f6d893 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Tue, 17 Apr 2012 16:46:13 +0800 Subject: [PATCH 40/56] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20submit=20=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=20&&=20=E4=BF=AE=E6=AD=A3=E4=B8=AD=E6=96=87=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=8F=90=E4=BA=A4=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- daemons/tasks.py | 4 ++-- judge/base/__init__.py | 20 ++++++++++++++++++-- less/style.less | 3 +-- static/css/style.css | 3 ++- tpl/submit.html | 24 ++++++++++++------------ 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/daemons/tasks.py b/daemons/tasks.py index c2a1bfb..e8a2476 100644 --- a/daemons/tasks.py +++ b/daemons/tasks.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: tasks.py # CREATED: 02:27:12 17/03/2012 -# MODIFIED: 14:26:12 19/03/2012 +# MODIFIED: 16:45:07 17/04/2012 import os import MySQLdb @@ -50,7 +50,7 @@ def _compile(result, query): _clean(COMPILE_DIR) os.chdir(COMPILE_DIR) with open(COMPILE_DIR + query['filename'], "w+") as code: - code.write(query['code']) + code.write(query['code'].encode("utf-8")) cmd = " ".join(["timeout 30", _compile_cmd(query['lang'], query['filename'])]) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) (stdoutput,erroutput) = proc.communicate() diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 2058f5e..840375a 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 16:59:00 05/04/2012 +# MODIFIED: 16:42:19 17/04/2012 # DESCRIPTION: Base handler import re @@ -34,6 +34,12 @@ 3 : CppLexer, } +CODE_LANG = { + 1 : "delphi", + 2 : "c", + 3 : "cpp", +} + def unauthenticated(method): """Decorate methods with this to require that user be NOT logged in""" @functools.wraps(method) @@ -170,6 +176,7 @@ def get_gravatar_url(self, email): return "http://www.gravatar.com/avatar/%s?d=mm" % (gravatar_id) def post_to_judger(self, query, judger, callback = None): query["time"] = time.time() + query["code"] = query["code"].decode("utf-8") query = dict(sorted(query.iteritems(), key=itemgetter(1))) jsondump = json.dumps(query) print jsondump @@ -179,7 +186,16 @@ def post_to_judger(self, query, judger, callback = None): http_client = AsyncHTTPClient() http_client.fetch(judger.path, method = "POST", body = urllib.urlencode({"query" : json.dumps(query)}), callback = callback) def highlight_code(self, code, lang): - return highlight(code, CODE_LEXER[lang](), HtmlFormatter(linenos=True)) + return highlight(code, CODE_LEXER[lang](), HtmlFormatter(linenos = True)) + codestr = highlight(code, CODE_LEXER[lang](), HtmlFormatter(nowrap = True)) + table = '
      '
      +        code = ''
      +        lines = codestr.split("\n")
      +        for index, line in zip(range(len(lines)), lines):
      +            table  +=  "%d\n" % (index + 1)
      +            code   +=  "%s\n" % line
      +        table  +=  "
      %s
      " % (CODE_LANG[lang], code) + return table @property def db(self): return self.application.db diff --git a/less/style.less b/less/style.less index 194c2da..33d5770 100644 --- a/less/style.less +++ b/less/style.less @@ -399,7 +399,6 @@ nav { .submitdetail tr { th, td { .border-radius(0) !important; - border-bottom: 1px solid #DDD; } } @@ -433,7 +432,7 @@ nav { } .highlight .hll { background-color: #ffffcc } -.highlight { background: #ffffff; } +.highlight { background: #ffffff; overflow-x: auto; overflow-y: hidden; } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ diff --git a/static/css/style.css b/static/css/style.css index 9e46b0b..65b7d29 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -4052,7 +4052,6 @@ nav .copyright a { -webkit-border-radius: 0 !important; -moz-border-radius: 0 !important; border-radius: 0 !important; - border-bottom: 1px solid #DDD; } .highlighttable { width: 100%; @@ -4086,6 +4085,8 @@ nav .copyright a { } .highlight { background: #ffffff; + overflow-x: auto; + overflow-y: hidden; } .highlight .c { color: #888888; diff --git a/tpl/submit.html b/tpl/submit.html index f6d4dcb..340a8f0 100644 --- a/tpl/submit.html +++ b/tpl/submit.html @@ -94,7 +94,7 @@
      {{ _('Code') }}
      - {% if submit.member_id == user.id or user.admin %} + {% if submit.member_id == user.id or user.admin or true%} {{ code_highlighted }} {% else %}
      {{ _("You dont have permissions to view this code.") }}
      @@ -106,17 +106,17 @@ {% endif %} {% endblock %} From 53c597ef9c19a82e5c03e9ddd13e6b629f189c92 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Tue, 17 Apr 2012 17:28:33 +0800 Subject: [PATCH 41/56] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E5=86=85=E5=AE=B9,=20=E5=A2=9E=E5=8A=A0=E4=B8=AA=E4=BA=BA?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=9C=80=E8=BF=91=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + home.py | 3 ++- judge/db/__init__.py | 12 +++++++++++- member.py | 6 ++++-- tpl/home.html | 36 ++++++++++++++++++++++++++++++++++-- tpl/member.html | 31 +++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 329db05..0573899 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ privekey.key upload/ test.py *.log +dbconvert.py diff --git a/home.py b/home.py index 43b5ce8..ca9b0b4 100644 --- a/home.py +++ b/home.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: home.py # CREATED: 02:00:16 08/03/2012 -# MODIFIED: 16:58:08 05/04/2012 +# MODIFIED: 17:19:36 17/04/2012 # DESCRIPTION: Home handler from contest import get_contest_status @@ -19,6 +19,7 @@ def get(self): breadcrumb.append((self._("Home"), "/")) latest_problem = self.select_latest_visible_problem_order_by_id(count = 5) latest_contest = self.select_visible_contest(count = 5) + latest_submit = self.select_submit_order_by_id() for contest in latest_contest: contest.status = get_contest_status(contest) latest_topic = [] diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 7480ecb..c52cd7f 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 16:57:43 05/04/2012 +# MODIFIED: 17:19:01 17/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -320,6 +320,16 @@ def select_submit_order_by_id(self, count = 10, start = 0): for row in rows: result.append(self._new_submit(row)) return result + def select_submit_by_member_id(self, member_id, count = 10): + rows = self.db.query("""SELECT `submit`.*, `problem`.`title` FROM `submit` + LEFT JOIN `member` ON `submit`.`member_id` = `member`.`id` + LEFT JOIN `problem` ON `submit`.`problem_id` = `problem`.`id` + WHERE `submit`.`member_id` = %s + ORDER BY `submit`.`id` DESC LIMIT %s""", int(member_id), int(count)) + result = [] + for row in rows: + result.append(self._new_submit(row)) + return result def select_problem_by_tagname(self, tagname, count = 10, start = 0): rows = self.db.query("""SELECT `problem_tag`.*, `problem`.* FROM `problem_tag` LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` diff --git a/member.py b/member.py index 24b1d4c..4b0e6b6 100644 --- a/member.py +++ b/member.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 04:22:54 19/03/2012 +# MODIFIED: 17:18:20 17/04/2012 # DESCRIPTION: member handlers import re @@ -14,6 +14,7 @@ from judge.db import Member from judge.db import MemberDBMixin +from judge.db import ProblemDBMixin from judge.base import BaseHandler from judge.base import unauthenticated @@ -166,13 +167,14 @@ def post(self): self.set_secure_cookie('msg', self._('Password Updated.')) self.redirect('/settings') -class MemberHandler(BaseHandler, MemberDBMixin): +class MemberHandler(BaseHandler, MemberDBMixin, ProblemDBMixin): def get(self, username): title = username username = username.lower() member = self.select_member_by_username_lower(username) if not member: raise HTTPError(404) + submits = self.select_submit_by_member_id(member.id, 5) breadcrumb = [] breadcrumb.append((self._('Home'), '/')) breadcrumb.append((member.username, '/member/%s' % member.username)) diff --git a/tpl/home.html b/tpl/home.html index 0806008..a2537f0 100644 --- a/tpl/home.html +++ b/tpl/home.html @@ -7,13 +7,40 @@
      -
      {{ _('Latest Problem') }}
      +
      {{ _('Recent Problem') }}
      {{ show_problem_list(latest_problem) }}
      -
      {{ _('Latest Contest') }}
      +
      {{ _('Recent Submit') }}
      +
      + + + + + + + + + + + + {% for submit in latest_submit %} + + + + + + + + {% endfor %} + +
      #{{ _('Status') }}{{ _('Problem') }}{{ _('User') }}{{ _('Language') }}
      {{ submit.id }}{{ submit | get_submit_status }}{{ submit.title }}{{ submit.username }}{{ submit.lang | lang2humantext }}
      +
      +
      +
      +
      {{ _('Recent Contest') }}
      {{ show_contest_list(latest_contest) }}
      @@ -33,6 +60,11 @@ {% include 'widget/notice.html' %}
      +
      +
      {{ _('New Node') }}
      +
      +
      +
      {{ _('Site Count') }}
      diff --git a/tpl/member.html b/tpl/member.html index 6c3221e..1567f97 100644 --- a/tpl/member.html +++ b/tpl/member.html @@ -17,4 +17,35 @@ {{ member.bio | autolink | replace("\n", "
      ")}}
      +
      +
      {{ _("Recent Submit") }}
      +
      + + + + + + + + + + + + + + {% for submit in submits %} + + + + + + + + + + {% endfor %} + +
      #{{ _('Status') }}{{ _('Problem') }}{{ _('Language') }}{{ _('Time') }}{{ _('Memory') }}{{ _('Testpoint') }}
      {{ submit.id }}{{ submit | get_submit_status }}{{ submit.title }}{{ submit.lang | lang2humantext }}{{ submit.costtime }} ms{{ submit.costmemory }} KB{% if submit.testpoint %}{{ submit.testpoint }}{% endif %}
      +
      +
      {% endblock %} From aa39ee1e82723f9710b1b26377c134ffd1d63c72 Mon Sep 17 00:00:00 2001 From: Kingfree Date: Tue, 17 Apr 2012 18:47:19 +0800 Subject: [PATCH 42/56] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- daemons/daemons.py | 4 ---- tpl/problem.html | 9 +++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/daemons/daemons.py b/daemons/daemons.py index aefff55..bea993d 100644 --- a/daemons/daemons.py +++ b/daemons/daemons.py @@ -42,13 +42,9 @@ def post(self): raise HTTPError(404) query = dict(sorted(query.iteritems(), key=itemgetter(1))) sign = hashlib.sha1(json.dumps(query) + SALT).hexdigest() - print json.dumps(query) - print SALT if not sign == query_sign: logging.error("Signature is invalid") raise HTTPError(404) - print sign - print query_sign judge.delay(query) application = tornado.web.Application([ diff --git a/tpl/problem.html b/tpl/problem.html index 067ade8..6355b29 100644 --- a/tpl/problem.html +++ b/tpl/problem.html @@ -7,6 +7,15 @@ {{ _('This Problem is Invisible!') }}
      {% endif %} +{% if error %} +
      +
        +{% for err in error %} +
      • {{ err }}
      • +{% endfor %} +
      +
      +{% endif %}
      {% if user.admin %} From 6c43e0114f414d2c2c6568b6e846e5039a1deb0e Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Tue, 17 Apr 2012 19:29:41 +0800 Subject: [PATCH 43/56] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers.py | 3 ++- home.py | 4 ++-- judge/db/__init__.py | 14 +++++++++++++- member.py | 25 +++++++++++++++++++++++-- tpl/base/sidebar.html | 6 ++++++ tpl/member_list.html | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 tpl/member_list.html diff --git a/handlers.py b/handlers.py index 9d23b7b..8d2b610 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 16:36:58 05/04/2012 +# MODIFIED: 19:08:55 17/04/2012 # DESCRIPTION: URL Route from api import * @@ -24,6 +24,7 @@ (r'/signout', SignoutHandler), (r'/settings', SettingsHandler), (r'/settings/changepass', ChangePasswordHandler), + (r'/member', ListMemberHandler), (r'/member/(.*)', MemberHandler), (r'/lang/(.*)', SetLanguageHandler), (r'/problem', ListProblemHandler), diff --git a/home.py b/home.py index ca9b0b4..5612cb0 100644 --- a/home.py +++ b/home.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: home.py # CREATED: 02:00:16 08/03/2012 -# MODIFIED: 17:19:36 17/04/2012 +# MODIFIED: 19:27:54 17/04/2012 # DESCRIPTION: Home handler from contest import get_contest_status @@ -19,7 +19,7 @@ def get(self): breadcrumb.append((self._("Home"), "/")) latest_problem = self.select_latest_visible_problem_order_by_id(count = 5) latest_contest = self.select_visible_contest(count = 5) - latest_submit = self.select_submit_order_by_id() + latest_submit = self.select_submit_order_by_id(count = 5) for contest in latest_contest: contest.status = get_contest_status(contest) latest_topic = [] diff --git a/judge/db/__init__.py b/judge/db/__init__.py index c52cd7f..8703c0c 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 17:19:01 17/04/2012 +# MODIFIED: 19:21:42 17/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -72,6 +72,12 @@ def _new_member(self, row): def count_member(self): count = self.db.get("""SELECT COUNT(*) FROM `member`""") return count["COUNT(*)"] + def count_accepted_by_member_id(self, member_id): + count = self.db.get("""SELECT COUNT(*) FROM `submit` WHERE `status` = 1 AND `member_id` = %s""", member_id) + return count["COUNT(*)"] + def count_submit_by_member_id(self, member_id): + count = self.db.get("""SELECT COUNT(*) FROM `submit` WHERE `member_id` = %s""", member_id) + return count["COUNT(*)"] ''' SELECT ''' def select_member_by_username_lower(self, username_lower): row = self.db.get("""SELECT * FROM `member` WHERE `username_lower` = %s LIMIT 1""", username_lower) @@ -88,6 +94,12 @@ def select_member_by_usr_pwd(self, usr, pwd): if row: return self._new_member(row) return None + def select_member_order_by_id(self, count = 10, start = 0): + rows = self.db.query("""SELECT * FROM `member` ORDER BY `id` LIMIT %s, %s""", int(start), int(count)) + result = [] + for row in rows: + result.append(self._new_member(row)) + return result ''' INSERT ''' def insert_member(self, member): member.id = self.db.execute("""INSERT INTO `member` (`username`, `username_lower`, `password`, `email`, diff --git a/member.py b/member.py index 4b0e6b6..bdcc44d 100644 --- a/member.py +++ b/member.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 17:18:20 17/04/2012 +# MODIFIED: 19:24:32 17/04/2012 # DESCRIPTION: member handlers import re @@ -180,4 +180,25 @@ def get(self, username): breadcrumb.append((member.username, '/member/%s' % member.username)) self.render("member.html", locals()) -__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler", "ChangePasswordHandler", "MemberHandler"] +class ListMemberHandler(BaseHandler, MemberDBMixin): + @authenticated + def get(self): + start = self.get_argument("start", default = 0) + try: + start = int(start) + except ValueError: + start = 0 + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Member List'), '/member')) + title = self._("Member List") + members = self.select_member_order_by_id(start = start) + count = self.count_member() + pages = self.get_page_count(count, 20) + for member in members: + member.accepted = self.count_accepted_by_member_id(member.id) + member.submit = self.count_submit_by_member_id(member.id) + member.rating = member.accepted / float(member.submit) * 100 + self.render("member_list.html", locals()) + +__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler", "ChangePasswordHandler", "MemberHandler", "ListMemberHandler"] diff --git a/tpl/base/sidebar.html b/tpl/base/sidebar.html index 8751fd4..82d4c1f 100644 --- a/tpl/base/sidebar.html +++ b/tpl/base/sidebar.html @@ -71,6 +71,12 @@ {{ _('Notes') }} --> +
    • + + + {{ _('Member') }} + +
    • diff --git a/tpl/member_list.html b/tpl/member_list.html new file mode 100644 index 0000000..b8b58c7 --- /dev/null +++ b/tpl/member_list.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} + +{% block body %} +
      +
      {{ _('Member List') }}
      +
      + + + + + + + + + + + + + {% for member in members %} + + + + + + + + + {% endfor %} + +
      #{{ _('Username') }}{{ _('Language') }}{{ _('Accepted') }}{{ _('Submit') }}{{ _('Rating') }}
      {{ member.id }}{{ member.username }}{{ member.lang | lang2humantext }}{{ member.accepted }}{{ member.submit }}{{ member.rating }} %
      +
      +
      +{% include 'count.html' %} +{% endblock %} From edadc838142c566093c16b1e0f232ccc4065074b Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Tue, 17 Apr 2012 23:08:36 +0800 Subject: [PATCH 44/56] finish node --- backstage.py | 45 +++++++++++++++++++++++++++++++++++-- forum.py | 6 +++++ handlers.py | 3 ++- judge/db/__init__.py | 25 +++++++++++++++++++-- tpl/backstage/add_node.html | 18 +++++++++++++++ tpl/submit.html | 6 ++--- 6 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 forum.py create mode 100644 tpl/backstage/add_node.html diff --git a/backstage.py b/backstage.py index f676e1c..1ed77c6 100644 --- a/backstage.py +++ b/backstage.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: backstage.py # CREATED: 02:43:49 15/03/2012 -# MODIFIED: 02:13:40 18/03/2012 +# MODIFIED: 23:05:02 17/04/2012 import re import datetime @@ -10,9 +10,11 @@ from tornado.web import HTTPError +from judge.db import Node from judge.db import Judger from judge.db import Contest from judge.db import Problem +from judge.db import ForumDBMixin from judge.db import JudgerDBMixin from judge.db import ContestDBMixin from judge.db import ProblemDBMixin @@ -146,6 +148,45 @@ def post(self): self.insert_contest_problem(contest.id, pid) self.redirect("/contest/%d" % int(contest.id)) +class AddNodeHandler(BaseHandler, ForumDBMixin): + @backstage + def get(self): + title = self._("Add Node") + nid = self.get_argument("nid", default = 0) + node = None + try: + nid = int(nid) + except ValueError: + raise HTTPError(404) + if nid: + node = self.select_node_by_id(nid) + if not node: + raise HTTPError(404) + title = self._("Edit Node") + self.render("backstage/add_node.html", locals()) + @backstage + def post(self): + name = self.get_argument("name", default = "") + link = self.get_argument("link", default = "") + nid = self.get_argument("nid", default = 0) + error = [] + node = Node() + error.extend(self.check_text_value(name, self._("Name"), required = True, max = 100)) + error.extend(self.check_text_value(link, self._("Link"), required = True, max = 100)) + node.id = nid + node.name = name + node.link = link + node.description = "" + if error: + title = self._("Edit Node") + self.render("backstage/add_node.html", locals()) + return + if node.id: + self.update_node(node) + else: + self.insert_node(node) + self.redirect("/go/%s" % node.link) + class ManageJudgerHandler(BaseHandler, JudgerDBMixin): @backstage def get(self): @@ -200,4 +241,4 @@ def post(self): self.insert_judger(judger) self.redirect("/backstage/judger") -__all__ = ["backstage", "AddProblemHandler", "AddContestHandler", "ManageJudgerHandler", "AddJudgerHandler"] +__all__ = ["backstage", "AddProblemHandler", "AddContestHandler", "ManageJudgerHandler", "AddJudgerHandler", "AddNodeHandler"] diff --git a/forum.py b/forum.py new file mode 100644 index 0000000..c240136 --- /dev/null +++ b/forum.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: forum.py +# CREATED: 22:39:44 17/04/2012 +# MODIFIED: 22:39:46 17/04/2012 + diff --git a/handlers.py b/handlers.py index 8d2b610..9dc8b7f 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 19:08:55 17/04/2012 +# MODIFIED: 22:42:07 17/04/2012 # DESCRIPTION: URL Route from api import * @@ -34,6 +34,7 @@ (r'/submit/(.*)', ViewSubmitHandler), (r'/backstage/problem/add', AddProblemHandler), (r'/backstage/contest/add', AddContestHandler), + (r'/backstage/node/add', AddNodeHandler), (r'/backstage/judger', ManageJudgerHandler), (r'/backstage/judger/add', AddJudgerHandler), (r'/contest', ListContestHandlder), diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 8703c0c..f6f933a 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 19:21:42 17/04/2012 +# MODIFIED: 23:04:42 17/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -175,7 +175,28 @@ class Reply(BaseDBObject): create = None class ForumDBMixin(BaseDBMixin): - pass + def _new_node(row): + node = Node() + node._init_row(row) + return node + '''COUNT''' + '''SELECT''' + def select_node_by_id(self, node_id): + row = self.db.get("""SELECT * FROM `node` WHERE `id` = %s""", int(node_id)) + if row: + return self._new_node(row) + return None + '''INSERT''' + def insert_node(self, node): + node.id = self.db.execute("""INSERT INTO `node` (`name`, `link`, `description`) + VALUES (%s, %s, %s)""", node.name, node.link, node.description) + '''UPDATE''' + def update_node(self, node): + self.db.execute("""UPDATE `node` SET `name` = %s, + `link` = %s, + `description` = %s, + WHERE `node`.`id` = %s""", node.name, node.link, node.description, node.id) + '''DELETE''' ''' '' =================================== diff --git a/tpl/backstage/add_node.html b/tpl/backstage/add_node.html new file mode 100644 index 0000000..d3ee1ad --- /dev/null +++ b/tpl/backstage/add_node.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} +{% from "macros.html" import input %} +{% from "macros.html" import textarea %} +{% from "macros.html" import form_actions %} + +{% block body %} + +
      +
      {{ title }}
      + {{ page.xsrf_form_html() }} + +
      + {{ input("name", _("Name"), value=node.name) }} + {{ input("link", _("Link"), value=node.link) }} + {{ form_actions(_("Submit")) }} +
      + +{% endblock %} diff --git a/tpl/submit.html b/tpl/submit.html index 340a8f0..097a4a3 100644 --- a/tpl/submit.html +++ b/tpl/submit.html @@ -30,15 +30,15 @@ {{ submit.score }} - {{ _('Cost Time') }} + {{ _('Time') }} {{ submit.costtime }} ms - {{ _('Cost Memory') }} + {{ _('Memory') }} {{ submit.costmemory }} KB - {{ _('Submit Time') }} + {{ _('Time') }} {{ submit.create }} {% if user.admin %} From 466ac21c35912384a33aefa6a3b12cf1a6ebd92e Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Wed, 18 Apr 2012 00:30:49 +0800 Subject: [PATCH 45/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/db/__init__.py | 218 +++++++------------------------------------ judge/db/models.py | 189 +++++++++++++++++++++++++++++++++++++ main.py | 17 +++- 3 files changed, 235 insertions(+), 189 deletions(-) create mode 100644 judge/db/models.py diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 8703c0c..9c50a76 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,29 +2,16 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 19:21:42 17/04/2012 +# MODIFIED: 00:30:09 18/04/2012 # DESCRIPTION: Database Table Object import uuid import binascii +from sqlalchemy import Column +from sqlalchemy import String +from sqlalchemy import Integer -class BaseDBObject(object): - ''' Base Table Object ''' - def __repr__(self): - ''' for debug ''' - result = ", \n".join(["'%s': '%s'" % (attr, getattr(self, attr)) for attr in dir(self) if attr[0] != '_' and not callable(getattr(self, attr)) ]) - return "<{%s}>" % result - def _init_row(self, row): - keys = row.keys() - for key in keys: - setattr(self, key, row[key]) - -class BaseDBMixin(object): - ''' Base Database Mixin ''' - def _new_object_by_row(self, Obj, row): - obj = Obj() - obj._init_row(row) - return obj +from judge.db.models import * ''' '' =================================== @@ -32,37 +19,7 @@ def _new_object_by_row(self, Obj, row): '' =================================== ''' -class Member(BaseDBObject): - '''User data table''' - __tablename__ = "member" - id = 0 - username = "" - username_lower = "" - passowrd = "" - email = "" - website = "" - tagline = "" - bio = "" - gravatar_link = "" - create = None - admin = 0 - lang = 1 - -class Auth(BaseDBObject): - '''User auth table''' - __tablename__ = "auth" - member_id = 0 - secret = "" - create = None - -class ResetMail(BaseDBObject): - '''User reset mail table''' - __tablename__ = "reset_mail" - member_id = 0 - secret = "" - create = None - -class MemberDBMixin(BaseDBMixin): +class MemberDBMixin(object): ''' New Data Model ''' def _new_member(self, row): member = Member() @@ -146,36 +103,29 @@ def create_auth(self, member_id): '' =================================== ''' -class Node(BaseDBObject): - '''Forum node table''' - __tablename__ = "node" - id = 0 - name = "" - description = "" - link = "" - -class Topic(BaseDBObject): - '''Forum topic table''' - __tablename__ = "topic" - id = 0 - title = "" - content = "" - node_id = 0 - member_id = 0 - create = None - last_reply = None - -class Reply(BaseDBObject): - '''Forum topic reply table''' - __tablename__ = "reply" - id = 0 - content = "" - member_id = 0 - topic_id = 0 - create = None - -class ForumDBMixin(BaseDBMixin): - pass +class ForumDBMixin(object): + def _new_node(row): + node = Node() + node._init_row(row) + return node + '''COUNT''' + '''SELECT''' + def select_node_by_id(self, node_id): + row = self.db.get("""SELECT * FROM `node` WHERE `id` = %s""", int(node_id)) + if row: + return self._new_node(row) + return None + '''INSERT''' + def insert_node(self, node): + node.id = self.db.execute("""INSERT INTO `node` (`name`, `link`, `description`) + VALUES (%s, %s, %s)""", node.name, node.link, node.description) + '''UPDATE''' + def update_node(self, node): + self.db.execute("""UPDATE `node` SET `name` = %s, + `link` = %s, + `description` = %s, + WHERE `node`.`id` = %s""", node.name, node.link, node.description, node.id) + '''DELETE''' ''' '' =================================== @@ -183,22 +133,7 @@ class ForumDBMixin(BaseDBMixin): '' =================================== ''' -class Note(BaseDBObject): - '''Note data table''' - __tablename__ = "note" - id = 0 - title = "" - content = "" - member_id = 0 - create = None - -class RelatedProblem(BaseDBObject): - '''Note related problem table''' - __tablename__ = "related_problem" - problem_id = 0 - note_id = 0 - -class NoteDBMixin(BaseDBMixin): +class NoteDBMixin(object): pass ''' @@ -207,47 +142,7 @@ class NoteDBMixin(BaseDBMixin): '' =================================== ''' -class Problem(BaseDBObject): - '''Problem table''' - __tablename__ = "problem" - id = 0 - title = "" - shortname = "" - content = "" - timelimit = 0 - memlimit = 0 - testpoint = 0 - invisible = 0 - create = None - -class ProblemTag(BaseDBObject): - '''Problem tag table''' - __tablename__ = "problem_tag" - problem_id = 0 - tagname = "" - -class Submit(BaseDBObject): - '''Submit table''' - __tablename__ = "submit" - id = 0 - problem_id = 0 - member_id = 0 - code = "" - status = 0 - testpoint = 0 - testpoint_time = "" - testpoint_memory = "" - score = 0 - costtime = 0 - costmemory = 0 - timestamp = "" - lang = 0 - msg = "" - user_agent = 0 - ip = 0 - create = 0 - -class ProblemDBMixin(BaseDBMixin): +class ProblemDBMixin(object): ''' New Data Model ''' def _new_problem(self, row): problem = Problem() @@ -401,42 +296,7 @@ def delete_problem_tag_by_problem_id(self, problem_id): '' =================================== ''' -class Contest(BaseDBObject): - '''Contest data table''' - __tablename__ = "contest" - id = 0 - title = "" - description = "" - start_time = None - end_time = None - invisible = 0 - create = None - -class ContestProblem(BaseDBObject): - '''Contest problem table''' - __tablename__ = "contest_problem" - contest_id = 0 - problem_id = 0 - -class ContestSubmit(BaseDBObject): - '''Contest submit table''' - __tablename__ = "contest_submit" - contest_id = 0 - problem_id = 0 - member_id = 0 - status = 0 - testpoint = "" - score = 0 - costtime = 0 - costmemory = 0 - timestamp = "" - lang = 0 - msg = "" - user_agent = 0 - ip = 0 - create = 0 - -class ContestDBMixin(BaseDBMixin): +class ContestDBMixin(object): ''' New Data Model ''' def _new_contest(self, row): contest = Contest() @@ -513,19 +373,7 @@ def delete_contest_problem_by_contest_id(self, contest_id): self.db.execute("""DELETE FROM `contest_problem` WHERE `contest_id` = %s""", contest_id) ''' OTHER ''' -class Judger(BaseDBObject): - '''Contest problem table''' - __tablename__ = "judge" - id = 0 - name = "" - description = "" - path = "" # support HTTP protocol - priority = 0 - queue_num = 0 - pubkey = "" - create = None - -class JudgerDBMixin(BaseDBMixin): +class JudgerDBMixin(object): ''' New Data Model ''' def _new_judger(self, row): judger = Judger() diff --git a/judge/db/models.py b/judge/db/models.py new file mode 100644 index 0000000..08d61be --- /dev/null +++ b/judge/db/models.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +# AUTHOR: Zeray Rice +# FILE: judge/db/models.py +# CREATED: 23:40:55 17/04/2012 +# MODIFIED: 00:29:45 18/04/2012 + +from sqlalchemy import create_engine +from sqlalchemy import Column, Integer, String, DateTime, Boolean +from sqlalchemy import ForeignKey +from sqlalchemy.orm import relation +from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import scoped_session +from sqlalchemy.ext.declarative import declarative_base + +Base = declarative_base() + +def init_db(engine): + Base.metadata.create_all(bind=engine) + +class Member(Base): + __tablename__ = "member" + id = Column(Integer, primary_key = True) + username = Column(String) + username_lower = Column(String) + password = Column(String) + email = Column(String) + website = Column(String) + tagline = Column(String) + bio = Column(String) + gravatar_link = Column(String) + create = Column(DateTime) + admin = Column(Integer) + lang = Column(Integer) + +class Auth(Base): + __tablename__ = "auth" + id = Column(Integer, primary_key = True) + member_id = Column(Integer, ForeignKey("member.id")) + member = relation("member") + secret = Column(String) + create = Column(DateTime) + +class ResetMail(Base): + __tablename__ = "reset_mail" + id = Column(Integer, primary_key = True) + member_id = Column(Integer, ForeignKey("member.id")) + member = relation("member") + secret = Column(String) + create = Column(DateTime) + +class Node(Base): + __tablename__ = "node" + id = Column(Integer, primary_key = True) + name = Column(String) + link = Column(String) + description = Column(String) + +class Topic(Base): + __tablename__ = "topic" + id = Column(Integer, primary_key = True) + title = Column(String) + content = Column(String) + node_id = Column(Integer, ForeignKey("node.id")) + node = relation("node") + member_id = Column(Integer, ForeignKey("member.id")) + member = relation("member") + create = Column(DateTime) + last_reply = Column(DateTime) + +class Reply(Base): + __tablename__ = "reply" + id = Column(Integer, primary_key = True) + content = Column(String) + member_id = Column(Integer, ForeignKey("member.id")) + member = relation("member") + topic_id = Column(Integer, ForeignKey("topic.id")) + topic = relation("topic") + create = Column(DateTime) + +class Note(Base): + __tablename__ = "note" + id = Column(Integer, primary_key = True) + title = Column(String) + content = Column(String) + member_id = Column(Integer, ForeignKey("member.id")) + member = relation("member") + create = Column(DateTime) + +class RelatedProblem(Base): + __tablename__ = "related_problem" + id = Column(Integer, primary_key = True) + problem_id = Column(Integer, ForeignKey("problem.id")) + problem = relation("problem") + note_id = Column(Integer, ForeignKey("note.id")) + note = relation("note") + +class Problem(Base): + __tablename__ = "problem" + id = Column(Integer, primary_key = True) + title = Column(String) + shortname = Column(String) + content = Column(String) + timelimit = Column(Integer) + memlimit = Column(Integer) + testpoint = Column(Integer) + invisible = Column(Boolean) + create = Column(DateTime) + +class ProblemTag(Base): + __tablename__ = "problem_tag" + id = Column(Integer, primary_key = True) + problem_id = Column(Integer, ForeignKey("problem.id")) + problem = relation("problem") + tagname = Column(String) + +class Submit(Base): + __tablename__ = "submit" + id = Column(Integer, primary_key = True) + problem_id = Column(Integer, ForeignKey("problem.id")) + problem = relation("problem") + member_id = Column(Integer, ForeignKey("member.id")) + member = relation("member") + code = Column(String) + status = Column(Integer) + testpoint = Column(String) + testpoint_time = Column(String) + testpoint_memory = Column(String) + score = Column(Integer) + costtime = Column(Integer) + costmemory = Column(Integer) + timestamp = Column(String) + lang = Column(Integer) + msg = Column(String) + user_agent = Column(String) + ip = Column(String) + create = Column(DateTime) + +class Contest(Base): + __tablename__ = "contest" + id = Column(Integer, primary_key = True) + title = Column(String) + description = Column(String) + start_time = Column(DateTime) + end_time = Column(DateTime) + invisible = Column(Boolean) + create = Column(DateTime) + +class ContestProblem(Base): + __tablename__ = "contest_problem" + id = Column(Integer, primary_key = True) + contest_id = Column(Integer, ForeignKey("contest.id")) + contest = relation("contest") + problem_id = Column(Integer, ForeignKey("problem.id")) + problem = relation("problem") + +class ContestSubmit(Base): + __tablename__ = "contest_submit" + id = Column(Integer, primary_key = True) + contest_id = Column(Integer, ForeignKey("contest.id")) + contest = relation("contest") + problem_id = Column(Integer, ForeignKey("problem.id")) + problem = relation("problem") + member_id = Column(Integer, ForeignKey("member.id")) + member = relation("member") + code = Column(String) + status = Column(Integer) + testpoint = Column(String) + testpoint_time = Column(String) + testpoint_memory = Column(String) + score = Column(Integer) + costtime = Column(Integer) + costmemory = Column(Integer) + timestamp = Column(String) + lang = Column(Integer) + msg = Column(String) + user_agent = Column(String) + ip = Column(String) + create = Column(DateTime) + +class Judger(Base): + __tablename__ = "judger" + id = Column(Integer, primary_key = True) + name = Column(String) + description = Column(String) + path = Column(String) + priority = Column(Integer) + queue_num = Column(Integer) + pubkey = Column(String) + create = Column(DateTime) diff --git a/main.py b/main.py index a745e75..92743cd 100644 --- a/main.py +++ b/main.py @@ -2,13 +2,15 @@ # AUTHOR: Zeray Rice # FILE: main.py # CREATED: 01:37:19 08/03/2012 -# MODIFIED: 15:46:12 15/03/2012 +# MODIFIED: 23:41:07 17/04/2012 # DESCRIPTION: Main Server File, run as `python2 main.py [port_num]` import re import sys import httplib from jinja2 import Environment, FileSystemLoader +from sqlalchemy import create_engine +from sqlalchemy.orm import scoped_session, sessionmaker httplib.responses[418] = "I'm a teapot" # hack for HTTP 418 :D @@ -20,14 +22,18 @@ from tornado.options import define from tornado.options import options +from judge.db import models from judge.filters import filters +from config import mysql_path from config import site_config from config import mysql_config from handlers import handlers tornado.options.parse_command_line() +define("debug", default = True) + # Set MySQL define("mysql_host", default = mysql_config['mysql_host']) define("mysql_database", default = mysql_config['mysql_database']) @@ -42,9 +48,12 @@ def __init__(self): jinja_env = Environment(loader = FileSystemLoader(self.settings['template_path'])) jinja_env.filters.update(filters) self.jinja2 = jinja_env - self.db = tornado.database.Connection( - host=options.mysql_host, database=options.mysql_database, - user=options.mysql_user, password=options.mysql_password) +# self.db = tornado.database.Connection( +# host=options.mysql_host, database=options.mysql_database, +# user=options.mysql_user, password=options.mysql_password) + engine = create_engine(mysql_path, convert_unicode=True, echo=options.debug) + models.init_db(engine) + self.db = scoped_session(sessionmaker(bind=engine)) if __name__ == '__main__': http_server = tornado.httpserver.HTTPServer(Application()) From 654464d533fed2701314c7301e0549462ebfc352 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Wed, 18 Apr 2012 02:16:58 +0800 Subject: [PATCH 46/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=20ORM=20=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/base/__init__.py | 37 +++-- judge/db/__init__.py | 354 ++++++++++------------------------------- judge/db/models.py | 38 ++--- 3 files changed, 121 insertions(+), 308 deletions(-) diff --git a/judge/base/__init__.py b/judge/base/__init__.py index 840375a..d1d05eb 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 16:42:19 17/04/2012 +# MODIFIED: 02:16:21 18/04/2012 # DESCRIPTION: Base handler import re @@ -25,6 +25,7 @@ import tornado.escape from tornado.httpclient import AsyncHTTPClient +from judge.db import Auth from judge.db import Member from judge.utils import _len @@ -61,28 +62,26 @@ def get_page_count(self, count, pre = 10): def get_current_user(self): '''Check user is logined''' auth = self.get_secure_cookie("auth") - uid = self.get_secure_cookie("uid") + member_id = self.get_secure_cookie("uid") member = None - if auth and uid: - auth = self.db.get("""SELECT * FROM `auth` WHERE `secret` = %s AND `member_id` = %s LIMIT 1""", auth, uid) + if auth and member_id: + auth = self.db.query(Auth).filter_by(secret = auth).filter_by(member_id = member_id).one() if auth: - member = Member() - query = self.db.get("""SELECT * FROM `member` WHERE `id` = %s LIMIT 1""", auth["member_id"]) - if query: - member._init_row(query) - delta = auth['create'] - datetime.datetime.now() + member = self.db.query(Member).get(auth.member_id) + if member: + delta = auth.create - datetime.datetime.now() if delta.days > 20: """ Refresh Token """ - sql = """DELETE FROM `auth` WHERE `secret` = '%s' LIMIT 1""" \ - % auth - self.db.execute(sql) - random = binascii.b2a_hex(uuid.uuid4().bytes) - sql = """INSERT INTO `auth` (`uid`, `secret`, `create`) \ - VALUES ('%d', '%s', UTC_TIMESTAMP())""" \ - % (uid, random) - self.db.execute(sql) - self.set_cookie('auth', random) - self.set_cookie('uid', str(uid)) + auth.delete() + self.db.commit() + auth = Auth() + auth.member_id = member_id + auth.secret = binascii.b2a_hex(uuid.uuid4().bytes) + auth.create = datetime.datetime.now() + self.db.add(auth) + self.db.commit() + self.set_cookie('auth', auth.secret) + self.set_cookie('uid', auth.member_id) else: self.clear_cookie("auth") self.clear_cookie("uid") diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 9c50a76..d0f6692 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,11 +2,13 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 00:30:09 18/04/2012 +# MODIFIED: 02:14:39 18/04/2012 # DESCRIPTION: Database Table Object import uuid import binascii +import datetime +from sqlalchemy import desc from sqlalchemy import Column from sqlalchemy import String from sqlalchemy import Integer @@ -20,77 +22,47 @@ ''' class MemberDBMixin(object): - ''' New Data Model ''' - def _new_member(self, row): - member = Member() - member._init_row(row) - return member ''' COUNT ''' def count_member(self): - count = self.db.get("""SELECT COUNT(*) FROM `member`""") - return count["COUNT(*)"] + return self.db.query(Member).count() def count_accepted_by_member_id(self, member_id): - count = self.db.get("""SELECT COUNT(*) FROM `submit` WHERE `status` = 1 AND `member_id` = %s""", member_id) - return count["COUNT(*)"] + return self.db.query(Submit).filter_by(member_id = 1).filter_by(status = 1).count() def count_submit_by_member_id(self, member_id): - count = self.db.get("""SELECT COUNT(*) FROM `submit` WHERE `member_id` = %s""", member_id) - return count["COUNT(*)"] + return self.db.query(Submit).filter_by(member_id = 1).count() ''' SELECT ''' def select_member_by_username_lower(self, username_lower): - row = self.db.get("""SELECT * FROM `member` WHERE `username_lower` = %s LIMIT 1""", username_lower) - if row: - return self._new_member(row) - return None + return self.db.query(Member).filter_by(username_lower = username_lower).one() def select_member_by_email(self, email): - row = self.db.get("""SELECT * FROM `member` WHERE `email` = %s LIMIT 1""", email) - if row: - return self._new_member(row) - return None + return self.db.query(Member).filter_by(email = email).one() def select_member_by_usr_pwd(self, usr, pwd): - row = self.db.get("""SELECT * FROM `member` WHERE `username` = %s AND `password` = %s LIMIT 1""", usr, pwd) - if row: - return self._new_member(row) - return None + return self.db.query(Member).filter_by(username_lower = usr.lower()).filter_by(password = pwd).one() def select_member_order_by_id(self, count = 10, start = 0): - rows = self.db.query("""SELECT * FROM `member` ORDER BY `id` LIMIT %s, %s""", int(start), int(count)) - result = [] - for row in rows: - result.append(self._new_member(row)) - return result + return self.db.query(Member).order_by(Member.id).offset(start).limit(count).all() ''' INSERT ''' def insert_member(self, member): - member.id = self.db.execute("""INSERT INTO `member` (`username`, `username_lower`, `password`, `email`, - `gravatar_link`, `create`, `website`, `tagline`, `bio`, - `admin`, `lang`) - VALUES (%s, %s, %s, %s, %s, UTC_TIMESTAMP(), %s, %s, %s, %s, %s)""", \ - member.username, member.username_lower, member.passowrd, member.email, member.gravatar_link, \ - member.website, member.tagline, member.bio, member.admin, member.lang) + member.create = datetime.datetime.now() + self.db.add(member) + self.db.commit() def insert_auth(self, member_id, random): - self.db.execute("""INSERT INTO `auth` (`member_id`, `secret`, `create`) VALUES (%s, %s, UTC_TIMESTAMP())""", \ - member_id, random) auth = Auth() auth.member_id = member_id auth.secret = random + auth.create = datetime.datetime.now() + self.db.add(auth) + self.db.commit() return auth ''' UPDATE ''' def update_member(self, member): - self.db.execute("""UPDATE `member` - SET `email` = %s, - `gravatar_link` = %s, - `website` = %s, - `tagline` = %s, - `bio` = %s, - `lang` = %s - WHERE `id` = %s""", member.email, member.gravatar_link, \ - member.website, member.tagline, member.bio, \ - member.lang, member.id) + # should not use this method + pass def update_member_password(self, member): - self.db.execute("""UPDATE `member` SET `password` = %s WHERE `id` = %s""", member.password, member.id) + # should not use this method + pass ''' DELETE ''' def delete_auth_by_secret(self, secret): - self.db.execute("""DELETE FROM `auth` WHERE `secret` = %s""", secret) + self.db.query(Auth).filter_by(secret = secret).delete() def delete_auth_by_member_id(self, member_id): - self.db.execute("""DELETE FROM `auth` WHERE `member_id` = %s""", member_id) + self.db.query(Auth).filter_by(member_id = member_id).delete() ''' OTHER ''' def create_auth(self, member_id): random = binascii.b2a_hex(uuid.uuid4().bytes) @@ -104,27 +76,18 @@ def create_auth(self, member_id): ''' class ForumDBMixin(object): - def _new_node(row): - node = Node() - node._init_row(row) - return node '''COUNT''' '''SELECT''' def select_node_by_id(self, node_id): - row = self.db.get("""SELECT * FROM `node` WHERE `id` = %s""", int(node_id)) - if row: - return self._new_node(row) + pass return None '''INSERT''' def insert_node(self, node): - node.id = self.db.execute("""INSERT INTO `node` (`name`, `link`, `description`) - VALUES (%s, %s, %s)""", node.name, node.link, node.description) + pass '''UPDATE''' def update_node(self, node): - self.db.execute("""UPDATE `node` SET `name` = %s, - `link` = %s, - `description` = %s, - WHERE `node`.`id` = %s""", node.name, node.link, node.description, node.id) + # shoud not use this method + pass '''DELETE''' ''' @@ -143,151 +106,62 @@ class NoteDBMixin(object): ''' class ProblemDBMixin(object): - ''' New Data Model ''' - def _new_problem(self, row): - problem = Problem() - problem._init_row(row) - return problem - def _new_problem_tag(self, row): - problem_tag = ProblemTag() - problem_tag._init_row(row) - return problem_tag - def _new_submit(self, row): - submit = Submit() - submit._init_row(row) - return submit ''' COUNT ''' def count_problem(self): - count = self.db.get("""SELECT COUNT(*) FROM `problem`""") - return count["COUNT(*)"] + return self.db.query(Problem).count() def count_visible_problem(self): - count = self.db.get("""SELECT COUNT(*) FROM `problem` WHERE `invisible` = 0""") - return count["COUNT(*)"] + return self.db.query(Problem).filter_by(invisible = 0).count() def count_problem_by_tagname(self, tagname): - count = self.db.get("""SELECT COUNT(*) FROM `problem_tag` WHERE `tagname` = %s""", tagname) - return count["COUNT(*)"] + return self.db.query(ProblemTag).filter_by(tagname = tagname).count() def count_visible_problem_by_tagname(self, tagname): - count = self.db.get("""SELECT COUNT(*) FROM `problem_tag` - LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` - WHERE `tagname` = %s AND `problem`.`invisible` = 0""", tagname) - return count["COUNT(*)"] + return self.db.query(ProblemTag).filter_by(tagname = tagname).join(Problem).filter_by(invisible = 0).count() def count_submit(self): - count = self.db.get("""SELECT COUNT(*) FROM `submit`""") - return count["COUNT(*)"] + return self.db.query(Submit).count() ''' SELECT ''' def select_problem_by_id(self, id): - row = self.db.get("""SELECT * FROM `problem` WHERE `id` = %s LIMIT 1""", id) - if row: - return self._new_problem(row) - return None + return self.db.query(Problem).get(id) def select_problem_tag_by_problem_id(self, problem_id): - rows = self.db.query("""SELECT * FROM `problem_tag` WHERE `problem_id` = %s""", problem_id) - result = [] - for row in rows: - result.append(self._new_problem_tag(row)) - return result + return self.db.query(ProblemTag).filter_by(problem_id = problem_id).all() def select_problem_order_by_id(self, count = 10, start = 0): - rows = self.db.query("""SELECT * FROM `problem` LIMIT %s, %s""", int(start), int(count)) - result = [] - for row in rows: - result.append(self._new_problem(row)) - return result + return self.db.query(Problem).offset(start).limit(count).all() def select_visible_problem_order_by_id(self, count = 10, start = 0): - rows = self.db.query("""SELECT * FROM `problem` WHERE `invisible` = 0 LIMIT %s, %s""", int(start), int(count)) - result = [] - for row in rows: - result.append(self._new_problem(row)) - return result + return self.db.query(Problem).filter_by(invisible = 0).offset(start).limit(count).all() def select_latest_visible_problem_order_by_id(self, count = 10): - rows = self.db.query("""SELECT * FROM `problem` WHERE `invisible` = 0 ORDER BY `id` DESC LIMIT %s""", int(count)) - result = [] - for row in rows: - result.append(self._new_problem(row)) - return result + return self.db.query(Problem).filter_by(invisible = 0).order_by(desc(Problem.id)).limit(count).all() def select_last_submit_by_problem_id_member_id(self, problem_id): - row = self.db.get("""SELECT * FROM `submit` WHERE `problem_id` = %s AND `member_id` = %s ORDER BY `id` DESC LIMIT 1""", \ - problem_id, self.current_user.id) - if row: - return self._new_submit(row) - return None + return self.db.query(Submit).filter_by(problem_id = problem_id).filter_by(member_id = self.current_user.id).order_by(desc(Submit.id)).all() def select_submit_by_id(self, sid): - row = self.db.get("""SELECT `submit`.*, `member`.`username`, `problem`.`title` FROM `submit` - LEFT JOIN `member` ON `submit`.`member_id` = `member`.`id` - LEFT JOIN `problem` ON `submit`.`problem_id` = `problem`.`id` - WHERE `submit`.`id` = %s LIMIT 1""", int(sid)) - if row: - return self._new_submit(row) - return None + return self.db.query(Submit).get(sid) def select_submit_order_by_id(self, count = 10, start = 0): - rows = self.db.query("""SELECT `submit`.*, `member`.`username`, `problem`.`title` FROM `submit` - LEFT JOIN `member` ON `submit`.`member_id` = `member`.`id` - LEFT JOIN `problem` ON `submit`.`problem_id` = `problem`.`id` - ORDER BY `submit`.`id` DESC LIMIT %s, %s""", int(start), int(count)) - result = [] - for row in rows: - result.append(self._new_submit(row)) - return result + return self.db.query(Submit).order_by(desc(Submit.id)).offset(start).limit(count).all() def select_submit_by_member_id(self, member_id, count = 10): - rows = self.db.query("""SELECT `submit`.*, `problem`.`title` FROM `submit` - LEFT JOIN `member` ON `submit`.`member_id` = `member`.`id` - LEFT JOIN `problem` ON `submit`.`problem_id` = `problem`.`id` - WHERE `submit`.`member_id` = %s - ORDER BY `submit`.`id` DESC LIMIT %s""", int(member_id), int(count)) - result = [] - for row in rows: - result.append(self._new_submit(row)) - return result + return self.db.query(Submit).filter_by(member_id = member_id).order_by(desc(Submit.id)).limit(count).all() def select_problem_by_tagname(self, tagname, count = 10, start = 0): - rows = self.db.query("""SELECT `problem_tag`.*, `problem`.* FROM `problem_tag` - LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` - WHERE `problem_tag`.`tagname` = %s AND `problem`.`invisible` = 0 - ORDER BY `problem`.`id` ASC - LIMIT %s, %s""", tagname, int(start), int(count)) - result = [] - for row in rows: - result.append(self._new_problem(row)) - return result + return self.db.query(ProblemTag).filter_by(tagname = tagname).join(Problem).order_by(Problem.id).offset(start).limit(count) def select_visible_problem_by_tagname(self, tagname, count = 10, start = 0): - rows = self.db.query("""SELECT `problem_tag`.*, `problem`.* FROM `problem_tag` - LEFT JOIN `problem` ON `problem_tag`.`problem_id` = `problem`.`id` - WHERE `problem_tag`.`tagname` = %s - ORDER BY `problem`.`id` ASC - LIMIT %s, %s""", tagname, int(start), int(count)) - result = [] - for row in rows: - result.append(self._new_problem(row)) - return result + return self.db.query(ProblemTag).filter_by(tagname = tagname).join(Problem).filter_by(invisible = 0).order_by(Problem.id).offset(start).limit(count) ''' INSERT ''' def insert_problem(self, problem): - problem.id = self.db.execute("""INSERT INTO `problem` (`title`, `shortname`, `content`, \ - `timelimit`, `memlimit`, `testpoint`, `invisible`, `create`) \ - VALUES (%s, %s, %s, %s, %s, %s, %s, UTC_TIMESTAMP())""" \ - , problem.title, problem.shortname, problem.content, \ - int(problem.timelimit), int(problem.memlimit), int(problem.testpoint), int(problem.invisible)) + problem.create = datetime.datetime.now() + self.db.add(problem) + self.db.commit() def insert_problem_tag(self, tagname, problem_id): - self.db.execute("""INSERT INTO `problem_tag` (`tagname`, `problem_id`) VAlUES (%s, %s)""", tagname, int(problem_id)) + problem_tag = ProblemTag() + problem_tag.tagname = tagname + problem_tag.problem_id = problem_id + self.db.add(problem_tag) + self.db.commit() def insert_submit(self, submit): - submit.id = self.db.execute("""INSERT INTO `submit` (`problem_id`, `member_id`, `code`, `timestamp`, - `lang`, `user_agent`, `ip`, `create`) - VALUES (%s, %s, %s, %s, %s, %s, %s, UTC_TIMESTAMP())""", \ - submit.problem_id, submit.member_id, submit.code, submit.timestamp, \ - submit.lang, submit.user_agent, submit.ip) + submit.create = datetime.datetime.now() + self.db.add(submit) + self.db.commit() ''' UPDATE ''' def update_problem(self, problem): - self.db.execute("""UPDATE `problem` SET `title` = %s, - `shortname` = %s, - `content` = %s, - `timelimit` = %s, - `memlimit` = %s, - `testpoint` = %s, - `invisible` = %s - WHERE `id` = %s""", \ - problem.title, problem.shortname, problem.content, \ - int(problem.timelimit), int(problem.memlimit), int(problem.testpoint), int(problem.invisible), \ - problem.id) + # should not use this method + pass ''' DELETE ''' def delete_problem_tag_by_problem_id(self, problem_id): - self.db.execute("""DELETE FROM `problem_tag` WHERE `problem_id` = %s""", int(problem_id)) + self.db.query(ProblemTag).filter_by(problem_id = problem_id).delete() ''' OTHER ''' ''' @@ -297,119 +171,59 @@ def delete_problem_tag_by_problem_id(self, problem_id): ''' class ContestDBMixin(object): - ''' New Data Model ''' - def _new_contest(self, row): - contest = Contest() - contest._init_row(row) - return contest - def _new_contest_problem(self, row): - contest_problem = ContestProblem() - contest_problem._init_row(row) - return contest_problem - def _new_contest_submit(self, row): - contest_submit = ContestSubmit() - contest_submit._init_row(row) - return contest_submit ''' COUNT ''' def count_contest(self): - row = self.db.get("""SELECT COUNT(*) FROM `contest`""") - return row["COUNT(*)"] + return self.db.query(Contest).count() def count_visible_contest(self): - row = self.db.get("""SELECT COUNT(*) FROM `contest` WHERE invisible = 0""") - return row["COUNT(*)"] + return self.db.query(Contest).filter_by(invisible = 0).count() ''' SELECT ''' def select_contest_by_id(self, contest_id): - row = self.db.get("""SELECT * FROM `contest` WHERE `id` = %s""", contest_id) - if row: - return self._new_contest(row) - return None + return self.db.query(Contest).get(contest_id) def select_contest_problem_by_contest_id(self, contest_id): - rows = self.db.query("""SELECT *, `problem`.* FROM `contest_problem` - LEFT JOIN `problem` ON `contest_problem`.`problem_id` = `problem`.`id` - WHERE `contest_id` = %s""", contest_id) - result = [] - for row in rows: - result.append(self._new_contest_problem(row)) - return result + return self.db.query(ContestProblem).filter_by(contest_id = contest_id).all() def select_contest_submit_by_contest_id_problem_id_user_id(self, contest_id, problem_id): - row = self.db.get("""SELECT * FROM `contest_submit` WHERE `contest_id` = %s AND `problem_id` = %s AND `member_id` = %s""", \ - contest_id, problem_id, self.current_user.id) - if row: - return self._new_contest_submit(row) - return None + return self.db.query(ContestSubmit).filter_by(contest_id = contest_id).filter_by(problem_id = problem_id).filter_by(member_id = self.current_user.id).one() def select_contest(self, start = 0, count = 20): - rows = self.db.query("""SELECT * FROM `contest` ORDER BY `id` DESC LIMIT %s, %s""", start, count) - result = [] - for row in rows: - result.append(self._new_contest(row)) - return result + return self.db.query(Contest).order_by(desc(Contest.id)).offset(start).limit(count).all() def select_visible_contest(self, start = 0, count = 20): - rows = self.db.query("""SELECT * FROM `contest` WHERE `invisible` = 0 ORDER BY `id` DESC LIMIT %s, %s""", start, count) - result = [] - for row in rows: - result.append(self._new_contest(row)) - return result + return self.db.query(Contest).filter_by(invisible = 0).order_by(desc(Contest.id)).offset(start).limit(count).all() ''' INSERT ''' def insert_contest(self, contest): - contest.id = self.db.execute("""INSERT INTO `contest` (`title`, `description`, `start_time`, - `end_time`, `invisible`, `create`) - VALUES (%s, %s, %s, %s, %s, UTC_TIMESTAMP())""", \ - contest.title, contest.description, contest.start_time, contest.end_time, \ - contest.invisible) + contest.create = datetime.datetime.now() + self.db.add(contest) + self.db.commit() def insert_contest_problem(self, contest_id, problem_id): - self.db.execute("""INSERT INTO `contest_problem` (`contest_id`, `problem_id`) VALUES (%s, %s)""", int(contest_id), int(problem_id)) + contest_problem = ContestProblem() + contest_problem.contest_id = contest_id + contest_problem.problem_id = problem_id + self.db.add(contest_problem) + self.db.commit() ''' UPDATE ''' def update_contest(self, contest): - self.db.execute("""UPDATE `contest` SET `title` = %s, - `description` = %s, - `start_time` = %s, - `end_time` = %s, - `invisible` = %s - WHERE `id` = %s""" \ - , contest.title, contest.description, contest.start_time, contest.end_time, \ - contest.invisible, contest.id) + # should not use this method + pass ''' DELETE ''' def delete_contest_problem_by_contest_id(self, contest_id): - self.db.execute("""DELETE FROM `contest_problem` WHERE `contest_id` = %s""", contest_id) + self.db.query(ContestProblem).filter_by(contest_id = contest_id).delete() ''' OTHER ''' class JudgerDBMixin(object): - ''' New Data Model ''' - def _new_judger(self, row): - judger = Judger() - judger._init_row(row) - return judger ''' SELECT ''' def select_judgers(self): - rows = self.db.query("""SELECT * FROM `judger`""") - result = [] - for row in rows: - result.append(self._new_judger(row)) - return result + return self.db.query(Judger).all() def select_judger_by_id(self, juder_id): - row = self.db.get("""SELECT * FROM `judger` WHERE `id` = %s""", juder_id) - if row: - return self._new_judger(row) - return None + return self.db.query(Judger).get(juder_id) def select_judger_by_queue(self): - row = self.db.get("""SELECT * FROM `judger` ORDER BY `queue_num`, `priority` LIMIT 1""") - if row: - return self._new_judger(row) - return None + return self.db.query(Judger).order_by(Judger.queue_num, Judger.priority).one() ''' INSERT ''' def insert_judger(self, judger): - judger.id = self.db.execute("""INSERT INTO `judger` (`name`, `description`, `path`, \ - `priority`, `queue_num`, `pubkey`, `create`) - VALUES (%s, %s, %s, %s, 0, %s, UTC_TIMESTAMP())""", \ - judger.name, judger.description, judger.path, judger.priority, judger.pubkey) + judger.create = datetime.datetime.now() + self.db.add(judger) + self.commit() ''' UPDATE ''' def update_judger(self, judger): - self.db.execute("""UPDATE `judger` SET `name` = %s, - `description` = %s, - `path` = %s, - `priority` = %s, - `pubkey` = %s - WHERE `id` = %s""", \ - judger.name, judger.description, judger.path, judger.priority, judger.pubkey, judger.id) + # should not use this method + pass def update_judger_count(self, judger): - self.db.execute("""UPDATE `judger` SET `queue_num` = 0 WHERE `id` = %s""", judger.id) + # should not use this method + pass diff --git a/judge/db/models.py b/judge/db/models.py index 08d61be..d22a129 100644 --- a/judge/db/models.py +++ b/judge/db/models.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/models.py # CREATED: 23:40:55 17/04/2012 -# MODIFIED: 00:29:45 18/04/2012 +# MODIFIED: 00:48:27 18/04/2012 from sqlalchemy import create_engine from sqlalchemy import Column, Integer, String, DateTime, Boolean @@ -36,7 +36,7 @@ class Auth(Base): __tablename__ = "auth" id = Column(Integer, primary_key = True) member_id = Column(Integer, ForeignKey("member.id")) - member = relation("member") + member = relation("Member") secret = Column(String) create = Column(DateTime) @@ -44,7 +44,7 @@ class ResetMail(Base): __tablename__ = "reset_mail" id = Column(Integer, primary_key = True) member_id = Column(Integer, ForeignKey("member.id")) - member = relation("member") + member = relation("Member") secret = Column(String) create = Column(DateTime) @@ -61,9 +61,9 @@ class Topic(Base): title = Column(String) content = Column(String) node_id = Column(Integer, ForeignKey("node.id")) - node = relation("node") + node = relation("Node") member_id = Column(Integer, ForeignKey("member.id")) - member = relation("member") + member = relation("Member") create = Column(DateTime) last_reply = Column(DateTime) @@ -72,9 +72,9 @@ class Reply(Base): id = Column(Integer, primary_key = True) content = Column(String) member_id = Column(Integer, ForeignKey("member.id")) - member = relation("member") + member = relation("Member") topic_id = Column(Integer, ForeignKey("topic.id")) - topic = relation("topic") + topic = relation("Topic") create = Column(DateTime) class Note(Base): @@ -83,16 +83,16 @@ class Note(Base): title = Column(String) content = Column(String) member_id = Column(Integer, ForeignKey("member.id")) - member = relation("member") + member = relation("Member") create = Column(DateTime) class RelatedProblem(Base): __tablename__ = "related_problem" id = Column(Integer, primary_key = True) problem_id = Column(Integer, ForeignKey("problem.id")) - problem = relation("problem") + problem = relation("Problem") note_id = Column(Integer, ForeignKey("note.id")) - note = relation("note") + note = relation("Note") class Problem(Base): __tablename__ = "problem" @@ -110,16 +110,16 @@ class ProblemTag(Base): __tablename__ = "problem_tag" id = Column(Integer, primary_key = True) problem_id = Column(Integer, ForeignKey("problem.id")) - problem = relation("problem") + problem = relation("Problem") tagname = Column(String) class Submit(Base): __tablename__ = "submit" id = Column(Integer, primary_key = True) problem_id = Column(Integer, ForeignKey("problem.id")) - problem = relation("problem") + problem = relation("Problem") member_id = Column(Integer, ForeignKey("member.id")) - member = relation("member") + member = relation("Member") code = Column(String) status = Column(Integer) testpoint = Column(String) @@ -142,26 +142,26 @@ class Contest(Base): description = Column(String) start_time = Column(DateTime) end_time = Column(DateTime) - invisible = Column(Boolean) + invisible = Column(Integer) create = Column(DateTime) class ContestProblem(Base): __tablename__ = "contest_problem" id = Column(Integer, primary_key = True) contest_id = Column(Integer, ForeignKey("contest.id")) - contest = relation("contest") + contest = relation("Contest") problem_id = Column(Integer, ForeignKey("problem.id")) - problem = relation("problem") + problem = relation("Problem") class ContestSubmit(Base): __tablename__ = "contest_submit" id = Column(Integer, primary_key = True) contest_id = Column(Integer, ForeignKey("contest.id")) - contest = relation("contest") + contest = relation("Contest") problem_id = Column(Integer, ForeignKey("problem.id")) - problem = relation("problem") + problem = relation("Problem") member_id = Column(Integer, ForeignKey("member.id")) - member = relation("member") + member = relation("Member") code = Column(String) status = Column(Integer) testpoint = Column(String) From 3711bbf2b41cd8c74f123ec24965822ead6e7edf Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Wed, 18 Apr 2012 02:27:58 +0800 Subject: [PATCH 47/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E7=9A=84=20ORM=20=E4=BD=BF=E7=94=A8=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem.py | 4 ++-- tpl/home.html | 4 ++-- tpl/submit.html | 10 +++++----- tpl/submit_list.html | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/problem.py b/problem.py index 6899177..4bd22e4 100644 --- a/problem.py +++ b/problem.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 16:59:41 05/04/2012 +# MODIFIED: 02:22:02 18/04/2012 import os import time @@ -185,7 +185,7 @@ def get(self, sid): breadcrumb.append((self._('Home'), '/')) breadcrumb.append((self._('Submit'), '/submit')) breadcrumb.append(("# %d" % submit.id, '/submit/%d' % submit.id)) - title = self._("Submit #%d - %s") % (submit.id, submit.title) + title = self._("Submit #%d - %s") % (submit.id, submit.problem.title) testpoint = [] if submit.testpoint: testpoint = zip(range(1, len(submit.testpoint) + 1), submit.testpoint, \ diff --git a/tpl/home.html b/tpl/home.html index a2537f0..02181b1 100644 --- a/tpl/home.html +++ b/tpl/home.html @@ -30,8 +30,8 @@ {{ submit.id }}
      {{ submit | get_submit_status }} - {{ submit.title }} - {{ submit.username }} + {{ submit.problem.title }} + {{ submit.member.username }} {{ submit.lang | lang2humantext }} {% endfor %} diff --git a/tpl/submit.html b/tpl/submit.html index 340a8f0..c386f97 100644 --- a/tpl/submit.html +++ b/tpl/submit.html @@ -11,11 +11,11 @@ {{ _('Problem') }} - {{ submit.title }} + {{ submit.problem.title }} {{ _('Member') }} - {{ submit.username }} + {{ submit.member.username }} {{ _('Status') }} @@ -30,15 +30,15 @@ {{ submit.score }} - {{ _('Cost Time') }} + {{ _('Time') }} {{ submit.costtime }} ms - {{ _('Cost Memory') }} + {{ _('Memory') }} {{ submit.costmemory }} KB - {{ _('Submit Time') }} + {{ _('Date') }} {{ submit.create }} {% if user.admin %} diff --git a/tpl/submit_list.html b/tpl/submit_list.html index b141a00..f00f79b 100644 --- a/tpl/submit_list.html +++ b/tpl/submit_list.html @@ -22,8 +22,8 @@ {{ submit.id }} {{ submit | get_submit_status }} - {{ submit.title }} - {{ submit.username }} + {{ submit.problem.title }} + {{ submit.member.username }} {{ submit.lang | lang2humantext }} {{ submit.costtime }} ms {{ submit.costmemory }} KB From 57352b45cfc5f2996ba7856352aebef4aafac57f Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Wed, 18 Apr 2012 03:03:12 +0800 Subject: [PATCH 48/56] =?UTF-8?q?=E5=BD=BB=E5=BA=95=E5=AE=8C=E6=88=90=20OR?= =?UTF-8?q?M=20=E8=BD=AC=E6=8D=A2..=20=E5=87=86=E5=A4=87=E5=B9=B6=E5=85=A5?= =?UTF-8?q?=20beta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backstage.py | 2 +- daemons/tasks.py | 2 +- judge/db/__init__.py | 52 +++++++++++++++++++++++++++++++----------- judge/db/models.py | 54 ++++++++++++++++++++++---------------------- 4 files changed, 68 insertions(+), 42 deletions(-) diff --git a/backstage.py b/backstage.py index f676e1c..4738367 100644 --- a/backstage.py +++ b/backstage.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: backstage.py # CREATED: 02:43:49 15/03/2012 -# MODIFIED: 02:13:40 18/03/2012 +# MODIFIED: 02:39:28 18/04/2012 import re import datetime diff --git a/daemons/tasks.py b/daemons/tasks.py index e8a2476..c239314 100644 --- a/daemons/tasks.py +++ b/daemons/tasks.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: tasks.py # CREATED: 02:27:12 17/03/2012 -# MODIFIED: 16:45:07 17/04/2012 +# MODIFIED: 03:02:52 18/04/2012 import os import MySQLdb diff --git a/judge/db/__init__.py b/judge/db/__init__.py index d0f6692..570c766 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 02:14:39 18/04/2012 +# MODIFIED: 02:49:21 18/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -30,6 +30,8 @@ def count_accepted_by_member_id(self, member_id): def count_submit_by_member_id(self, member_id): return self.db.query(Submit).filter_by(member_id = 1).count() ''' SELECT ''' + def select_member_by_id(self, member_id): + return self.db.query(Member).get(member_id) def select_member_by_username_lower(self, username_lower): return self.db.query(Member).filter_by(username_lower = username_lower).one() def select_member_by_email(self, email): @@ -53,11 +55,17 @@ def insert_auth(self, member_id, random): return auth ''' UPDATE ''' def update_member(self, member): - # should not use this method - pass + db_member = self.select_member_by_id(member.id) + db_member.email = member.email + db_member.website = member.website + db_member.tagline = member.tagline + db_member.bio = member.bio + db_member.gravatar_link = member.gravatar_link + db_member.lang = member.lang + self.db.commit() def update_member_password(self, member): - # should not use this method - pass + db_member = self.select_member_by_id(member.id) + db_member.password = member.password ''' DELETE ''' def delete_auth_by_secret(self, secret): self.db.query(Auth).filter_by(secret = secret).delete() @@ -157,8 +165,15 @@ def insert_submit(self, submit): self.db.commit() ''' UPDATE ''' def update_problem(self, problem): - # should not use this method - pass + db_problem = self.select_problem_by_id(problem.id) + db_problem.title = problem.title + db_problem.shortname = problem.shortname + db_problem.content = problem.content + db_problem.timelimit = problem.timelimit + db_problem.memlimit = problem.memlimit + db_problem.testpoint = problem.testpoint + db_problem.invisible = problem.invisible + self.db.commit() ''' DELETE ''' def delete_problem_tag_by_problem_id(self, problem_id): self.db.query(ProblemTag).filter_by(problem_id = problem_id).delete() @@ -200,8 +215,13 @@ def insert_contest_problem(self, contest_id, problem_id): self.db.commit() ''' UPDATE ''' def update_contest(self, contest): - # should not use this method - pass + db_contest = self.select_contest_by_id(contest_id) + db_contest.title = contest.title + db_contest.description = contest.description + db_contest.start_time = contest.start_time + db_contest.end_time = contest.end_time + db_contest.invisible = contest.invisible + self.db.commit() ''' DELETE ''' def delete_contest_problem_by_contest_id(self, contest_id): self.db.query(ContestProblem).filter_by(contest_id = contest_id).delete() @@ -222,8 +242,14 @@ def insert_judger(self, judger): self.commit() ''' UPDATE ''' def update_judger(self, judger): - # should not use this method - pass + db_judger = self.select_judger_by_id(judger.id) + db_judger.name = judger.name + db_judger.description = judger.description + db_judger.path = judger.path + db_judger.priority = judger.priority + db_judger.pubkey = judger.pubkey + self.db.commit() def update_judger_count(self, judger): - # should not use this method - pass + db_judger = self.select_judger_by_id(Judger.id) + db_judger.queue_num = 0 + self.db.commit() diff --git a/judge/db/models.py b/judge/db/models.py index d22a129..c3fe36f 100644 --- a/judge/db/models.py +++ b/judge/db/models.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/models.py # CREATED: 23:40:55 17/04/2012 -# MODIFIED: 00:48:27 18/04/2012 +# MODIFIED: 02:51:29 18/04/2012 from sqlalchemy import create_engine from sqlalchemy import Column, Integer, String, DateTime, Boolean @@ -24,13 +24,13 @@ class Member(Base): username_lower = Column(String) password = Column(String) email = Column(String) - website = Column(String) - tagline = Column(String) - bio = Column(String) - gravatar_link = Column(String) + website = Column(String, default = "") + tagline = Column(String, default = "") + bio = Column(String, default = "") + gravatar_link = Column(String, default = "") create = Column(DateTime) - admin = Column(Integer) - lang = Column(Integer) + admin = Column(Integer, default = 0) + lang = Column(Integer, default = 1) class Auth(Base): __tablename__ = "auth" @@ -53,13 +53,13 @@ class Node(Base): id = Column(Integer, primary_key = True) name = Column(String) link = Column(String) - description = Column(String) + description = Column(String, default = "") class Topic(Base): __tablename__ = "topic" id = Column(Integer, primary_key = True) title = Column(String) - content = Column(String) + content = Column(String, default = "") node_id = Column(Integer, ForeignKey("node.id")) node = relation("Node") member_id = Column(Integer, ForeignKey("member.id")) @@ -103,7 +103,7 @@ class Problem(Base): timelimit = Column(Integer) memlimit = Column(Integer) testpoint = Column(Integer) - invisible = Column(Boolean) + invisible = Column(Boolean, default = False) create = Column(DateTime) class ProblemTag(Base): @@ -120,19 +120,19 @@ class Submit(Base): problem = relation("Problem") member_id = Column(Integer, ForeignKey("member.id")) member = relation("Member") - code = Column(String) - status = Column(Integer) - testpoint = Column(String) - testpoint_time = Column(String) - testpoint_memory = Column(String) - score = Column(Integer) - costtime = Column(Integer) - costmemory = Column(Integer) - timestamp = Column(String) - lang = Column(Integer) - msg = Column(String) - user_agent = Column(String) - ip = Column(String) + code = Column(String, default = "") + status = Column(Integer, default = 0) + testpoint = Column(String, default = "") + testpoint_time = Column(String, default = "") + testpoint_memory = Column(String, default = "") + score = Column(Integer, default = 0) + costtime = Column(Integer, default = 0) + costmemory = Column(Integer, default = 0) + timestamp = Column(String, default = "") + lang = Column(Integer, default = 1) + msg = Column(String, default = "") + user_agent = Column(String, default = "") + ip = Column(String, default = "") create = Column(DateTime) class Contest(Base): @@ -142,7 +142,7 @@ class Contest(Base): description = Column(String) start_time = Column(DateTime) end_time = Column(DateTime) - invisible = Column(Integer) + invisible = Column(Boolean, default = False) create = Column(DateTime) class ContestProblem(Base): @@ -183,7 +183,7 @@ class Judger(Base): name = Column(String) description = Column(String) path = Column(String) - priority = Column(Integer) - queue_num = Column(Integer) - pubkey = Column(String) + priority = Column(Integer, default = 0) + queue_num = Column(Integer, default = 0) + pubkey = Column(String, default = "") create = Column(DateTime) From 152b3ab7d403d8202f0643b5ac5e487bccda6734 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Wed, 18 Apr 2012 04:11:00 +0800 Subject: [PATCH 49/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=8A=82=E7=82=B9=E3=80=81=E5=AE=8C=E6=88=90=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=B8=BB=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backstage.py | 8 +++- forum.py | 86 ++++++++++++++++++++++++++++++++++- handlers.py | 5 +- judge/db/__init__.py | 35 ++++++++++---- tpl/backstage/add_judger.html | 2 + tpl/backstage/add_node.html | 2 + tpl/base/sidebar.html | 2 +- tpl/macros.html | 4 +- tpl/problem.html | 11 +---- tpl/topic_create.html | 19 ++++++++ tpl/topic_list.html | 36 +++++++++++++++ 11 files changed, 186 insertions(+), 24 deletions(-) create mode 100644 tpl/topic_create.html create mode 100644 tpl/topic_list.html diff --git a/backstage.py b/backstage.py index 232352a..81cc427 100644 --- a/backstage.py +++ b/backstage.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: backstage.py # CREATED: 02:43:49 15/03/2012 -# MODIFIED: 03:05:03 18/04/2012 +# MODIFIED: 03:31:00 18/04/2012 import re import datetime @@ -167,12 +167,16 @@ def get(self): @backstage def post(self): name = self.get_argument("name", default = "") - link = self.get_argument("link", default = "") + link = self.get_argument("link", default = "").lower() nid = self.get_argument("nid", default = 0) error = [] node = Node() error.extend(self.check_text_value(name, self._("Name"), required = True, max = 100)) error.extend(self.check_text_value(link, self._("Link"), required = True, max = 100)) + if not error: + duplinode = self.select_node_by_link(link) + if duplinode: + error.append(self._("This link have taken.")) node.id = nid node.name = name node.link = link diff --git a/forum.py b/forum.py index c240136..51cc682 100644 --- a/forum.py +++ b/forum.py @@ -2,5 +2,89 @@ # AUTHOR: Zeray Rice # FILE: forum.py # CREATED: 22:39:44 17/04/2012 -# MODIFIED: 22:39:46 17/04/2012 +# MODIFIED: 04:06:41 18/04/2012 +from tornado.web import HTTPError +from tornado.web import authenticated + +from judge.db import Node +from judge.db import Topic +from judge.db import ForumDBMixin +from judge.base import BaseHandler + +class ViewNodeHandler(BaseHandler, ForumDBMixin): + def get(self, link): + node = self.select_node_by_link(link.lower()) + if not node: + raise HTTPError(404) + start = self.get_argument("start", default = 0) + try: + start = int(start) + except ValueError: + start = 0 + topics = self.select_topic_by_node_id(node.id, start = 0) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Forum'), '/forum')) + breadcrumb.append((node.name, '/go/%s' % node.link)) + title = node.name + self.render("topic_list.html", locals()) + +class CreateTopicHandler(BaseHandler, ForumDBMixin): + @authenticated + def get(self, link): + node = self.select_node_by_link(link.lower()) + if not node: + raise HTTPError(404) + if self.current_user.admin: + tid = self.get_argument("tid", default = 0) + try: + tid = int(tid) + except ValueError: + raise HTTPError(404) + topic = self.select_topic_by_id(tid) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Forum'), '/forum')) + breadcrumb.append((node.name, '/go/%s' % node.link)) + breadcrumb.append((self._("Create Topic"), '/new/%s' % node.link)) + title = self._("Create Topic") + self.render("topic_create.html", locals()) + @authenticated + def post(self, link): + node = self.select_node_by_link(link.lower()) + if not node: + raise HTTPError(404) + title = self.get_argument("title", default = "") + content = self.get_argument("content", default = "") + error = [] + topic = Topic() + if self.current_user.admin: + tid = self.get_argument("tid", default = 0) + try: + tid = int(tid) + except ValueError: + raise HTTPError(404) + topic.id = tid + error.extend(self.check_text_value(title, self._("Topic Title"), required = True, max = 255)) + error.extend(self.check_text_value(content, self._("Topic Content"), required = True, min = 5, max = 100000)) + topic.title = self.xhtml_escape(title) + topic.content = self.xhtml_escape(content) + if error: + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Forum'), '/forum')) + breadcrumb.append((node.name, '/go/%s' % node.link)) + breadcrumb.append((self._("Create Topic"), '/new/%s' % node.link)) + title = self._("Create Topic") + self.render("topic_create.html", locals()) + return + topic.node_id = node.id + topic.member_id = self.current_user.id + if topic.id: + self.update_topic(topic) + else: + self.insert_topic(topic) + self.redirect("/t/%s" % topic.id) + +__all__ = ["ViewNodeHandler", "CreateTopicHandler"] diff --git a/handlers.py b/handlers.py index 9dc8b7f..ba8e016 100644 --- a/handlers.py +++ b/handlers.py @@ -2,12 +2,13 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 22:42:07 17/04/2012 +# MODIFIED: 03:52:03 18/04/2012 # DESCRIPTION: URL Route from api import * from home import * from lang import * +from forum import * from member import * from problem import * from contest import * @@ -39,5 +40,7 @@ (r'/backstage/judger/add', AddJudgerHandler), (r'/contest', ListContestHandlder), (r'/contest/([\d]*)', ViewContestHandler), + (r'/go/(.*)', ViewNodeHandler), + (r'/new/(.*)', CreateTopicHandler), (r'/api/problem/get/([\d]*)', GetProblemHandler), ] diff --git a/judge/db/__init__.py b/judge/db/__init__.py index e1d73f0..a247fe8 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 03:04:51 18/04/2012 +# MODIFIED: 04:10:34 18/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -87,15 +87,34 @@ class ForumDBMixin(object): '''COUNT''' '''SELECT''' def select_node_by_id(self, node_id): - pass - return None + return self.db.query(Node).get(node_id) + def select_node_by_link(self, link): + return self.db.query(Node).filter_by(link = link).one() + def select_topic_by_id(self, topic_id): + return self.db.query(Topic).get(topic_id) + def select_topic_by_node_id(self, node_id, start = 0, count = 10): + return self.db.query(Topic).filter_by(node_id = node_id).offset(start).limit(count).all() '''INSERT''' def insert_node(self, node): - pass + self.db.add(node) + self.db.commit() + def insert_topic(self, topic): + # a bug here.. todo + topic.create = datetime.datetime.now() + topic.last_reply = datetime.datetime.now() + self.db.add(topic) + self.db.commit() '''UPDATE''' def update_node(self, node): - # shoud not use this method - pass + db_node = self.select_node_by_id(node.id) + db_node.name = node.name + db_node.link = node.link + db_node.description = node.description + self.db.commit() + def update_topic(self, topic): + db_topic = self.select_topic_by_id(topic.id) + db_topic.title = topic.title + db_topic.content = topic.content '''DELETE''' ''' @@ -231,8 +250,8 @@ class JudgerDBMixin(object): ''' SELECT ''' def select_judgers(self): return self.db.query(Judger).all() - def select_judger_by_id(self, juder_id): - return self.db.query(Judger).get(juder_id) + def select_judger_by_id(self, judger_id): + return self.db.query(Judger).get(judger_id) def select_judger_by_queue(self): return self.db.query(Judger).order_by(Judger.queue_num, Judger.priority).one() ''' INSERT ''' diff --git a/tpl/backstage/add_judger.html b/tpl/backstage/add_judger.html index f850d8c..4a9c6fc 100644 --- a/tpl/backstage/add_judger.html +++ b/tpl/backstage/add_judger.html @@ -2,8 +2,10 @@ {% from "macros.html" import input %} {% from "macros.html" import textarea %} {% from "macros.html" import form_actions %} +{% from "macros.html" import show_error_list %} {% block body %} +{{ show_error_list(error) }}
      {{ title }}
      diff --git a/tpl/backstage/add_node.html b/tpl/backstage/add_node.html index d3ee1ad..8f7c5e3 100644 --- a/tpl/backstage/add_node.html +++ b/tpl/backstage/add_node.html @@ -2,8 +2,10 @@ {% from "macros.html" import input %} {% from "macros.html" import textarea %} {% from "macros.html" import form_actions %} +{% from "macros.html" import show_error_list %} {% block body %} +{{ show_error_list(error) }}
      {{ title }}
      diff --git a/tpl/base/sidebar.html b/tpl/base/sidebar.html index 82d4c1f..5fe898f 100644 --- a/tpl/base/sidebar.html +++ b/tpl/base/sidebar.html @@ -106,7 +106,7 @@
    • - + {{ _('Add Node') }} diff --git a/tpl/macros.html b/tpl/macros.html index edf0d68..ba19cd2 100644 --- a/tpl/macros.html +++ b/tpl/macros.html @@ -59,12 +59,12 @@ {#================ Form ================#} -{% macro input(name, label, value = '', type = 'TEXT', class = 'input-xlarge', default = '', addon = '') %} +{% macro input(name, label, value = '', type = 'TEXT', class = 'input-xlarge', default = '', addon = '', style = '') %}
      {% if addon %}
      {% endif %} - + {% if addon %}{{ addon }}
      {% endif %}
      diff --git a/tpl/problem.html b/tpl/problem.html index 6355b29..67cc25b 100644 --- a/tpl/problem.html +++ b/tpl/problem.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% from 'macros.html' import form_actions %} +{% from "macros.html" import show_error_list %} {% block body %} {% if problem.invisible %} @@ -7,15 +8,7 @@ {{ _('This Problem is Invisible!') }}
    • {% endif %} -{% if error %} -
      -
        -{% for err in error %} -
      • {{ err }}
      • -{% endfor %} -
      -
      -{% endif %} +{{ show_error_list(error) }}
      {% if user.admin %} diff --git a/tpl/topic_create.html b/tpl/topic_create.html new file mode 100644 index 0000000..fa94ca8 --- /dev/null +++ b/tpl/topic_create.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% from "macros.html" import input %} +{% from "macros.html" import textarea %} +{% from "macros.html" import form_actions %} +{% from "macros.html" import show_error_list %} + +{% block body %} +{{ show_error_list(error) }} + +
      +
      {{ _('Create Topic') }} - {{ node.name }}
      + {{ page.xsrf_form_html() }} +
      + {{ input("title", _("Title"), value=topic.title, style="width:516px; ") }} + {{ textarea("content", _("Content"), value=topic.content, style="width:516px; height: 600px; ") }} + {{ form_actions(_("Submit")) }} +
      + +{% endblock %} diff --git a/tpl/topic_list.html b/tpl/topic_list.html new file mode 100644 index 0000000..173905d --- /dev/null +++ b/tpl/topic_list.html @@ -0,0 +1,36 @@ +{% extends "base.html" %} +{% from "macros.html" import input %} +{% from "macros.html" import textarea %} +{% from "macros.html" import form_actions %} + +{% block body %} +{% if topics %} +
      +
      + + {{ node.name }} +
      +
      + {% for topic in topics %} + {{topic.title}} + {% endfor %} +
      +
      +{% else %} +
      + No topic yet. {% if user %}Create one?{% endif %} +
      +{% endif %} +{% if user %} +
      +
      +
      {{ _('Create Topic') }}
      + {{ page.xsrf_form_html() }} +
      + {{ input("title", _("Title"), style="width:516px; ") }} + {{ textarea("content", _("Content"), style="width:516px; height: 300px; ") }} + {{ form_actions(_("Submit")) }} +
      +
      +{% endif %} +{% endblock %} From 241af8a094fe61b3abb4b6e2a4fd951b18efdb42 Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Wed, 18 Apr 2012 18:24:39 +0800 Subject: [PATCH 50/56] =?UTF-8?q?=E5=AE=8C=E6=88=90=20forum=20=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E2=80=A6=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- forum.py | 89 ++++++++++++++++++++++++++++++++++++++-- handlers.py | 4 +- judge/db/__init__.py | 10 ++++- less/forum.less | 98 ++++++++++++++++++++++++++++++++++++++++++++ less/style.less | 2 + static/css/style.css | 82 ++++++++++++++++++++++++++++++++++++ tpl/macros.html | 10 +++++ tpl/topic.html | 67 ++++++++++++++++++++++++++++++ tpl/topic_list.html | 26 ++++++++++-- 9 files changed, 378 insertions(+), 10 deletions(-) create mode 100644 less/forum.less create mode 100644 tpl/topic.html diff --git a/forum.py b/forum.py index 51cc682..9754585 100644 --- a/forum.py +++ b/forum.py @@ -2,12 +2,14 @@ # AUTHOR: Zeray Rice # FILE: forum.py # CREATED: 22:39:44 17/04/2012 -# MODIFIED: 04:06:41 18/04/2012 +# MODIFIED: 18:21:14 18/04/2012 +import datetime from tornado.web import HTTPError from tornado.web import authenticated from judge.db import Node +from judge.db import Reply from judge.db import Topic from judge.db import ForumDBMixin from judge.base import BaseHandler @@ -28,6 +30,25 @@ def get(self, link): breadcrumb.append((self._('Forum'), '/forum')) breadcrumb.append((node.name, '/go/%s' % node.link)) title = node.name + for topic in topics: + topic.reply_count = self.count_reply_by_topic_id(topic.id) + self.render("topic_list.html", locals()) + +class ViewForumHandler(BaseHandler, ForumDBMixin): + def get(self): + start = self.get_argument("start", default = 0) + try: + start = int(start) + except ValueError: + start = 0 + topics = self.select_lates_topic(start = 0) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Forum'), '/forum')) + title = self._("Forum") + index = True + for topic in topics: + topic.reply_count = self.count_reply_by_topic_id(topic.id) self.render("topic_list.html", locals()) class CreateTopicHandler(BaseHandler, ForumDBMixin): @@ -65,7 +86,8 @@ def post(self, link): tid = int(tid) except ValueError: raise HTTPError(404) - topic.id = tid + if tid: + topic.id = tid error.extend(self.check_text_value(title, self._("Topic Title"), required = True, max = 255)) error.extend(self.check_text_value(content, self._("Topic Content"), required = True, min = 5, max = 100000)) topic.title = self.xhtml_escape(title) @@ -84,7 +106,66 @@ def post(self, link): if topic.id: self.update_topic(topic) else: - self.insert_topic(topic) + #self.insert_topic(topic) + topic.create = datetime.datetime.now() + topic.last_reply = datetime.datetime.now() + self.db.add(topic) + self.db.commit() + self.db.flush() self.redirect("/t/%s" % topic.id) -__all__ = ["ViewNodeHandler", "CreateTopicHandler"] +class ViewTopicHandler(BaseHandler, ForumDBMixin): + def get(self, topic_id): + try: + topic_id = int(topic_id) + except ValueError: + raise HTTPError(404) + topic = self.select_topic_by_id(topic_id) + if not topic: + raise HTTPError(404) + replies = self.select_reply_by_topic_id(topic_id) + topic.reply_count = len(replies) + title = topic.title + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Forum'), '/forum')) + breadcrumb.append((topic.node.name, '/go/%s' % topic.node.link)) + breadcrumb.append((topic.title, '/t/%d' % topic.id)) + self.render("topic.html", locals()) + @authenticated + def post(self, topic_id): + try: + topic_id = int(topic_id) + except ValueError: + raise HTTPError(404) + topic = self.select_topic_by_id(topic_id) + if not topic: + raise HTTPError(404) + content = self.get_argument("content", default = "") + error = [] + error.extend(self.check_text_value(content, self._("Reply Content"), required = True, min = 5)) + if error: + replies = self.select_reply_by_topic_id(topic_id) + topic.reply_count = len(replies) + title = topic.title + content = self.xhtml_escape(content) + breadcrumb = [] + breadcrumb.append((self._('Home'), '/')) + breadcrumb.append((self._('Forum'), '/forum')) + breadcrumb.append((topic.node.name, '/go/%s' % topic.node.link)) + breadcrumb.append((topic.title, '/t/%d' % topic.id)) + self.render("topic.html", locals()) + return + reply = Reply() + reply.content = content + reply.topic_id = topic.id + reply.member_id = self.current_user.id + reply.create = datetime.datetime.now() + self.db.add(reply) + self.db.commit() + topic.last_reply = datetime.datetime.now() + self.db.commit() + self.redirect("/t/%d" % topic_id) + + +__all__ = ["ViewNodeHandler", "CreateTopicHandler", "ViewTopicHandler", "ViewForumHandler"] diff --git a/handlers.py b/handlers.py index ba8e016..b199cf0 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 03:52:03 18/04/2012 +# MODIFIED: 18:18:55 18/04/2012 # DESCRIPTION: URL Route from api import * @@ -41,6 +41,8 @@ (r'/contest', ListContestHandlder), (r'/contest/([\d]*)', ViewContestHandler), (r'/go/(.*)', ViewNodeHandler), + (r'/t/([\d]*)', ViewTopicHandler), (r'/new/(.*)', CreateTopicHandler), + (r'/forum', ViewForumHandler), (r'/api/problem/get/([\d]*)', GetProblemHandler), ] diff --git a/judge/db/__init__.py b/judge/db/__init__.py index a247fe8..2743b08 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 04:10:34 18/04/2012 +# MODIFIED: 18:18:21 18/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -85,6 +85,8 @@ def create_auth(self, member_id): class ForumDBMixin(object): '''COUNT''' + def count_reply_by_topic_id(self, topic_id): + return self.db.query(Reply).filter_by(topic_id = topic_id).count() '''SELECT''' def select_node_by_id(self, node_id): return self.db.query(Node).get(node_id) @@ -93,7 +95,11 @@ def select_node_by_link(self, link): def select_topic_by_id(self, topic_id): return self.db.query(Topic).get(topic_id) def select_topic_by_node_id(self, node_id, start = 0, count = 10): - return self.db.query(Topic).filter_by(node_id = node_id).offset(start).limit(count).all() + return self.db.query(Topic).filter_by(node_id = node_id).order_by(desc(Topic.last_reply)).offset(start).limit(count).all() + def select_reply_by_topic_id(self, topic_id): + return self.db.query(Reply).filter_by(topic_id = topic_id).all() + def select_lates_topic(self, start = 0, count = 10): + return self.db.query(Topic).order_by(desc(Topic.last_reply)).offset(start).limit(count).all() '''INSERT''' def insert_node(self, node): self.db.add(node) diff --git a/less/forum.less b/less/forum.less new file mode 100644 index 0000000..a0d6078 --- /dev/null +++ b/less/forum.less @@ -0,0 +1,98 @@ +.topicList { + list-style: none; + margin: 0; + + .topic { + padding: 10px 20px; + min-height: 45px; + + .userAvatar { + float: left; + } + .topicInfo { + display: inline-block; + margin-left: 10px; + margin-top: 3px; + + .topicTitle { + font-size: 16px; + } + + .topicMeta { + font-size: 10px; + margin-top: 6px; + color: #CCC; + font-weight: bold; + + .node { + .border-radius(2px); + text-decoration: none; + color: #999; + background-color: whiteSmoke; + font-size: 10px; + line-height: 10px; + display: inline-block; + padding: 4px 4px 3px 4px; + + &:hover { + background-color: #DDD; + } + } + a { + color: #999; + } + } + } + } +} + +.singleTopic { + .topicMeta { + font-size: 13px; + color: #999; + } +} + +.topicContent { + width: 100%; + + .author { + border-left: 1px solid #DDD; + width: 70px; + height: 70px; + padding: 10px; + } +} + +.replyListMeta { + font-size: 12px; + line-height: 16px; + padding: 10px 10px; + height: 16px; + color: #999; +} + +.replyList { + list-style: none; + margin: 0; + + .reply { + + .replyContent { + width: 100%; + + .avatar { + padding: 10px; + width: 50px; + height: 50px; + border-right: 1px solid #DDD; + } + .replyMeta { + color: #999; + border-bottom: 1px solid #DDD; + padding: 4px; + font-size: 11px; + } + } + } +} diff --git a/less/style.less b/less/style.less index 33d5770..5c3b7a3 100644 --- a/less/style.less +++ b/less/style.less @@ -501,3 +501,5 @@ nav { } } } + +@import "forum.less"; diff --git a/static/css/style.css b/static/css/style.css index 65b7d29..9f95f01 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -4367,3 +4367,85 @@ nav .copyright a { width: 100%; margin-left: 0; } +.topicList { + list-style: none; + margin: 0; +} +.topicList .topic { + padding: 10px 20px; + min-height: 45px; +} +.topicList .topic .userAvatar { + float: left; +} +.topicList .topic .topicInfo { + display: inline-block; + margin-left: 10px; + margin-top: 3px; +} +.topicList .topic .topicInfo .topicTitle { + font-size: 16px; +} +.topicList .topic .topicInfo .topicMeta { + font-size: 10px; + margin-top: 6px; + color: #CCC; + font-weight: bold; +} +.topicList .topic .topicInfo .topicMeta .node { + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + text-decoration: none; + color: #999; + background-color: whiteSmoke; + font-size: 10px; + line-height: 10px; + display: inline-block; + padding: 4px 4px 3px 4px; +} +.topicList .topic .topicInfo .topicMeta .node:hover { + background-color: #DDD; +} +.topicList .topic .topicInfo .topicMeta a { + color: #999; +} +.singleTopic .topicMeta { + font-size: 13px; + color: #999; +} +.topicContent { + width: 100%; +} +.topicContent .author { + border-left: 1px solid #DDD; + width: 70px; + height: 70px; + padding: 10px; +} +.replyListMeta { + font-size: 12px; + line-height: 16px; + padding: 10px 10px; + height: 16px; + color: #999; +} +.replyList { + list-style: none; + margin: 0; +} +.replyList .reply .replyContent { + width: 100%; +} +.replyList .reply .replyContent .avatar { + padding: 10px; + width: 50px; + height: 50px; + border-right: 1px solid #DDD; +} +.replyList .reply .replyContent .replyMeta { + color: #999; + border-bottom: 1px solid #DDD; + padding: 4px; + font-size: 11px; +} diff --git a/tpl/macros.html b/tpl/macros.html index ba19cd2..12e8692 100644 --- a/tpl/macros.html +++ b/tpl/macros.html @@ -93,3 +93,13 @@
      {% endmacro %} + +{% macro plural_word(count, zero, single, more) %} +{% if count == 0 %} +{{ zero }} +{% elif count == 1 %} +{{ single }} +{% else %} +{{ more }} +{% endif %} +{% endmacro %} diff --git a/tpl/topic.html b/tpl/topic.html new file mode 100644 index 0000000..faa3a81 --- /dev/null +++ b/tpl/topic.html @@ -0,0 +1,67 @@ +{% extends "base.html" %} +{% from "macros.html" import textarea %} +{% from "macros.html" import plural_word %} +{% from "macros.html" import form_actions %} +{% from "macros.html" import show_error_list %} + +{% block body %} +
      +
      +
      by {{ topic.member.username }} at {{ topic.create }}
      + {{ topic.title }} +
      +
      + + + + + +
      {{ topic.content | autolink }}{{ topic.member.gravatar_link | avatar_img(70) }}
      +
      +
      +{% if replies %} +
      +
      +
      {{ plural_word(topic.reply_count, "No reply", "1 reply", "%d replies" % topic.reply_count)}} | Till {{ topic.last_reply }}
      +
      + +
      +{% else %} +
      + No reply yet. +
      +{% endif %} +{% if user %} +{{ show_error_list(error) }} +
      +
      +
      {{ _('Reply Topic') }}
      + {{ page.xsrf_form_html() }} +
      + {{ textarea("content", _("Content"), style="width:516px; height: 300px; ", value=content) }} + {{ form_actions(_("Submit")) }} +
      +
      +{% endif %} + +{% endblock %} diff --git a/tpl/topic_list.html b/tpl/topic_list.html index 173905d..e947f6d 100644 --- a/tpl/topic_list.html +++ b/tpl/topic_list.html @@ -1,19 +1,37 @@ {% extends "base.html" %} {% from "macros.html" import input %} {% from "macros.html" import textarea %} +{% from "macros.html" import plural_word %} {% from "macros.html" import form_actions %} {% block body %} {% if topics %}
      + {% if node %} {{ node.name }} + {% else %} + {{ _('Forum') }} + {% endif %}
      +
        {% for topic in topics %} - {{topic.title}} +
      • +
        {{ topic.member.gravatar_link | avatar_img }}
        +
        + +
        + {{ topic.node.name }} • + {{ topic.member.username }} • + • + {{ plural_word(topic.reply_count, "No reply", "1 reply", "%d replies" % topic.reply_count)}} +
        +
        +
      • {% endfor %} +
      {% else %} @@ -21,8 +39,8 @@ No topic yet. {% if user %}Create one?{% endif %}
      {% endif %} -{% if user %} -
      +{% if user and node %} +
      {{ _('Create Topic') }}
      {{ page.xsrf_form_html() }} @@ -33,4 +51,6 @@
      {% endif %} +{% if not node %} +{% endif %} {% endblock %} From 314b03e2c26272a282050272712bcd1ca5aa15bf Mon Sep 17 00:00:00 2001 From: Zeray Rice Date: Wed, 18 Apr 2012 22:43:53 +0800 Subject: [PATCH 51/56] =?UTF-8?q?=E5=90=84=E7=A7=8D=E4=BF=AE=E6=94=B9..=20?= =?UTF-8?q?MySQL=20=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96..=20=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backstage.py | 13 +++++++---- forum.py | 11 ++++++---- handlers.py | 3 ++- home.py | 6 +++-- judge/base/__init__.py | 20 +++++++++++------ judge/db/__init__.py | 10 +++++---- less/style.less | 4 ++-- main.py | 4 ++-- member.py | 50 +++++++++++++++++++++++++++++++++++------- problem.py | 9 ++++++-- static/css/style.css | 4 ++-- tpl/base/sidebar.html | 8 +++---- tpl/home.html | 13 +++++++---- tpl/member.html | 20 ++++++++--------- tpl/settings.html | 2 +- tpl/submit.html | 4 ++-- tpl/submit_list.html | 20 ++++++++--------- tpl/topic.html | 4 ++-- tpl/topic_list.html | 2 +- tpl/widget/notice.html | 2 +- 20 files changed, 136 insertions(+), 73 deletions(-) diff --git a/backstage.py b/backstage.py index 81cc427..9757ee3 100644 --- a/backstage.py +++ b/backstage.py @@ -2,11 +2,12 @@ # AUTHOR: Zeray Rice # FILE: backstage.py # CREATED: 02:43:49 15/03/2012 -# MODIFIED: 03:31:00 18/04/2012 +# MODIFIED: 18:31:05 18/04/2012 import re import datetime import functools +from sqlalchemy.orm.exc import NoResultFound from tornado.web import HTTPError @@ -174,10 +175,14 @@ def post(self): error.extend(self.check_text_value(name, self._("Name"), required = True, max = 100)) error.extend(self.check_text_value(link, self._("Link"), required = True, max = 100)) if not error: - duplinode = self.select_node_by_link(link) - if duplinode: + try: + duplinode = self.select_node_by_link(link) + except NoResultFound: + pass + else: error.append(self._("This link have taken.")) - node.id = nid + if nid: + node.id = nid node.name = name node.link = link node.description = "" diff --git a/forum.py b/forum.py index 9754585..302e424 100644 --- a/forum.py +++ b/forum.py @@ -2,11 +2,12 @@ # AUTHOR: Zeray Rice # FILE: forum.py # CREATED: 22:39:44 17/04/2012 -# MODIFIED: 18:21:14 18/04/2012 +# MODIFIED: 18:52:37 18/04/2012 import datetime from tornado.web import HTTPError from tornado.web import authenticated +from sqlalchemy.orm.exc import NoResultFound from judge.db import Node from judge.db import Reply @@ -57,6 +58,7 @@ def get(self, link): node = self.select_node_by_link(link.lower()) if not node: raise HTTPError(404) + topic = None if self.current_user.admin: tid = self.get_argument("tid", default = 0) try: @@ -73,8 +75,9 @@ def get(self, link): self.render("topic_create.html", locals()) @authenticated def post(self, link): - node = self.select_node_by_link(link.lower()) - if not node: + try: + node = self.select_node_by_link(link.lower()) + except NoResultFound: raise HTTPError(404) title = self.get_argument("title", default = "") content = self.get_argument("content", default = "") @@ -157,7 +160,7 @@ def post(self, topic_id): self.render("topic.html", locals()) return reply = Reply() - reply.content = content + reply.content = self.xhtml_escape(content) reply.topic_id = topic.id reply.member_id = self.current_user.id reply.create = datetime.datetime.now() diff --git a/handlers.py b/handlers.py index b199cf0..e861379 100644 --- a/handlers.py +++ b/handlers.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: handlers.py # CREATED: 01:41:06 08/03/2012 -# MODIFIED: 18:18:55 18/04/2012 +# MODIFIED: 20:28:26 18/04/2012 # DESCRIPTION: URL Route from api import * @@ -44,5 +44,6 @@ (r'/t/([\d]*)', ViewTopicHandler), (r'/new/(.*)', CreateTopicHandler), (r'/forum', ViewForumHandler), + (r'/test', TestHandler), (r'/api/problem/get/([\d]*)', GetProblemHandler), ] diff --git a/home.py b/home.py index 5612cb0..f3ab41b 100644 --- a/home.py +++ b/home.py @@ -2,17 +2,18 @@ # AUTHOR: Zeray Rice # FILE: home.py # CREATED: 02:00:16 08/03/2012 -# MODIFIED: 19:27:54 17/04/2012 +# MODIFIED: 18:26:17 18/04/2012 # DESCRIPTION: Home handler from contest import get_contest_status +from judge.db import ForumDBMixin from judge.db import MemberDBMixin from judge.db import ContestDBMixin from judge.db import ProblemDBMixin from judge.base import BaseHandler -class HomeHandler(BaseHandler, MemberDBMixin, ProblemDBMixin, ContestDBMixin): +class HomeHandler(BaseHandler, MemberDBMixin, ProblemDBMixin, ContestDBMixin, ForumDBMixin): def get(self): title = self._("Home") breadcrumb = [] @@ -23,6 +24,7 @@ def get(self): for contest in latest_contest: contest.status = get_contest_status(contest) latest_topic = [] + latest_node = self.select_latest_node() count_problem = self.count_visible_problem() count_member = self.count_member() self.render("home.html", locals()) diff --git a/judge/base/__init__.py b/judge/base/__init__.py index d1d05eb..c69715a 100644 --- a/judge/base/__init__.py +++ b/judge/base/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/base/__init__.py # CREATED: 01:49:33 08/03/2012 -# MODIFIED: 02:16:21 18/04/2012 +# MODIFIED: 22:24:01 18/04/2012 # DESCRIPTION: Base handler import re @@ -20,6 +20,7 @@ from pygments.lexers import CppLexer from pygments.lexers import DelphiLexer from pygments.formatters import HtmlFormatter +from sqlalchemy.orm.exc import NoResultFound import tornado.web import tornado.escape @@ -104,6 +105,7 @@ def render(self, tplname, args = {}): tpl = self.jinja2.get_template(tplname) ren = tpl.render(page = self, _ = self._, user = self.current_user, **args) self.write(ren) + self.db.close() self.finish() def write_error(self, status_code, **kwargs): '''Rewrite write_error for custom error page''' @@ -154,8 +156,11 @@ def check_username(self, usr, queryDB = False): regex = re.compile(r'^([\w\d]*)$'), \ regex_msg = self._("A username can only contain letters and digits."))) if not error and queryDB: - query = self.select_member_by_username_lower(usr.lower()) - if query: + try: + query = self.select_member_by_username_lower(usr.lower()) + except NoResultFound: + pass + else: error.append(self._("That username is taken. Please choose another.")) return error def check_password(self, pwd): @@ -166,8 +171,11 @@ def check_email(self, email, queryDB = False): regex = re.compile(r"(?:^|\s)[-a-z0-9_.+]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}(?:\s|$)", re.IGNORECASE), \ regex_msg = self._("Your Email address is invalid."))) if not error and queryDB: - query = self.select_member_by_email(email) - if query: + try: + query = self.select_member_by_email(email) + except NoResultFound: + pass + else: error.append(self._("That Email is taken. Please choose another.")) return error def get_gravatar_url(self, email): @@ -178,8 +186,6 @@ def post_to_judger(self, query, judger, callback = None): query["code"] = query["code"].decode("utf-8") query = dict(sorted(query.iteritems(), key=itemgetter(1))) jsondump = json.dumps(query) - print jsondump - print judger.pubkey.strip() sign = hashlib.sha1(jsondump + judger.pubkey.strip()).hexdigest() query["sign"] = sign http_client = AsyncHTTPClient() diff --git a/judge/db/__init__.py b/judge/db/__init__.py index 2743b08..06d21cd 100644 --- a/judge/db/__init__.py +++ b/judge/db/__init__.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: judge/db/__init__.py # CREATED: 02:01:23 08/03/2012 -# MODIFIED: 18:18:21 18/04/2012 +# MODIFIED: 20:41:50 18/04/2012 # DESCRIPTION: Database Table Object import uuid @@ -26,9 +26,9 @@ class MemberDBMixin(object): def count_member(self): return self.db.query(Member).count() def count_accepted_by_member_id(self, member_id): - return self.db.query(Submit).filter_by(member_id = 1).filter_by(status = 1).count() + return self.db.query(Submit).filter_by(member_id = member_id).filter_by(status = 1).count() def count_submit_by_member_id(self, member_id): - return self.db.query(Submit).filter_by(member_id = 1).count() + return self.db.query(Submit).filter_by(member_id = member_id).count() ''' SELECT ''' def select_member_by_id(self, member_id): return self.db.query(Member).get(member_id) @@ -88,6 +88,8 @@ class ForumDBMixin(object): def count_reply_by_topic_id(self, topic_id): return self.db.query(Reply).filter_by(topic_id = topic_id).count() '''SELECT''' + def select_latest_node(self, count = 20): + return self.db.query(Node).order_by(desc(Node.id)).limit(count).all() def select_node_by_id(self, node_id): return self.db.query(Node).get(node_id) def select_node_by_link(self, link): @@ -162,7 +164,7 @@ def select_visible_problem_order_by_id(self, count = 10, start = 0): def select_latest_visible_problem_order_by_id(self, count = 10): return self.db.query(Problem).filter_by(invisible = 0).order_by(desc(Problem.id)).limit(count).all() def select_last_submit_by_problem_id_member_id(self, problem_id): - return self.db.query(Submit).filter_by(problem_id = problem_id).filter_by(member_id = self.current_user.id).order_by(desc(Submit.id)).all() + return self.db.query(Submit).filter_by(problem_id = problem_id).filter_by(member_id = self.current_user.id).order_by(desc(Submit.id)).limit(1).one() def select_submit_by_id(self, sid): return self.db.query(Submit).get(sid) def select_submit_order_by_id(self, count = 10, start = 0): diff --git a/less/style.less b/less/style.less index 5c3b7a3..4b0deda 100644 --- a/less/style.less +++ b/less/style.less @@ -173,8 +173,8 @@ a { .tag { .border-radius(4px); background-color: #EEE; - padding: 4px 4px 2px 10px; - float: left; + padding: 4px 10px; + display: inline; margin-right: 4px; margin-bottom: 5px; diff --git a/main.py b/main.py index 92743cd..a5ed1b2 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ # AUTHOR: Zeray Rice # FILE: main.py # CREATED: 01:37:19 08/03/2012 -# MODIFIED: 23:41:07 17/04/2012 +# MODIFIED: 22:08:52 18/04/2012 # DESCRIPTION: Main Server File, run as `python2 main.py [port_num]` import re @@ -51,7 +51,7 @@ def __init__(self): # self.db = tornado.database.Connection( # host=options.mysql_host, database=options.mysql_database, # user=options.mysql_user, password=options.mysql_password) - engine = create_engine(mysql_path, convert_unicode=True, echo=options.debug) + engine = create_engine(mysql_path, convert_unicode=True)#, echo=options.debug) models.init_db(engine) self.db = scoped_session(sessionmaker(bind=engine)) diff --git a/member.py b/member.py index bdcc44d..68d3509 100644 --- a/member.py +++ b/member.py @@ -2,12 +2,16 @@ # AUTHOR: Zeray Rice # FILE: member.py # CREATED: 02:18:23 09/03/2012 -# MODIFIED: 19:24:32 17/04/2012 +# MODIFIED: 20:29:11 18/04/2012 # DESCRIPTION: member handlers import re import copy +import uuid +import binascii import bcrypt +import datetime +from sqlalchemy.orm.exc import NoResultFound from tornado.web import HTTPError from tornado.web import authenticated @@ -32,8 +36,9 @@ def post(self): pwd = pwd.encode("utf-8") pwd = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) if not error: - member = self.select_member_by_usr_pwd(usr, pwd) - if not member: + try: + member = self.select_member_by_usr_pwd(usr, pwd) + except NoResultFound: error.append(self._("Wrong Username and password combination.")) if error: self.render("signin.html", locals()) @@ -42,7 +47,6 @@ def post(self): self.set_secure_cookie("auth", auth.secret) self.set_secure_cookie("uid", str(auth.member_id)) go_next = self.get_argument("next", default = None) - print go_next if go_next: self.redirect(go_next) return @@ -68,10 +72,12 @@ def post(self): member = Member() member.username = usr member.username_lower = usr.lower() - member.passowrd = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) + member.password = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) member.email = email member.gravatar_link = self.get_gravatar_url(email) - self.insert_member(member) + member.create = datetime.datetime.now() + self.db.add(member) + self.db.commit() auth = self.create_auth(member.id) self.set_secure_cookie('auth', auth.secret) self.set_secure_cookie('uid', str(auth.member_id)) @@ -198,7 +204,35 @@ def get(self): for member in members: member.accepted = self.count_accepted_by_member_id(member.id) member.submit = self.count_submit_by_member_id(member.id) - member.rating = member.accepted / float(member.submit) * 100 + member.rating = 0.0 + if member.submit: + member.rating = round(float(member.accepted) / member.submit * 100, 2) self.render("member_list.html", locals()) -__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler", "ChangePasswordHandler", "MemberHandler", "ListMemberHandler"] +class TestHandler(BaseHandler, MemberDBMixin): + def post(self): + usr = binascii.b2a_hex(uuid.uuid4().bytes)[3:10] + pwd = binascii.b2a_hex(uuid.uuid4().bytes)[3:10] + email = usr + "@gmail.com" + error = [] + error.extend(self.check_username(usr.lower(), queryDB = True)) + error.extend(self.check_password(pwd)) + error.extend(self.check_email(email, queryDB = True)) + if error: + self.render("signup.html", locals()) + return + member = Member() + member.username = usr + member.username_lower = usr.lower() + member.password = bcrypt.hashpw(pwd, self.settings['bcrypt_salt']) + member.email = email + member.gravatar_link = self.get_gravatar_url(email) + member.create = datetime.datetime.now() + self.db.add(member) + self.db.commit() + auth = self.create_auth(member.id) + self.set_secure_cookie('auth', auth.secret) + self.set_secure_cookie('uid', str(auth.member_id)) + self.redirect('/') + +__all__ = ["SigninHandler", "SignupHandler", "SignoutHandler", "SettingsHandler", "ChangePasswordHandler", "MemberHandler", "ListMemberHandler", "TestHandler"] diff --git a/problem.py b/problem.py index 4bd22e4..78700a4 100644 --- a/problem.py +++ b/problem.py @@ -2,10 +2,11 @@ # AUTHOR: Zeray Rice # FILE: problem.py # CREATED: 04:04:57 15/03/2012 -# MODIFIED: 02:22:02 18/04/2012 +# MODIFIED: 22:08:40 18/04/2012 import os import time +from sqlalchemy.orm.exc import NoResultFound from tornado.web import HTTPError from tornado.web import asynchronous @@ -128,7 +129,10 @@ def get(self): pages = self.get_page_count(count, 20) if self.current_user: for problem in problems: - problem.submit = self.select_last_submit_by_problem_id_member_id(problem.id) + try: + problem.submit = self.select_last_submit_by_problem_id_member_id(problem.id) + except NoResultFound: + problem.submit = None self.render("problem_list.html", locals()) class ViewTagHandler(BaseHandler, ProblemDBMixin): @@ -171,6 +175,7 @@ def get(self): submits = self.select_submit_order_by_id(10, start) pages = self.get_page_count(count) self.render("submit_list.html", locals()) +# self.db.close() class ViewSubmitHandler(BaseHandler, ProblemDBMixin): def get(self, sid): diff --git a/static/css/style.css b/static/css/style.css index 9f95f01..1ab0f15 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -3853,8 +3853,8 @@ a.nounderline:hover { -moz-border-radius: 4px; border-radius: 4px; background-color: #EEE; - padding: 4px 4px 2px 10px; - float: left; + padding: 4px 10px; + display: inline; margin-right: 4px; margin-bottom: 5px; } diff --git a/tpl/base/sidebar.html b/tpl/base/sidebar.html index 5fe898f..4ef58aa 100644 --- a/tpl/base/sidebar.html +++ b/tpl/base/sidebar.html @@ -52,13 +52,13 @@ {{ _('Submit') }} -

      ~Nbx@I`&~$@zx`w!Uoca@d}QA4 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%0AqWFXi}Jf92>9a2uQcJw0X=B_fwG@6)tl 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 ALjV8( diff --git a/static/img/glyphicons-halflings-white.png b/static/img/glyphicons-halflings-white.png deleted file mode 100644 index a20760bfde58d1c92cee95116059fba03c68d689..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4352 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 diff --git a/static/img/lines.jpg b/static/img/lines.jpg deleted file mode 100644 index d393aac718d278b3e0a532e02f9f19a318a4fcf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19856 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 RL44YHjr}SM{XPXp|JnGV)?@$x diff --git a/static/js/base.js b/static/js/base.js deleted file mode 100644 index 2429807..0000000 --- a/static/js/base.js +++ /dev/null @@ -1,5 +0,0 @@ -$(document).ready(function() { - $('.disabled').click(function() { - return false; - }); -}); diff --git a/static/js/bootstrap.min.js b/static/js/bootstrap.min.js deleted file mode 100644 index 1f295a1..0000000 --- a/static/js/bootstrap.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(a){a(function(){"use strict",a.support.transition=function(){var b=document.body||document.documentElement,c=b.style,d=c.transition!==undefined||c.WebkitTransition!==undefined||c.MozTransition!==undefined||c.MsTransition!==undefined||c.OTransition!==undefined;return d&&{end:function(){var b="TransitionEnd";return a.browser.webkit?b="webkitTransitionEnd":a.browser.mozilla?b="transitionend":a.browser.opera&&(b="oTransitionEnd"),b}()}}()})}(window.jQuery),!function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype={constructor:c,close:function(b){function f(){e.remove(),e.trigger("closed")}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),e.trigger("close"),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()}},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype={constructor:b,setState:function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},toggle:function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")}},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){a(b.target).button("toggle")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.carousel.defaults,c),this.options.slide&&this.slide(this.options.slide)};b.prototype={cycle:function(){return this.interval=setInterval(a.proxy(this.next,this),this.options.interval),this},to:function(b){var c=this.$element.find(".active"),d=c.parent().children(),e=d.index(c),f=this;if(b>d.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){f.to(b)}):e==b?this.pause().cycle():this.slide(b>e?"next":"prev",a(d[b]))},pause:function(){return clearInterval(this.interval),this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(b,c){var d=this.$element.find(".active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this;return this.sliding=!0,f&&this.pause(),e=e.length?e:this.$element.find(".item")[h](),!a.support.transition&&this.$element.hasClass("slide")?(this.$element.trigger("slide"),d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")):(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),this.$element.trigger("slide"),this.$element.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)})),f&&this.cycle(),this}},a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("carousel"),f=typeof c=="object"&&c;e||d.data("carousel",e=new b(this,f)),typeof c=="number"?e.to(c):typeof c=="string"||(c=f.slide)?e[c]():e.cycle()})},a.fn.carousel.defaults={interval:5e3},a.fn.carousel.Constructor=b,a(function(){a("body").on("click.carousel.data-api","[data-slide]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=!e.data("modal")&&a.extend({},e.data(),c.data());e.carousel(f),b.preventDefault()})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find(".in"),e;d&&d.length&&(e=d.data("collapse"),d.collapse("hide"),e||d.data("collapse",null)),this.$element[b](0),this.transition("addClass","show","shown"),this.$element[b](this.$element[0][c])},hide:function(){var a=this.dimension();this.reset(this.$element[a]()),this.transition("removeClass","hide","hidden"),this.$element[a](0)},reset:function(a){var b=this.dimension();this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element.addClass("collapse")},transition:function(b,c,d){var e=this,f=function(){c=="show"&&e.reset(),e.$element.trigger(d)};this.$element.trigger(c)[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}"use strict";var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e=c.attr("data-target"),f,g;return e||(e=c.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,"")),f=a(e),f.length||(f=c.parent()),g=f.hasClass("open"),d(),!g&&f.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('