# HG changeset patch # User Pavel Ryapolov # Date 2013-10-16 14:16:32 # Node ID 389d132112b9b0e3eebcaba5076a8252033a3466 # Parent d10da3f666793a62ecd569dacb940911cefb1d05 # Parent 0a3b13db3db6bae0214f4acefa7e7ecde153346e Merged with BB diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -1,2 +1,3 @@ bc8fce57a613175450b8b6d933cdd85f22c04658 1.1 784258eb652c563c288ca7652c33f52cd4733d83 1.1-stable +1b53a22467a8fccc798935d7a26efe78e4bc7b25 1.2-stable diff --git a/boards/authors.py b/boards/authors.py --- a/boards/authors.py +++ b/boards/authors.py @@ -1,24 +1,31 @@ +from django.utils.translation import ugettext_lazy as _ + __author__ = 'neko259' +ROLE_AUTHOR = _('author') +ROLE_DEVELOPER = _('developer') +ROLE_JS_DEV = _('javascript developer') +ROLE_DESIGNER = _('designer') + authors = { 'neko259': { 'name': 'Pavel Ryapolov', 'contacts': ['neko259@gmail.com'], - 'roles': ['author', 'developer'], + 'roles': [ROLE_AUTHOR, ROLE_DEVELOPER], }, 'ilyas': { 'name': 'Ilyas Babayev', 'contacts': ['zamesilyasa@gmail.com'], - 'roles': ['author', 'developer'], + 'roles': [ROLE_AUTHOR, ROLE_DEVELOPER], }, 'ritsufag': { 'name': 'Aiko Kirino', 'contacts': ['ritsufag@gmail.com'], - 'roles': ['javascript developer', 'designer'], + 'roles': [ROLE_JS_DEV, ROLE_DESIGNER], }, 'Tenno Seremel': { 'name': 'anonymous', 'contacts': ['html@serenareem.net'], - 'roles': ['javascript developer', 'designer'], + 'roles': [ROLE_JS_DEV, ROLE_DESIGNER], }, } \ No newline at end of file diff --git a/boards/forms.py b/boards/forms.py --- a/boards/forms.py +++ b/boards/forms.py @@ -9,6 +9,12 @@ from neboard import settings from boards import utils LAST_POST_TIME = "last_post_time" +LAST_LOGIN_TIME = "last_login_time" + +LOGIN_DELAY = 60 * 60 + +MAX_TEXT_LENGTH = 30000 +MAX_IMAGE_SIZE = 8 * 1024 * 1024 class PlainErrorList(ErrorList): @@ -41,45 +47,56 @@ class NeboardForm(forms.Form): class PostForm(NeboardForm): - MAX_TEXT_LENGTH = 30000 - MAX_IMAGE_SIZE = 8 * 1024 * 1024 + title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False, + label=_('Title')) + text = forms.CharField(widget=forms.Textarea, required=False, + label=_('Text')) + image = forms.ImageField(required=False, label=_('Image')) - title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False) - text = forms.CharField(widget=forms.Textarea, required=False) - image = forms.ImageField(required=False) + # This field is for spam prevention only + email = forms.CharField(max_length=100, required=False, label=_('e-mail'), + widget=forms.TextInput(attrs={ + 'class': 'form-email'})) session = None + need_to_ban = False def clean_title(self): title = self.cleaned_data['title'] if title: if len(title) > TITLE_MAX_LENGTH: - raise forms.ValidationError('Title must have less than' + - str(TITLE_MAX_LENGTH) + - ' characters.') + raise forms.ValidationError(_('Title must have less than %s ' + 'characters') % + str(TITLE_MAX_LENGTH)) return title def clean_text(self): text = self.cleaned_data['text'] if text: - if len(text) > self.MAX_TEXT_LENGTH: - raise forms.ValidationError('Text must have less than ' + - str(self.MAX_TEXT_LENGTH) + - ' characters.') + if len(text) > MAX_TEXT_LENGTH: + raise forms.ValidationError(_('Text must have less than %s ' + 'characters') % + str(MAX_TEXT_LENGTH)) return text def clean_image(self): image = self.cleaned_data['image'] if image: - if image._size > self.MAX_IMAGE_SIZE: - raise forms.ValidationError('Image must be less than ' + - str(self.MAX_IMAGE_SIZE) + - ' bytes.') + if image._size > MAX_IMAGE_SIZE: + raise forms.ValidationError(_('Image must be less than %s ' + 'bytes') % str(MAX_IMAGE_SIZE)) return image def clean(self): cleaned_data = super(PostForm, self).clean() + if not self.session: + raise forms.ValidationError('Humans have sessions') + + if cleaned_data['email']: + self.need_to_ban = True + raise forms.ValidationError('A human cannot enter a hidden field') + if not self.errors: self._clean_text_image() @@ -106,9 +123,8 @@ class PostForm(NeboardForm): current_delay = int(now - last_post_time) if current_delay < settings.POSTING_DELAY: - error_message = 'Wait ' + str(settings.POSTING_DELAY - - current_delay)\ - + ' seconds after last posting' + error_message = _('Wait %s seconds after last posting') % str( + settings.POSTING_DELAY - current_delay) self._errors['text'] = self.error_class([error_message]) can_post = False @@ -118,8 +134,10 @@ class PostForm(NeboardForm): class ThreadForm(PostForm): + regex_tags = re.compile(ur'^[\w\s\d]+$', re.UNICODE) - tags = forms.CharField(max_length=100) + + tags = forms.CharField(max_length=100, label=_('Tags')) def clean_tags(self): tags = self.cleaned_data['tags'] @@ -192,8 +210,11 @@ class ModeratorSettingsForm(SettingsForm class LoginForm(NeboardForm): + user_id = forms.CharField() + session = None + def clean_user_id(self): user_id = self.cleaned_data['user_id'] if user_id: @@ -203,7 +224,31 @@ class LoginForm(NeboardForm): return user_id + def _validate_login_speed(self): + can_post = True + + if LAST_LOGIN_TIME in self.session: + now = time.time() + last_login_time = self.session[LAST_LOGIN_TIME] + + current_delay = int(now - last_login_time) + + if current_delay < LOGIN_DELAY: + error_message = _('Wait %s minutes after last login') % str( + (LOGIN_DELAY - current_delay) / 60) + self._errors['user_id'] = self.error_class([error_message]) + + can_post = False + + if can_post: + self.session[LAST_LOGIN_TIME] = time.time() + def clean(self): + if not self.session: + raise forms.ValidationError('Humans have sessions') + + self._validate_login_speed() + cleaned_data = super(LoginForm, self).clean() - return cleaned_data \ No newline at end of file + return cleaned_data diff --git a/boards/locale/ru/LC_MESSAGES/django.mo b/boards/locale/ru/LC_MESSAGES/django.mo index 85f3e03ca1688517c25b0fca50235e6a9f42858c..5cbe4434140d193b752ab5d68348c76cbee6161d GIT binary patch literal 5447 zc$|$^Yit}>6~28y?8Q!O#|A=abCV`%9_)74PD`?}lWgL3V%0DF2nqzjcz0}%yPnz1 z%$gWl6x(tVdf02-o_=OM>eCM9K-gW8# zo6LOoaqhY2@trgNxaP?>1b(e}zKAFNxDW>LgC~XhML#XX)4&+;Gr&&Z7U0)`_%Bi# zhw&;0UIgv{epk!A0jvhz(sIAVs}6V%xEJ^v;OBsU2hx=x9I6Cv1BQT413v}a50tzaiKdfT=7OL33Kj?FR)%fo!_P3^*=ew%ezQfgQ&pD0X1YQ9S zRkPl|0TX0bHOI5DhUG2*8;GAZtnbHoy#)NAM#l~K6vb^j*VoSNynhtf1Dx8Ed-ge_!KrE&KnwTK415wQR@Zb-Z3z$Nuit7^`F6odiB6 z_;*C`+F4QjeMzu>>NO_?bB%aLoS;5)MsOaeCWu!FeU5CVxKIs}y*o;Dl3)Avn7BlI zqnaST>-H#~&{(IDdfCnr9pn?mtC@TeT-)?Jrja;(utc6}d8-~%ol-6i3$7)K(~ElV zD4r%gCO#5}sfQC+>-Bnr#uo&0{t%v1c%ISg#7E*V@sBus0?+e!p2gE5bpO#m$`$oh zQ7_YD6S58R-vUFYSp$&L47IPn5n`v>%$)u%k zUh>6hBkQMz3^{6KthC`kaAqS?%tzA2h5&v&iZdl17Q>B_ew_WZCkhYhKJ*D#Ns;UaVmVCTz@A zF)u9UX>*2P2i{PYC8cS{^rVe=sDO!H%g>nn{y!A=Wknw)qqSLKTzu8Ae3BWlZ1C2T z#sK7GhH{%xIV=cxX3DYC8w4oR#KQAVP8#kyc^x-GOSq&<8tJr4rVJV2qG{T)U)3AZ z?7+E{ukvi9aXZxxofU>EP|=Ty6e(SDY16X?ZKNn|j+z-Ki;;@3CoDxzF>H()Udpwy zzATDh!vwFzMMVl1bg*#3)7dUGgf7<^HdB7MH61>O5TW$qvMX`=rNo(}JeTb5Y3=L? z5p`TY-0lrp>F}xCpcn3S;xg3L*&9}T#i4MsDunuItRWmd8m_OG^|5%v3x}c&(I^DN z-R7v}73Iz+6W!tV&Tw-=p6!gcw;uXhXGbzbH5Kl44cp65EaI}IudPjXB-)d*G1;DI zZ9AE0ZthO@^c;t%J(xoX!o8+35|?d>jx&8^a${TD$&3|o+`*zuT)MeXduw~L=wU1p z4N(pd-Ei+%79v#P&u24+WgkmkRUg0Bh4D;S2;N!uj||fOP3B)KI5R1NpV2lHEs%%^ZbNpQZ_uHFx%nHgV*>LV z6i@_G1n(A1mAGk%ta?D#Lhk~uQ5MgUi*OLm$>2_Ynr)aRr?5wsPE&9pyoB&yWeey6 z+=%TZnk=idQ4o*{s9q4k+XW{nh_s_KHm5C~4A$Zzc#raf<1=JYG4N0^FM=N-D624u zoV%w&_~_*lKZ4Z~KUA#o%v0w>j%R{J%G)jF+$thCN!CCEC`0TSr=gUC@SLT#Y4+Tp; zEJ03DAeb+jWC#UGzJp`aSW+2YQ3VAdirV*!fxMZYVwSwFV$K#l!VN{sd8I2@WL_}4 z?h>gU-cppgMQqd*j>sa(DFY5f`bYLTQ*_KSthtBsa!sMf3bp_Be@kLQ_&N zlrFkqnFb$H7O0%YH!_BqiPcHUxjF{Eae}Gm-!0rloqv<1hb$-a=1ckty1=zZ*?yD1 z3i&DVUwT8~1M`V$i}McMeh=>jRWa1TmQ_e5DX43OZcsARjo~i!z*#PD?!cSqqR%B_ zIf)Z<|6AJ{w<7i3xJx>3Qg}-nzbXXvshG)MqdyrD%{lt2BX5-SU`Y~THv7=3_Am=V z-DC4`6F57rG_cE*ea@{eIDANj>cna)bc8p2sRc1?v+wPkVl}mz6;*>=9qN4t+9v2L xM|{|f`=qtl#vgH17XOMB>Z5%{oxV@C0}b?zEH<6h^-e>?q0f3rd*GfU{sURLlfM7} diff --git a/boards/locale/ru/LC_MESSAGES/django.po b/boards/locale/ru/LC_MESSAGES/django.po --- a/boards/locale/ru/LC_MESSAGES/django.po +++ b/boards/locale/ru/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-09-17 21:58+0300\n" +"POT-Creation-Date: 2013-09-22 21:35+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,30 +18,97 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: forms.py:96 +#: authors.py:5 +msgid "author" +msgstr "автор" + +#: authors.py:6 +msgid "developer" +msgstr "разработчик" + +#: authors.py:7 +msgid "javascript developer" +msgstr "разработчик javascript" + +#: authors.py:8 +msgid "designer" +msgstr "дизайнер" + +#: forms.py:51 templates/boards/posting_general.html:135 +#: templates/boards/thread.html:82 +msgid "Title" +msgstr "Заголовок" + +#: forms.py:53 templates/boards/posting_general.html:150 +#: templates/boards/thread.html:97 +msgid "Text" +msgstr "Текст" + +#: forms.py:54 templates/boards/posting_general.html:155 +#: templates/boards/thread.html:102 +msgid "Image" +msgstr "Изображение" + +#: forms.py:57 templates/boards/posting_general.html:165 +#: templates/boards/thread.html:107 +msgid "e-mail" +msgstr "" + +#: forms.py:67 +#, python-format +msgid "Title must have less than %s characters" +msgstr "Заголовок должен иметь меньше %s символов" + +#: forms.py:76 +#, python-format +msgid "Text must have less than %s characters" +msgstr "Текст должен быть короче %s символов" + +#: forms.py:85 +#, python-format +msgid "Image must be less than %s bytes" +msgstr "Изображение должно быть менее %s байт" + +#: forms.py:111 msgid "Either text or image must be entered." msgstr "Текст или картинка должны быть введены." -#: forms.py:130 +#: forms.py:124 +#, python-format +msgid "Wait %s seconds after last posting" +msgstr "Подождите %s секунд после последнего постинга" + +#: forms.py:138 templates/boards/post.html:39 +#: templates/boards/posting_general.html:77 +#: templates/boards/posting_general.html:160 templates/boards/tags.html:7 +#: templates/boards/thread.html:62 templates/boards/rss/post.html:10 +msgid "Tags" +msgstr "Теги" + +#: forms.py:146 msgid "Inappropriate characters in tags." msgstr "Недопустимые символы в тегах." -#: forms.py:158 forms.py:179 +#: forms.py:174 forms.py:195 msgid "Captcha validation failed" msgstr "Проверка капчи провалена" -#: forms.py:185 +#: forms.py:201 msgid "Theme" msgstr "Тема" -#: forms.py:190 +#: forms.py:206 msgid "Enable moderation panel" msgstr "Включить панель модерации" -#: forms.py:202 -#, fuzzy +#: forms.py:221 msgid "No such user found" -msgstr "Теги не найдены." +msgstr "Данный пользователь не найден" + +#: forms.py:235 +#, python-format +msgid "Wait %s minutes after last login" +msgstr "Подождите %s минут после последнего входа" #: templates/boards/404.html:6 msgid "Not found" @@ -71,24 +138,24 @@ msgstr "Репозиторий" msgid "Feed" msgstr "Лента" -#: templates/boards/base.html:29 +#: templates/boards/base.html:33 msgid "All threads" msgstr "Все темы" -#: templates/boards/base.html:34 +#: templates/boards/base.html:38 msgid "Tag management" msgstr "Управление тегами" -#: templates/boards/base.html:36 +#: templates/boards/base.html:40 msgid "Settings" msgstr "Настройки" -#: templates/boards/base.html:43 templates/boards/login.html:6 +#: templates/boards/base.html:47 templates/boards/login.html:6 #: templates/boards/login.html.py:21 msgid "Login" msgstr "Вход" -#: templates/boards/base.html:44 +#: templates/boards/base.html:48 msgid "Up" msgstr "Вверх" @@ -100,42 +167,38 @@ msgstr "ID пользователя" msgid "Insert your user id above" msgstr "Вставьте свой ID пользователя выше" +#: templates/boards/post.html:10 templates/boards/posting_general.html:44 +#: templates/boards/posting_general.html:100 templates/boards/thread.html:31 +#: templates/boards/rss/post.html:5 +msgid "Post image" +msgstr "Изображение сообщения" + +#: templates/boards/post.html:26 templates/boards/posting_general.html:62 +#: templates/boards/thread.html:49 +msgid "Delete" +msgstr "Удалить" + +#: templates/boards/post.html:29 templates/boards/posting_general.html:65 +#: templates/boards/thread.html:52 +msgid "Ban IP" +msgstr "Заблокировать IP" + #: templates/boards/posting_general.html:19 msgid "Tag: " msgstr "Тег: " -#: templates/boards/posting_general.html:44 -#: templates/boards/posting_general.html:100 templates/boards/thread.html:29 -#: templates/boards/rss/post.html:5 -msgid "Post image" -msgstr "Изображение сообщения" - #: templates/boards/posting_general.html:57 msgid "Reply" msgstr "Ответ" -#: templates/boards/posting_general.html:62 templates/boards/thread.html:47 -msgid "Delete" -msgstr "Удалить" - -#: templates/boards/posting_general.html:65 templates/boards/thread.html:50 -msgid "Ban IP" -msgstr "Заблокировать IP" - -#: templates/boards/posting_general.html:74 templates/boards/thread.html:116 +#: templates/boards/posting_general.html:74 templates/boards/thread.html:135 msgid "replies" msgstr "ответов" -#: templates/boards/posting_general.html:75 templates/boards/thread.html:117 +#: templates/boards/posting_general.html:75 templates/boards/thread.html:136 msgid "images" msgstr "изображений" -#: templates/boards/posting_general.html:77 -#: templates/boards/posting_general.html:150 templates/boards/tags.html:7 -#: templates/boards/thread.html:60 templates/boards/rss/post.html:10 -msgid "Tags" -msgstr "Теги" - #: templates/boards/posting_general.html:126 msgid "No threads exist. Create the first one!" msgstr "Нет тем. Создайте первую!" @@ -144,32 +207,44 @@ msgstr "Нет тем. Создайте первую!" msgid "Create new thread" msgstr "Создать новую тему" -#: templates/boards/posting_general.html:135 templates/boards/thread.html:80 -msgid "Title" -msgstr "Заголовок" +#: templates/boards/posting_general.html:140 templates/boards/thread.html:87 +msgid "Formatting" +msgstr "Форматирование" + +#: templates/boards/posting_general.html:142 templates/boards/thread.html:89 +msgid "quote" +msgstr "цитата" + +#: templates/boards/posting_general.html:143 templates/boards/thread.html:90 +msgid "italic" +msgstr "курсив" -#: templates/boards/posting_general.html:140 templates/boards/thread.html:85 -msgid "Text" -msgstr "Текст" +#: templates/boards/posting_general.html:144 templates/boards/thread.html:91 +msgid "bold" +msgstr "полужирный" -#: templates/boards/posting_general.html:145 templates/boards/thread.html:90 -msgid "Image" -msgstr "Изображение" +#: templates/boards/posting_general.html:145 templates/boards/thread.html:92 +msgid "spoiler" +msgstr "спойлер" -#: templates/boards/posting_general.html:163 templates/boards/thread.html:104 +#: templates/boards/posting_general.html:146 templates/boards/thread.html:93 +msgid "comment" +msgstr "комментарий" + +#: templates/boards/posting_general.html:178 templates/boards/thread.html:121 msgid "Post" msgstr "Отправить" -#: templates/boards/posting_general.html:165 +#: templates/boards/posting_general.html:180 msgid "Tags must be delimited by spaces. Text or image is required." msgstr "" "Теги должны быть разделены пробелами. Текст или изображение обязательны." -#: templates/boards/posting_general.html:168 templates/boards/thread.html:106 +#: templates/boards/posting_general.html:183 templates/boards/thread.html:123 msgid "Text syntax" msgstr "Синтаксис текста" -#: templates/boards/posting_general.html:178 +#: templates/boards/posting_general.html:193 msgid "Pages:" msgstr "Страницы: " @@ -205,11 +280,11 @@ msgstr "тем" msgid "No tags found." msgstr "Теги не найдены." -#: templates/boards/thread.html:77 +#: templates/boards/thread.html:79 msgid "Reply to thread" msgstr "Ответить в тему" -#: templates/boards/thread.html:118 +#: templates/boards/thread.html:137 msgid "Last update: " msgstr "Последнее обновление: " @@ -266,12 +341,6 @@ msgstr "Ссылка на сообщение" #~ msgid "Example: " #~ msgstr "Пример: " -#~ msgid "italic" -#~ msgstr "курсив" - -#~ msgid "bold" -#~ msgstr "полужирный" - #~ msgid "tags" #~ msgstr "тегов" @@ -283,15 +352,3 @@ msgstr "Ссылка на сообщение" #~ msgid "gets" #~ msgstr "гетов" - -#~ msgid "author" -#~ msgstr "автор" - -#~ msgid "developer" -#~ msgstr "разработчик" - -#~ msgid "javascript developer" -#~ msgstr "разработчик javascript" - -#~ msgid "designer" -#~ msgstr "дизайнер" diff --git a/boards/middlewares.py b/boards/middlewares.py new file mode 100644 --- /dev/null +++ b/boards/middlewares.py @@ -0,0 +1,17 @@ +from django.shortcuts import redirect +from boards import views, utils +from boards.models import Ban + + +class BanMiddleware: + """This is run before showing the thread. Banned users don't need to see + anything""" + + def process_view(self, request, view_func, view_args, view_kwargs): + + if view_func != views.you_are_banned: + ip = utils.get_client_ip(request) + is_banned = Ban.objects.filter(ip=ip).exists() + + if is_banned: + return redirect(views.you_are_banned) \ No newline at end of file diff --git a/boards/models.py b/boards/models.py --- a/boards/models.py +++ b/boards/models.py @@ -110,7 +110,7 @@ class PostManager(models.Manager): if opening_post.replies: thread = [opening_post] - thread.extend(opening_post.replies.all()) + thread.extend(opening_post.replies.all().order_by('pub_time')) return thread @@ -139,7 +139,7 @@ class PostManager(models.Manager): # must not be shown and be able for replying. threads = self.get_threads() - thread_count = len(threads) + thread_count = threads.count() if thread_count > settings.MAX_THREAD_COUNT: num_threads_to_delete = thread_count - settings.MAX_THREAD_COUNT @@ -269,7 +269,7 @@ class Post(models.Model): if reply_count > 0: reply_count_to_show = min(settings.LAST_REPLIES_COUNT, reply_count) - last_replies = self.replies.all()[reply_count - + last_replies = self.replies.all().order_by('pub_time')[reply_count - reply_count_to_show:] return last_replies diff --git a/boards/rss.py b/boards/rss.py --- a/boards/rss.py +++ b/boards/rss.py @@ -6,8 +6,6 @@ from neboard import settings __author__ = 'neko259' -MAX_ITEMS = 20 - # TODO Make tests for all of these class AllThreadsFeed(Feed): @@ -16,7 +14,7 @@ class AllThreadsFeed(Feed): description_template = 'boards/rss/post.html' def items(self): - return Post.objects.get_threads(order_by='-pub_time')[:MAX_ITEMS] + return Post.objects.get_threads(order_by='-pub_time') def item_title(self, item): return item.title @@ -35,7 +33,7 @@ class TagThreadsFeed(Feed): def items(self, obj): return Post.objects.get_threads(tag=obj, - order_by='-pub_time')[:MAX_ITEMS] + order_by='-pub_time') def get_object(self, request, tag_name): return get_object_or_404(Tag, name=tag_name) @@ -59,7 +57,7 @@ class ThreadPostsFeed(Feed): description_template = 'boards/rss/post.html' def items(self, obj): - return Post.objects.get_thread(opening_post_id=obj)[:MAX_ITEMS] + return Post.objects.get_thread(opening_post_id=obj) def get_object(self, request, post_id): return post_id @@ -69,7 +67,7 @@ class ThreadPostsFeed(Feed): def item_link(self, item): if item.thread: - return reverse('thread', args={item.parent}) + "#" + str(item.id) + return reverse('thread', args={item.thread.id}) + "#" + str(item.id) else: return reverse('thread', args={item.id}) @@ -77,4 +75,4 @@ class ThreadPostsFeed(Feed): return item.pub_time def title(self, obj): - return get_object_or_404(Post, id=obj).title \ No newline at end of file + return get_object_or_404(Post, id=obj).title diff --git a/boards/static/css/base.css b/boards/static/css/base.css new file mode 100644 --- /dev/null +++ b/boards/static/css/base.css @@ -0,0 +1,20 @@ +.ui-button { + display: none; +} + +.ui-dialog-content { + padding: 0; + min-height: 0; +} + +.mark_btn { + cursor: pointer; +} + +.img-full { + position: fixed; + z-index: 9999; + background-color: #CCC; + border: 1px solid #000; + cursor: pointer; +} \ No newline at end of file diff --git a/boards/static/css/fancybox_loading.gif b/boards/static/css/fancybox_loading.gif deleted file mode 100644 index 01586176d793c261db6b6ca4ca7822b2d3b35703..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ .post, #posts > .post { - border-bottom: 1px solid #182F6F; - padding-bottom: 1em; -} + #posts > .post:last-child { border-bottom: none; padding-bottom: 0; @@ -223,15 +224,10 @@ li { } .thread > .post > .message > .post-info { - border-bottom: 2px solid #182F6F; + border-bottom: 1px solid #ccc; padding-bottom: .5em; } -.last-replies > .post:last-child { - border-bottom: none; - padding-bottom: 0; -} - :target .post_id { background: #182F6F; color: #FFF; @@ -284,4 +280,8 @@ li { .role { text-decoration: underline; -} \ No newline at end of file +} + +.form-email { + display: none; +} diff --git a/boards/static/js/image.js b/boards/static/js/image.js new file mode 100644 --- /dev/null +++ b/boards/static/js/image.js @@ -0,0 +1,71 @@ +function addImgPreview() { + var margin = 20; //..change + + //keybind + $(document).on('keyup.removepic', function(e) { + if(e.which === 27) { + $('.img-full').remove(); + } + }); + + $('body').on('click', '.thumb', function() { + var el = $(this); + var thumb_id = 'full' + el.find('img').attr('alt'); + + if(!$('#'+thumb_id).length) { + var img_w = el.find('img').attr('data-width'); + var img_h = el.find('img').attr('data-height'); + + var win_w = $(window).width(); + var win_h = $(window).height(); + //new image size + if (img_w > win_w) { + img_h = img_h * (win_w/img_w) - margin; + img_w = win_w - margin; + } + if (img_h > win_h) { + img_w = img_w * (win_h/img_h) - margin; + img_h = win_h - margin; + } + + var img_pv = new Image(); + $(img_pv) + .addClass('img-full') + .attr('id', thumb_id) + .attr('src', $(el).attr('href')) + .appendTo($(el)) + .css({ + 'width': img_w, + 'height': img_h, + 'left': (win_w - img_w) / 2, + 'top': ((win_h - img_h) / 2) + }) + //scaling preview + .mousewheel(function(event, delta) { + var cx = event.originalEvent.clientX, + cy = event.originalEvent.clientY, + i_w = parseFloat($(img_pv).width()), + i_h = parseFloat($(img_pv).height()), + newIW = i_w * (delta > 0 ? 1.25 : 0.8), + newIH = i_h * (delta > 0 ? 1.25 : 0.8); + + $(img_pv).width(newIW); + $(img_pv).height(newIH); + //set position + $(img_pv) + .css({ + left: parseInt(cx - (newIW/i_w) * (cx - parseInt($(img_pv).position().left, 10)), 10), + top: parseInt(cy - (newIH/i_h) * (cy - parseInt($(img_pv).position().top, 10)), 10) + }); + + return false; + } + ).draggable() + } + else { + $('#'+thumb_id).remove(); + } + //prevent default + return false; + }); +} \ No newline at end of file diff --git a/boards/static/js/jquery-ui-1.10.3.custom.min.js b/boards/static/js/jquery-ui-1.10.3.custom.min.js new file mode 100644 --- /dev/null +++ b/boards/static/js/jquery-ui-1.10.3.custom.min.js @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.10.3 - 2013-09-21 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.resizable.js, jquery.ui.button.js, jquery.ui.dialog.js +* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ + +(function(e,t){function i(t,i){var s,a,o,r=t.nodeName.toLowerCase();return"area"===r?(s=t.parentNode,a=s.name,t.href&&a&&"map"===s.nodeName.toLowerCase()?(o=e("img[usemap=#"+a+"]")[0],!!o&&n(o)):!1):(/input|select|textarea|button|object/.test(r)?!t.disabled:"a"===r?t.href||i:i)&&n(t)}function n(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var s=0,a=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,n){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),n&&n.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var n,s,a=e(this[0]);a.length&&a[0]!==document;){if(n=a.css("position"),("absolute"===n||"relative"===n||"fixed"===n)&&(s=parseInt(a.css("zIndex"),10),!isNaN(s)&&0!==s))return s;a=a.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++s)})},removeUniqueId:function(){return this.each(function(){a.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,n){return!!e.data(t,n[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),s=isNaN(n);return(s||n>=0)&&i(t,!s)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(i,n){function s(t,i,n,s){return e.each(a,function(){i-=parseFloat(e.css(t,"padding"+this))||0,n&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var a="Width"===n?["Left","Right"]:["Top","Bottom"],o=n.toLowerCase(),r={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+n]=function(i){return i===t?r["inner"+n].call(this):this.each(function(){e(this).css(o,s(this,i)+"px")})},e.fn["outer"+n]=function(t,i){return"number"!=typeof t?r["outer"+n].call(this,t):this.each(function(){e(this).css(o,s(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,n){var s,a=e.ui[t].prototype;for(s in n)a.plugins[s]=a.plugins[s]||[],a.plugins[s].push([i,n[s]])},call:function(e,t,i){var n,s=e.plugins[t];if(s&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(n=0;s.length>n;n++)e.options[s[n][0]]&&s[n][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var n=i&&"left"===i?"scrollLeft":"scrollTop",s=!1;return t[n]>0?!0:(t[n]=1,s=t[n]>0,t[n]=0,s)}})})(jQuery);(function(t,e){var i=0,s=Array.prototype.slice,n=t.cleanData;t.cleanData=function(e){for(var i,s=0;null!=(i=e[s]);s++)try{t(i).triggerHandler("remove")}catch(o){}n(e)},t.widget=function(i,s,n){var o,a,r,h,l={},c=i.split(".")[0];i=i.split(".")[1],o=c+"-"+i,n||(n=s,s=t.Widget),t.expr[":"][o.toLowerCase()]=function(e){return!!t.data(e,o)},t[c]=t[c]||{},a=t[c][i],r=t[c][i]=function(t,i){return this._createWidget?(arguments.length&&this._createWidget(t,i),e):new r(t,i)},t.extend(r,a,{version:n.version,_proto:t.extend({},n),_childConstructors:[]}),h=new s,h.options=t.widget.extend({},h.options),t.each(n,function(i,n){return t.isFunction(n)?(l[i]=function(){var t=function(){return s.prototype[i].apply(this,arguments)},e=function(t){return s.prototype[i].apply(this,t)};return function(){var i,s=this._super,o=this._superApply;return this._super=t,this._superApply=e,i=n.apply(this,arguments),this._super=s,this._superApply=o,i}}(),e):(l[i]=n,e)}),r.prototype=t.widget.extend(h,{widgetEventPrefix:a?h.widgetEventPrefix:i},l,{constructor:r,namespace:c,widgetName:i,widgetFullName:o}),a?(t.each(a._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,r,i._proto)}),delete a._childConstructors):s._childConstructors.push(r),t.widget.bridge(i,r)},t.widget.extend=function(i){for(var n,o,a=s.call(arguments,1),r=0,h=a.length;h>r;r++)for(n in a[r])o=a[r][n],a[r].hasOwnProperty(n)&&o!==e&&(i[n]=t.isPlainObject(o)?t.isPlainObject(i[n])?t.widget.extend({},i[n],o):t.widget.extend({},o):o);return i},t.widget.bridge=function(i,n){var o=n.prototype.widgetFullName||i;t.fn[i]=function(a){var r="string"==typeof a,h=s.call(arguments,1),l=this;return a=!r&&h.length?t.widget.extend.apply(null,[a].concat(h)):a,r?this.each(function(){var s,n=t.data(this,o);return n?t.isFunction(n[a])&&"_"!==a.charAt(0)?(s=n[a].apply(n,h),s!==n&&s!==e?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):e):t.error("no such method '"+a+"' for "+i+" widget instance"):t.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+a+"'")}):this.each(function(){var e=t.data(this,o);e?e.option(a||{})._init():t.data(this,o,new n(a,this))}),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this.bindings=t(),this.hoverable=t(),this.focusable=t(),s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(i,s){var n,o,a,r=i;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof i)if(r={},n=i.split("."),i=n.shift(),n.length){for(o=r[i]=t.widget.extend({},this.options[i]),a=0;n.length-1>a;a++)o[n[a]]=o[n[a]]||{},o=o[n[a]];if(i=n.pop(),s===e)return o[i]===e?null:o[i];o[i]=s}else{if(s===e)return this.options[i]===e?null:this.options[i];r[i]=s}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return this.options[t]=e,"disabled"===t&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!e).attr("aria-disabled",e),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var o,a=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=o=t(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,o=this.widget()),t.each(n,function(n,r){function h(){return i||a.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?a[r]:r).apply(a,arguments):e}"string"!=typeof r&&(h.guid=r.guid=r.guid||h.guid||t.guid++);var l=n.match(/^(\w+)\s*(.*)$/),c=l[1]+a.eventNamespace,u=l[2];u?o.delegate(u,c,h):s.bind(c,h)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(e).undelegate(e)},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){t(e.currentTarget).addClass("ui-state-hover")},mouseleave:function(e){t(e.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){t(e.currentTarget).addClass("ui-state-focus")},focusout:function(e){t(e.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}})})(jQuery);(function(t){var e=!1;t(document).mouseup(function(){e=!1}),t.widget("ui.mouse",{version:"1.10.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.bind("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).bind("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!e){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,a="string"==typeof this.options.cancel&&i.target.nodeName?t(i.target).closest(this.options.cancel).length:!1;return n&&!a&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===t.data(i.target,this.widgetName+".preventClickEvent")&&t.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return s._mouseMove(t)},this._mouseUpDelegate=function(t){return s._mouseUp(t)},t(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),e=!0,!0)):!0}},_mouseMove:function(e){return t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button?this._mouseUp(e):this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){return t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),!1},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(t,e){function i(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function s(e,i){return parseInt(t.css(e,i),10)||0}function n(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}t.ui=t.ui||{};var a,o=Math.max,r=Math.abs,l=Math.round,h=/left|center|right/,c=/top|center|bottom/,u=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(a!==e)return a;var i,s,n=t("
"),o=n.children()[0];return t("body").append(n),i=o.offsetWidth,n.css("overflow","scroll"),s=o.offsetWidth,i===s&&(s=n[0].clientWidth),n.remove(),a=i-s},getScrollInfo:function(e){var i=e.isWindow?"":e.element.css("overflow-x"),s=e.isWindow?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widths?"left":i>0?"right":"center",vertical:0>a?"top":n>0?"bottom":"middle"};u>p&&p>r(i+s)&&(l.horizontal="center"),d>g&&g>r(n+a)&&(l.vertical="middle"),l.important=o(r(i),r(s))>o(r(n),r(a))?"horizontal":"vertical",e.using.call(this,t,l)}),c.offset(t.extend(M,{using:h}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,l=n-r,h=r+e.collisionWidth-a-n;e.collisionWidth>a?l>0&&0>=h?(i=t.left+l+e.collisionWidth-a-n,t.left+=l-i):t.left=h>0&&0>=l?n:l>h?n+a-e.collisionWidth:n:l>0?t.left+=l:h>0?t.left-=h:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,l=n-r,h=r+e.collisionHeight-a-n;e.collisionHeight>a?l>0&&0>=h?(i=t.top+l+e.collisionHeight-a-n,t.top+=l-i):t.top=h>0&&0>=l?n:l>h?n+a-e.collisionHeight:n:l>0?t.top+=l:h>0?t.top-=h:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,a=n.offset.left+n.scrollLeft,o=n.width,l=n.isWindow?n.scrollLeft:n.offset.left,h=t.left-e.collisionPosition.marginLeft,c=h-l,u=h+e.collisionWidth-o-l,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-o-a,(0>i||r(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-l,(s>0||u>r(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,a=n.offset.top+n.scrollTop,o=n.height,l=n.isWindow?n.scrollTop:n.offset.top,h=t.top-e.collisionPosition.marginTop,c=h-l,u=h+e.collisionHeight-o-l,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-o-a,t.top+p+f+g>c&&(0>s||r(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-l,t.top+p+f+g>u&&(i>0||u>r(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}},function(){var e,i,s,n,a,o=document.getElementsByTagName("body")[0],r=document.createElement("div");e=document.createElement(o?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&t.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(a in s)e.style[a]=s[a];e.appendChild(r),i=o||document.documentElement,i.insertBefore(e,i.firstChild),r.style.cssText="position: absolute; left: 10.7432222px;",n=t(r).offset().left,t.support.offsetFractions=n>10&&11>n,e.innerHTML="",i.removeChild(e)}()})(jQuery);(function(t){t.widget("ui.draggable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(t(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){t("
").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(t(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_mouseDrag:function(e,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"original"!==this.options.helper||t.contains(this.element[0].ownerDocument,this.element[0])?("invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1):!1},_mouseUp:function(e){return t("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.element.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;return n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):"document"===n.containment?(this.containment=[0,0,t(document).width()-this.helperProportions.width-this.margins.left,(t(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):n.containment.constructor===Array?(this.containment=n.containment,undefined):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),undefined):(this.containment=null,undefined)},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent;return this.offset.scroll||(this.offset.scroll={top:n.scrollTop(),left:n.scrollLeft()}),{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top)*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)*s}},_generatePosition:function(e){var i,s,n,a,o=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,l=e.pageX,h=e.pageY;return this.offset.scroll||(this.offset.scroll={top:r.scrollTop(),left:r.scrollLeft()}),this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.lefti[2]&&(l=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(h=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,h=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,l=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a)),{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s]),"drag"===e&&(this.positionAbs=this._convertPositionTo("absolute")),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i){var s=t(this).data("ui-draggable"),n=s.options,a=t.extend({},i,{item:s.element});s.sortables=[],t(n.connectToSortable).each(function(){var i=t.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",e,a))})},stop:function(e,i){var s=t(this).data("ui-draggable"),n=t.extend({},i,{item:s.element});t.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(e),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",e,n))})},drag:function(e,i){var s=t(this).data("ui-draggable"),n=this;t.each(s.sortables,function(){var a=!1,o=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(a=!0,t.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&t.contains(o.instance.element[0],this.instance.element[0])&&(a=!1),a})),a?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=t(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},e.target=this.instance.currentItem[0],this.instance._mouseCapture(e,!0),this.instance._mouseStart(e,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",e),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(e)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",e,this.instance._uiHash(this.instance)),this.instance._mouseStop(e,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",e),s.dropped=!1)})}}),t.ui.plugin.add("draggable","cursor",{start:function(){var e=t("body"),i=t(this).data("ui-draggable").options;e.css("cursor")&&(i._cursor=e.css("cursor")),e.css("cursor",i.cursor)},stop:function(){var e=t(this).data("ui-draggable").options;e._cursor&&t("body").css("cursor",e._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._opacity&&t(i.helper).css("opacity",s._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(){var e=t(this).data("ui-draggable");e.scrollParent[0]!==document&&"HTML"!==e.scrollParent[0].tagName&&(e.overflowOffset=e.scrollParent.offset())},drag:function(e){var i=t(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-e.pageY=0;u--)r=p.snapElements[u].left,l=r+p.snapElements[u].width,h=p.snapElements[u].top,c=h+p.snapElements[u].height,r-f>_||m>l+f||h-f>b||v>c+f||!t.contains(p.snapElements[u].item.ownerDocument,p.snapElements[u].item)?(p.snapElements[u].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=!1):("inner"!==g.snapMode&&(s=f>=Math.abs(h-b),n=f>=Math.abs(c-v),a=f>=Math.abs(r-_),o=f>=Math.abs(l-m),s&&(i.position.top=p._convertPositionTo("relative",{top:h-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:l}).left-p.margins.left)),d=s||n||a||o,"outer"!==g.snapMode&&(s=f>=Math.abs(h-v),n=f>=Math.abs(c-b),a=f>=Math.abs(r-m),o=f>=Math.abs(l-_),s&&(i.position.top=p._convertPositionTo("relative",{top:h,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c-p.helperProportions.height,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:l-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[u].snapping&&(s||n||a||o||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=s||n||a||o||d)}}),t.ui.plugin.add("draggable","stack",{start:function(){var e,i=this.data("ui-draggable").options,s=t.makeArray(t(i.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});s.length&&(e=parseInt(t(s[0]).css("zIndex"),10)||0,t(s).each(function(i){t(this).css("zIndex",e+i)}),this.css("zIndex",e+s.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._zIndex&&t(i.helper).css("zIndex",s._zIndex)}})})(jQuery);(function(t){function e(t){return parseInt(t,10)||0}function i(t){return!isNaN(parseInt(t,10))}t.widget("ui.resizable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var e,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(t("
").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("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,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=r.handles||(t(".ui-resizable-handle",this.element).length?{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"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),e=this.handles.split(","),this.handles={},i=0;e.length>i;i++)s=t.trim(e[i]),a="ui-resizable-"+s,n=t("
"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(e){var i,s,n,a;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=t(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=t(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,a),this._proportionallyResize()),t(this.handles[i]).length},this._renderAxis(this.element),this._handles=t(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),t(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(t(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(t(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,a,o=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=e(this.helper.css("left")),n=e(this.helper.css("top")),o.containment&&(s+=t(o.containment).scrollLeft()||0,n+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,a=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===a?this.axis+"-resize":a),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(e){var i,s=this.helper,n={},a=this.originalMousePosition,o=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,c=this.size.height,u=e.pageX-a.left||0,d=e.pageY-a.top||0,p=this._change[o];return p?(i=p.apply(this,[e,u,d]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==c&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(n)||this._trigger("resize",e,this.ui()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&t.ui.hasScroll(i[0],"left")?0:c.sizeDiff.height,a=s?0:c.sizeDiff.width,o={width:c.helper.width()-a,height:c.helper.height()-n},r=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null,h=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(o,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(t){var e,s,n,a,o,r=this.options;o={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,n=o.minWidth/this.aspectRatio,s=o.maxHeight*this.aspectRatio,a=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),n>o.minHeight&&(o.minHeight=n),o.maxWidth>s&&(o.maxWidth=s),o.maxHeight>a&&(o.maxHeight=a)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),i(t.left)&&(this.position.left=t.left),i(t.top)&&(this.position.top=t.top),i(t.height)&&(this.size.height=t.height),i(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,s=this.size,n=this.axis;return i(t.height)?t.width=t.height*this.aspectRatio:i(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===n&&(t.left=e.left+(s.width-t.width),t.top=null),"nw"===n&&(t.top=e.top+(s.height-t.height),t.left=e.left+(s.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,s=this.axis,n=i(t.width)&&e.maxWidth&&e.maxWidtht.width,r=i(t.height)&&e.minHeight&&e.minHeight>t.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,c=/sw|nw|w/.test(s),u=/nw|ne|n/.test(s);return o&&(t.width=e.minWidth),r&&(t.height=e.minHeight),n&&(t.width=e.maxWidth),a&&(t.height=e.maxHeight),o&&c&&(t.left=h-e.minWidth),n&&c&&(t.left=h-e.maxWidth),r&&u&&(t.top=l-e.minHeight),a&&u&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var t,e,i,s,n,a=this.helper||this.element;for(t=0;this._proportionallyResizeElements.length>t;t++){if(n=this._proportionallyResizeElements[t],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],e=0;i.length>e;e++)this.borderDif[e]=(parseInt(i[e],10)||0)+(parseInt(s[e],10)||0);n.css({height:a.height()-this.borderDif[0]-this.borderDif[2]||0,width:a.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,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}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&t.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,c=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,a,o,r,h,l=t(this).data("ui-resizable"),c=l.options,u=l.element,d=c.containment,p=d instanceof t?d.get(0):/parent/.test(d)?u.parent().get(0):d;p&&(l.containerElement=t(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(i=t(p),s=[],t(["Top","Right","Left","Bottom"]).each(function(t,n){s[t]=e(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,a=l.containerSize.height,o=l.containerSize.width,r=t.ui.hasScroll(p,"left")?p.scrollWidth:o,h=t.ui.hasScroll(p)?p.scrollHeight:a,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(e){var i,s,n,a,o=t(this).data("ui-resizable"),r=o.options,h=o.containerOffset,l=o.position,c=o._aspectRatio||e.shiftKey,u={top:0,left:0},d=o.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-u.left),c&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),c&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?h.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,i=Math.abs((o._helper?o.offset.left-u.left:o.offset.left-u.left)+o.sizeDiff.width),s=Math.abs((o._helper?o.offset.top-u.top:o.offset.top-h.top)+o.sizeDiff.height),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a&&(i-=o.parentData.left),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,c&&(o.size.height=o.size.width/o.aspectRatio)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,c&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.containerOffset,n=e.containerPosition,a=e.containerElement,o=t(e.helper),r=o.offset(),h=o.outerWidth()-e.sizeDiff.width,l=o.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(a.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(a.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=function(e){t(e).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseInt(e.width(),10),height:parseInt(e.height(),10),left:parseInt(e.css("left"),10),top:parseInt(e.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):t.each(i.alsoResize,function(t){s(t)})},resize:function(e,i){var s=t(this).data("ui-resizable"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0},h=function(e,s){t(e).each(function(){var e=t(this),n=t(this).data("ui-resizable-alsoresize"),a={},o=s&&s.length?s:e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(n[e]||0)+(r[e]||0);i&&i>=0&&(a[e]=i||null)}),e.css(a)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):t.each(n.alsoResize,function(t,e){h(t,e)})},stop:function(){t(this).removeData("resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).data("ui-resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).data("ui-resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size,n=e.originalSize,a=e.originalPosition,o=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,c=Math.round((s.width-n.width)/h)*h,u=Math.round((s.height-n.height)/l)*l,d=n.width+c,p=n.height+u,f=i.maxWidth&&d>i.maxWidth,g=i.maxHeight&&p>i.maxHeight,m=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,m&&(d+=h),v&&(p+=l),f&&(d-=h),g&&(p-=l),/^(se|s|e)$/.test(o)?(e.size.width=d,e.size.height=p):/^(ne)$/.test(o)?(e.size.width=d,e.size.height=p,e.position.top=a.top-u):/^(sw)$/.test(o)?(e.size.width=d,e.size.height=p,e.position.left=a.left-c):(e.size.width=d,e.size.height=p,e.position.top=a.top-u,e.position.left=a.left-c)}})})(jQuery);(function(e){var t,i,n,s,a="ui-button ui-widget ui-state-default ui-corner-all",o="ui-state-hover ui-state-active ",r="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",h=function(){var t=e(this);setTimeout(function(){t.find(":ui-button").button("refresh")},1)},u=function(t){var i=t.name,n=t.form,s=e([]);return i&&(i=i.replace(/'/g,"\\'"),s=n?e(n).find("[name='"+i+"']"):e("[name='"+i+"']",t.ownerDocument).filter(function(){return!this.form})),s};e.widget("ui.button",{version:"1.10.3",defaultElement:"").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html(" "),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("
").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("
").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),e.isEmptyObject(i)||e.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(e.each(i,function(i,a){var s,n;a=e.isFunction(a)?{click:a,text:i}:a,a=e.extend({type:"button"},a),s=a.click,a.click=function(){s.apply(t.element[0],arguments)},n={icons:a.icons,text:a.showText},delete a.icons,delete a.showText,e("",a).button(n).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function t(e){return{position:e.position,offset:e.offset}}var i=this,a=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(a,s){e(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",a,t(s))},drag:function(e,a){i._trigger("drag",e,t(a))},stop:function(s,n){a.position=[n.position.left-i.document.scrollLeft(),n.position.top-i.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",s,t(n))}})},_makeResizable:function(){function t(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var i=this,a=this.options,s=a.resizable,n=this.uiDialog.css("position"),r="string"==typeof s?s:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:a.maxWidth,maxHeight:a.maxHeight,minWidth:a.minWidth,minHeight:this._minHeight(),handles:r,start:function(a,s){e(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",a,t(s))},resize:function(e,a){i._trigger("resize",e,t(a))},stop:function(s,n){a.height=e(this).height(),a.width=e(this).width(),e(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",s,t(n))}}).css("position",n)},_minHeight:function(){var e=this.options;return"auto"===e.height?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(a){var s=this,n=!1,r={};e.each(a,function(e,a){s._setOption(e,a),e in t&&(n=!0),e in i&&(r[e]=a)}),n&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",r)},_setOption:function(e,t){var i,a,s=this.uiDialog;"dialogClass"===e&&s.removeClass(this.options.dialogClass).addClass(t),"disabled"!==e&&(this._super(e,t),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:""+t}),"draggable"===e&&(i=s.is(":data(ui-draggable)"),i&&!t&&s.draggable("destroy"),!i&&t&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(a=s.is(":data(ui-resizable)"),a&&!t&&s.resizable("destroy"),a&&"string"==typeof t&&s.resizable("option","handles",t),a||t===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var e,t,i,a=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),a.minWidth>a.width&&(a.width=a.minWidth),e=this.uiDialog.css({height:"auto",width:a.width}).outerHeight(),t=Math.max(0,a.minHeight-e),i="number"==typeof a.maxHeight?Math.max(0,a.maxHeight-e):"none","auto"===a.height?this.element.css({minHeight:t,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,a.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("
").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return e(t.target).closest(".ui-dialog").length?!0:!!e(t.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var t=this,i=this.widgetFullName;e.ui.dialog.overlayInstances||this._delay(function(){e.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(a){t._allowInteraction(a)||(a.preventDefault(),e(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=e("
").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),e.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(e.ui.dialog.overlayInstances--,e.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),e.ui.dialog.overlayInstances=0,e.uiBackCompat!==!1&&e.widget("ui.dialog",e.ui.dialog,{_position:function(){var t,i=this.options.position,a=[],s=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(a=i.split?i.split(" "):[i[0],i[1]],1===a.length&&(a[1]=a[0]),e.each(["left","top"],function(e,t){+a[e]===a[e]&&(s[e]=a[e],a[e]=t)}),i={my:a[0]+(0>s[0]?s[0]:"+"+s[0])+" "+a[1]+(0>s[1]?s[1]:"+"+s[1]),at:a.join(" ")}),i=e.extend({},e.ui.dialog.prototype.options.position,i)):i=e.ui.dialog.prototype.options.position,t=this.uiDialog.is(":visible"),t||this.uiDialog.show(),this.uiDialog.position(i),t||this.uiDialog.hide()}})})(jQuery); \ No newline at end of file diff --git a/boards/static/js/jquery.fancybox.pack.js b/boards/static/js/jquery.fancybox.pack.js deleted file mode 100755 --- a/boards/static/js/jquery.fancybox.pack.js +++ /dev/null @@ -1,45 +0,0 @@ -/*! fancyBox v2.1.4 fancyapps.com | fancyapps.com/fancybox/#license */ -(function(C,z,f,r){var q=f(C),n=f(z),b=f.fancybox=function(){b.open.apply(this,arguments)},H=navigator.userAgent.match(/msie/),w=null,s=z.createTouch!==r,t=function(a){return a&&a.hasOwnProperty&&a instanceof f},p=function(a){return a&&"string"===f.type(a)},F=function(a){return p(a)&&0
',image:'',iframe:'",error:'

The requested content cannot be loaded.
Please try again later.

',closeBtn:'
',next:'',prev:''},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0, -openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:f.noop,beforeLoad:f.noop,afterLoad:f.noop,beforeShow:f.noop,afterShow:f.noop,beforeChange:f.noop,beforeClose:f.noop,afterClose:f.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1, -isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(a,d){if(a&&(f.isPlainObject(d)||(d={}),!1!==b.close(!0)))return f.isArray(a)||(a=t(a)?f(a).get():[a]),f.each(a,function(e,c){var k={},g,h,j,m,l;"object"===f.type(c)&&(c.nodeType&&(c=f(c)),t(c)?(k={href:c.data("fancybox-href")||c.attr("href"),title:c.data("fancybox-title")||c.attr("title"),isDom:!0,element:c},f.metadata&&f.extend(!0,k, -c.metadata())):k=c);g=d.href||k.href||(p(c)?c:null);h=d.title!==r?d.title:k.title||"";m=(j=d.content||k.content)?"html":d.type||k.type;!m&&k.isDom&&(m=c.data("fancybox-type"),m||(m=(m=c.prop("class").match(/fancybox\.(\w+)/))?m[1]:null));p(g)&&(m||(b.isImage(g)?m="image":b.isSWF(g)?m="swf":"#"===g.charAt(0)?m="inline":p(c)&&(m="html",j=c)),"ajax"===m&&(l=g.split(/\s+/,2),g=l.shift(),l=l.shift()));j||("inline"===m?g?j=f(p(g)?g.replace(/.*(?=#[^\s]+$)/,""):g):k.isDom&&(j=c):"html"===m?j=g:!m&&(!g&& -k.isDom)&&(m="inline",j=c));f.extend(k,{href:g,type:m,content:j,title:h,selector:l});a[e]=k}),b.opts=f.extend(!0,{},b.defaults,d),d.keys!==r&&(b.opts.keys=d.keys?f.extend({},b.defaults.keys,d.keys):!1),b.group=a,b._start(b.opts.index)},cancel:function(){var a=b.coming;a&&!1!==b.trigger("onCancel")&&(b.hideLoading(),b.ajaxLoad&&b.ajaxLoad.abort(),b.ajaxLoad=null,b.imgPreload&&(b.imgPreload.onload=b.imgPreload.onerror=null),a.wrap&&a.wrap.stop(!0,!0).trigger("onReset").remove(),b.coming=null,b.current|| -b._afterZoomOut(a))},close:function(a){b.cancel();!1!==b.trigger("beforeClose")&&(b.unbindEvents(),b.isActive&&(!b.isOpen||!0===a?(f(".fancybox-wrap").stop(!0).trigger("onReset").remove(),b._afterZoomOut()):(b.isOpen=b.isOpened=!1,b.isClosing=!0,f(".fancybox-item, .fancybox-nav").remove(),b.wrap.stop(!0,!0).removeClass("fancybox-opened"),b.transitions[b.current.closeMethod]())))},play:function(a){var d=function(){clearTimeout(b.player.timer)},e=function(){d();b.current&&b.player.isActive&&(b.player.timer= -setTimeout(b.next,b.current.playSpeed))},c=function(){d();f("body").unbind(".player");b.player.isActive=!1;b.trigger("onPlayEnd")};if(!0===a||!b.player.isActive&&!1!==a){if(b.current&&(b.current.loop||b.current.index=c.index?"next":"prev"],b.router=e||"jumpto",c.loop&&(0>a&&(a=c.group.length+a%c.group.length),a%=c.group.length),c.group[a]!==r&&(b.cancel(),b._start(a)))},reposition:function(a,d){var e=b.current,c=e?e.wrap:null,k;c&&(k=b._getPosition(d),a&&"scroll"===a.type?(delete k.position,c.stop(!0,!0).animate(k,200)):(c.css(k),e.pos=f.extend({}, -e.dim,k)))},update:function(a){var d=a&&a.type,e=!d||"orientationchange"===d;e&&(clearTimeout(w),w=null);b.isOpen&&!w&&(w=setTimeout(function(){var c=b.current;c&&!b.isClosing&&(b.wrap.removeClass("fancybox-tmp"),(e||"load"===d||"resize"===d&&c.autoResize)&&b._setDimension(),"scroll"===d&&c.canShrink||b.reposition(a),b.trigger("onUpdate"),w=null)},e&&!s?0:300))},toggle:function(a){b.isOpen&&(b.current.fitToView="boolean"===f.type(a)?a:!b.current.fitToView,s&&(b.wrap.removeAttr("style").addClass("fancybox-tmp"), -b.trigger("onUpdate")),b.update())},hideLoading:function(){n.unbind(".loading");f("#fancybox-loading").remove()},showLoading:function(){var a,d;b.hideLoading();a=f('
').click(b.cancel).appendTo("body");n.bind("keydown.loading",function(a){if(27===(a.which||a.keyCode))a.preventDefault(),b.cancel()});b.defaults.fixed||(d=b.getViewport(),a.css({position:"absolute",top:0.5*d.h+d.y,left:0.5*d.w+d.x}))},getViewport:function(){var a=b.current&&b.current.locked|| -!1,d={x:q.scrollLeft(),y:q.scrollTop()};a?(d.w=a[0].clientWidth,d.h=a[0].clientHeight):(d.w=s&&C.innerWidth?C.innerWidth:q.width(),d.h=s&&C.innerHeight?C.innerHeight:q.height());return d},unbindEvents:function(){b.wrap&&t(b.wrap)&&b.wrap.unbind(".fb");n.unbind(".fb");q.unbind(".fb")},bindEvents:function(){var a=b.current,d;a&&(q.bind("orientationchange.fb"+(s?"":" resize.fb")+(a.autoCenter&&!a.locked?" scroll.fb":""),b.update),(d=a.keys)&&n.bind("keydown.fb",function(e){var c=e.which||e.keyCode,k= -e.target||e.srcElement;if(27===c&&b.coming)return!1;!e.ctrlKey&&(!e.altKey&&!e.shiftKey&&!e.metaKey&&(!k||!k.type&&!f(k).is("[contenteditable]")))&&f.each(d,function(d,k){if(1h[0].clientWidth||h[0].clientHeight&&h[0].scrollHeight>h[0].clientHeight),h=f(h).parent();if(0!==c&&!j&&1g||0>k)b.next(0>g?"up":"right");d.preventDefault()}}))},trigger:function(a,d){var e,c=d||b.coming||b.current;if(c){f.isFunction(c[a])&&(e=c[a].apply(c,Array.prototype.slice.call(arguments,1)));if(!1===e)return!1;c.helpers&&f.each(c.helpers,function(d, -e){e&&(b.helpers[d]&&f.isFunction(b.helpers[d][a]))&&(e=f.extend(!0,{},b.helpers[d].defaults,e),b.helpers[d][a](e,c))});f.event.trigger(a+".fb")}},isImage:function(a){return p(a)&&a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp)((\?|#).*)?$)/i)},isSWF:function(a){return p(a)&&a.match(/\.(swf)((\?|#).*)?$/i)},_start:function(a){var d={},e,c;a=l(a);e=b.group[a]||null;if(!e)return!1;d=f.extend(!0,{},b.opts,e);e=d.margin;c=d.padding;"number"===f.type(e)&&(d.margin=[e,e,e,e]);"number"===f.type(c)&& -(d.padding=[c,c,c,c]);d.modal&&f.extend(!0,d,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}});d.autoSize&&(d.autoWidth=d.autoHeight=!0);"auto"===d.width&&(d.autoWidth=!0);"auto"===d.height&&(d.autoHeight=!0);d.group=b.group;d.index=a;b.coming=d;if(!1===b.trigger("beforeLoad"))b.coming=null;else{c=d.type;e=d.href;if(!c)return b.coming=null,b.current&&b.router&&"jumpto"!==b.router?(b.current.index=a,b[b.router](b.direction)):!1;b.isActive= -!0;if("image"===c||"swf"===c)d.autoHeight=d.autoWidth=!1,d.scrolling="visible";"image"===c&&(d.aspectRatio=!0);"iframe"===c&&s&&(d.scrolling="scroll");d.wrap=f(d.tpl.wrap).addClass("fancybox-"+(s?"mobile":"desktop")+" fancybox-type-"+c+" fancybox-tmp "+d.wrapCSS).appendTo(d.parent||"body");f.extend(d,{skin:f(".fancybox-skin",d.wrap),outer:f(".fancybox-outer",d.wrap),inner:f(".fancybox-inner",d.wrap)});f.each(["Top","Right","Bottom","Left"],function(a,b){d.skin.css("padding"+b,x(d.padding[a]))});b.trigger("onReady"); -if("inline"===c||"html"===c){if(!d.content||!d.content.length)return b._error("content")}else if(!e)return b._error("href");"image"===c?b._loadImage():"ajax"===c?b._loadAjax():"iframe"===c?b._loadIframe():b._afterLoad()}},_error:function(a){f.extend(b.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:a,content:b.coming.tpl.error});b._afterLoad()},_loadImage:function(){var a=b.imgPreload=new Image;a.onload=function(){this.onload=this.onerror=null;b.coming.width= -this.width;b.coming.height=this.height;b._afterLoad()};a.onerror=function(){this.onload=this.onerror=null;b._error("image")};a.src=b.coming.href;!0!==a.complete&&b.showLoading()},_loadAjax:function(){var a=b.coming;b.showLoading();b.ajaxLoad=f.ajax(f.extend({},a.ajax,{url:a.href,error:function(a,e){b.coming&&"abort"!==e?b._error("ajax",a):b.hideLoading()},success:function(d,e){"success"===e&&(a.content=d,b._afterLoad())}}))},_loadIframe:function(){var a=b.coming,d=f(a.tpl.iframe.replace(/\{rnd\}/g, -(new Date).getTime())).attr("scrolling",s?"auto":a.iframe.scrolling).attr("src",a.href);f(a.wrap).bind("onReset",function(){try{f(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(a){}});a.iframe.preload&&(b.showLoading(),d.one("load",function(){f(this).data("ready",1);s||f(this).bind("load.fb",b.update);f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();b._afterLoad()}));a.content=d.appendTo(a.inner);a.iframe.preload||b._afterLoad()},_preloadImages:function(){var a= -b.group,d=b.current,e=a.length,c=d.preload?Math.min(d.preload,e-1):0,f,g;for(g=1;g<=c;g+=1)f=a[(d.index+g)%e],"image"===f.type&&f.href&&((new Image).src=f.href)},_afterLoad:function(){var a=b.coming,d=b.current,e,c,k,g,h;b.hideLoading();if(a&&!1!==b.isActive)if(!1===b.trigger("afterLoad",a,d))a.wrap.stop(!0).trigger("onReset").remove(),b.coming=null;else{d&&(b.trigger("beforeChange",d),d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove());b.unbindEvents(); -e=a.content;c=a.type;k=a.scrolling;f.extend(b,{wrap:a.wrap,skin:a.skin,outer:a.outer,inner:a.inner,current:a,previous:d});g=a.href;switch(c){case "inline":case "ajax":case "html":a.selector?e=f("
").html(e).find(a.selector):t(e)&&(e.data("fancybox-placeholder")||e.data("fancybox-placeholder",f('
').insertAfter(e).hide()),e=e.show().detach(),a.wrap.bind("onReset",function(){f(this).find(e).length&&e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder", -!1)}));break;case "image":e=a.tpl.image.replace("{href}",g);break;case "swf":e='',h="",f.each(a.swf,function(a,b){e+='';h+=" "+a+'="'+b+'"'}),e+='"}(!t(e)||!e.parent().is(a.inner))&&a.inner.append(e);b.trigger("beforeShow"); -a.inner.css("overflow","yes"===k?"scroll":"no"===k?"hidden":k);b._setDimension();b.reposition();b.isOpen=!1;b.coming=null;b.bindEvents();if(b.isOpened){if(d.prevMethod)b.transitions[d.prevMethod]()}else f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove();b.transitions[b.isOpened?a.nextMethod:a.openMethod]();b._preloadImages()}},_setDimension:function(){var a=b.getViewport(),d=0,e=!1,c=!1,e=b.wrap,k=b.skin,g=b.inner,h=b.current,c=h.width,j=h.height,m=h.minWidth,u=h.minHeight,n=h.maxWidth, -v=h.maxHeight,s=h.scrolling,q=h.scrollOutside?h.scrollbarWidth:0,y=h.margin,p=l(y[1]+y[3]),r=l(y[0]+y[2]),z,A,t,D,B,G,C,E,w;e.add(k).add(g).width("auto").height("auto").removeClass("fancybox-tmp");y=l(k.outerWidth(!0)-k.width());z=l(k.outerHeight(!0)-k.height());A=p+y;t=r+z;D=F(c)?(a.w-A)*l(c)/100:c;B=F(j)?(a.h-t)*l(j)/100:j;if("iframe"===h.type){if(w=h.content,h.autoHeight&&1===w.data("ready"))try{w[0].contentWindow.document.location&&(g.width(D).height(9999),G=w.contents().find("body"),q&&G.css("overflow-x", -"hidden"),B=G.height())}catch(H){}}else if(h.autoWidth||h.autoHeight)g.addClass("fancybox-tmp"),h.autoWidth||g.width(D),h.autoHeight||g.height(B),h.autoWidth&&(D=g.width()),h.autoHeight&&(B=g.height()),g.removeClass("fancybox-tmp");c=l(D);j=l(B);E=D/B;m=l(F(m)?l(m,"w")-A:m);n=l(F(n)?l(n,"w")-A:n);u=l(F(u)?l(u,"h")-t:u);v=l(F(v)?l(v,"h")-t:v);G=n;C=v;h.fitToView&&(n=Math.min(a.w-A,n),v=Math.min(a.h-t,v));A=a.w-p;r=a.h-r;h.aspectRatio?(c>n&&(c=n,j=l(c/E)),j>v&&(j=v,c=l(j*E)),cA||p>r)&&(c>m&&j>u)&&!(19n&&(c=n,j=l(c/E)),g.width(c).height(j),e.width(c+y),a=e.width(),p=e.height();else c=Math.max(m,Math.min(c,c-(a-A))),j=Math.max(u,Math.min(j,j-(p-r)));q&&("auto"===s&&jA||p>r)&&c>m&&j>u;c=h.aspectRatio?cu&&j
').appendTo("body"); -this.fixed=!1;a.fixed&&b.defaults.fixed&&(this.overlay.addClass("fancybox-overlay-fixed"),this.fixed=!0)},open:function(a){var d=this;a=f.extend({},this.defaults,a);this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(a);this.fixed||(q.bind("resize.overlay",f.proxy(this.update,this)),this.update());a.closeClick&&this.overlay.bind("click.overlay",function(a){f(a.target).hasClass("fancybox-overlay")&&(b.isActive?b.close():d.close())});this.overlay.css(a.css).show()}, -close:function(){f(".fancybox-overlay").remove();q.unbind("resize.overlay");this.overlay=null;!1!==this.margin&&(f("body").css("margin-right",this.margin),this.margin=!1);this.el&&this.el.removeClass("fancybox-lock")},update:function(){var a="100%",b;this.overlay.width(a).height("100%");H?(b=Math.max(z.documentElement.offsetWidth,z.body.offsetWidth),n.width()>b&&(a=n.width())):n.width()>q.width()&&(a=n.width());this.overlay.width(a).height(n.height())},onReady:function(a,b){f(".fancybox-overlay").stop(!0, -!0);this.overlay||(this.margin=n.height()>q.height()||"scroll"===f("body").css("overflow-y")?f("body").css("margin-right"):!1,this.el=z.all&&!z.querySelector?f("html"):f("body"),this.create(a));a.locked&&this.fixed&&(b.locked=this.overlay.append(b.wrap),b.fixed=!1);!0===a.showEarly&&this.beforeShow.apply(this,arguments)},beforeShow:function(a,b){b.locked&&(this.el.addClass("fancybox-lock"),!1!==this.margin&&f("body").css("margin-right",l(this.margin)+b.scrollbarWidth));this.open(a)},onUpdate:function(){this.fixed|| -this.update()},afterClose:function(a){this.overlay&&!b.isActive&&this.overlay.fadeOut(a.speedOut,f.proxy(this.close,this))}};b.helpers.title={defaults:{type:"float",position:"bottom"},beforeShow:function(a){var d=b.current,e=d.title,c=a.type;f.isFunction(e)&&(e=e.call(d.element,d));if(p(e)&&""!==f.trim(e)){d=f('
'+e+"
");switch(c){case "inside":c=b.skin;break;case "outside":c=b.wrap;break;case "over":c=b.inner;break;default:c=b.skin,d.appendTo("body"), -H&&d.width(d.width()),d.wrapInner(''),b.current.margin[2]+=Math.abs(l(d.css("margin-bottom")))}d["top"===a.position?"prependTo":"appendTo"](c)}}};f.fn.fancybox=function(a){var d,e=f(this),c=this.selector||"",k=function(g){var h=f(this).blur(),j=d,k,l;!g.ctrlKey&&(!g.altKey&&!g.shiftKey&&!g.metaKey)&&!h.is(".fancybox-wrap")&&(k=a.groupAttr||"data-fancybox-group",l=h.attr(k),l||(k="rel",l=h.get(0)[k]),l&&(""!==l&&"nofollow"!==l)&&(h=c.length?f(c):e,h=h.filter("["+k+'="'+l+ -'"]'),j=h.index(this)),a.index=j,!1!==b.open(h,a)&&g.preventDefault())};a=a||{};d=a.index||0;!c||!1===a.live?e.unbind("click.fb-start").bind("click.fb-start",k):n.undelegate(c,"click.fb-start").delegate(c+":not('.fancybox-item, .fancybox-nav')","click.fb-start",k);this.filter("[data-fancybox-start=1]").trigger("click");return this};n.ready(function(){f.scrollbarWidth===r&&(f.scrollbarWidth=function(){var a=f('
').appendTo("body"),b=a.children(), -b=b.innerWidth()-b.height(99).innerWidth();a.remove();return b});if(f.support.fixedPosition===r){var a=f.support,d=f('
').appendTo("body"),e=20===d[0].offsetTop||15===d[0].offsetTop;d.remove();a.fixedPosition=e}f.extend(b.defaults,{scrollbarWidth:f.scrollbarWidth(),fixed:f.support.fixedPosition,parent:f("body")})})})(window,document,jQuery); \ No newline at end of file diff --git a/boards/static/js/jquery.mousewheel.js b/boards/static/js/jquery.mousewheel.js new file mode 100644 --- /dev/null +++ b/boards/static/js/jquery.mousewheel.js @@ -0,0 +1,117 @@ +/*! Copyright (c) 2013 Brandon Aaron (http://brandonaaron.net) + * Licensed under the MIT License (LICENSE.txt). + * + * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. + * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. + * Thanks to: Seamus Leahy for adding deltaX and deltaY + * + * Version: 3.1.3 + * + * Requires: 1.2.2+ + */ + +(function (factory) { + if ( typeof define === 'function' && define.amd ) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS style for Browserify + module.exports = factory; + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + + var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll']; + var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll']; + var lowestDelta, lowestDeltaXY; + + if ( $.event.fixHooks ) { + for ( var i = toFix.length; i; ) { + $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; + } + } + + $.event.special.mousewheel = { + setup: function() { + if ( this.addEventListener ) { + for ( var i = toBind.length; i; ) { + this.addEventListener( toBind[--i], handler, false ); + } + } else { + this.onmousewheel = handler; + } + }, + + teardown: function() { + if ( this.removeEventListener ) { + for ( var i = toBind.length; i; ) { + this.removeEventListener( toBind[--i], handler, false ); + } + } else { + this.onmousewheel = null; + } + } + }; + + $.fn.extend({ + mousewheel: function(fn) { + return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); + }, + + unmousewheel: function(fn) { + return this.unbind("mousewheel", fn); + } + }); + + + function handler(event) { + var orgEvent = event || window.event, + args = [].slice.call(arguments, 1), + delta = 0, + deltaX = 0, + deltaY = 0, + absDelta = 0, + absDeltaXY = 0, + fn; + event = $.event.fix(orgEvent); + event.type = "mousewheel"; + + // Old school scrollwheel delta + if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; } + if ( orgEvent.detail ) { delta = orgEvent.detail * -1; } + + // New school wheel delta (wheel event) + if ( orgEvent.deltaY ) { + deltaY = orgEvent.deltaY * -1; + delta = deltaY; + } + if ( orgEvent.deltaX ) { + deltaX = orgEvent.deltaX; + delta = deltaX * -1; + } + + // Webkit + if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; } + if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX * -1; } + + // Look for lowest delta to normalize the delta values + absDelta = Math.abs(delta); + if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; } + absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX)); + if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; } + + // Get a whole value for the deltas + fn = delta > 0 ? 'floor' : 'ceil'; + delta = Math[fn](delta / lowestDelta); + deltaX = Math[fn](deltaX / lowestDeltaXY); + deltaY = Math[fn](deltaY / lowestDeltaXY); + + // Add event and delta to the front of the arguments + args.unshift(event, delta, deltaX, deltaY); + + return ($.event.dispatch || $.event.handle).apply(this, args); + } + +})); diff --git a/boards/static/js/main.js b/boards/static/js/main.js --- a/boards/static/js/main.js +++ b/boards/static/js/main.js @@ -4,13 +4,10 @@ return false; }); - $(".fancy").fancybox({ - closeBtn: false, - closeClick: true, - padding: 0, - openEffect: 'none', - closeEffect: 'none' - }); + addImgPreview(); + addRefLinkMap(); - addRefLinkMap(); -}) + // TODO Rewrite popups module and reenable it + //addPopups(); + addMarkPanel(); +}); diff --git a/boards/static/js/panel.js b/boards/static/js/panel.js new file mode 100644 --- /dev/null +++ b/boards/static/js/panel.js @@ -0,0 +1,34 @@ +function addMarkToMsg(start, end) { + var textarea = document.getElementById('id_text'); + if(!textarea) return; + if( document.selection ) { + textarea.focus(); + sel = document.selection.createRange(); + sel.text = start + sel.text + end; + } else if(textarea.selectionStart || textarea.selectionStart == '0') { + textarea.focus(); + var startPos = textarea.selectionStart; + var endPos = textarea.selectionEnd; + textarea.value = textarea.value.substring(0, startPos) + start + textarea.value.substring(startPos, endPos) + end + textarea.value.substring( endPos, textarea.value.length ); + } else { + textarea.value += start + end; + } + return false; +} + +function addMarkPanel() { + $('.mark_btn').on('click', function() { + switch($(this).attr('id')) { + case "italic": + return addMarkToMsg('_', '_'); + case "bold": + return addMarkToMsg('__', '__'); + case "spoiler": + return addMarkToMsg('%%', '%%'); + case "comment": + return addMarkToMsg('//', ''); + case "quote": + return addMarkToMsg('>', ''); + } + }); +} diff --git a/boards/static/js/popup.js b/boards/static/js/popup.js new file mode 100644 --- /dev/null +++ b/boards/static/js/popup.js @@ -0,0 +1,44 @@ +/** + * Created with IntelliJ IDEA. + * User: vurdalak + * Date: 21.09.13 + * Time: 15:21 + * To change this template use File | Settings | File Templates. + */ + +function addPopups() { + + $('a').each(function() { + if($(this).text().indexOf('>>') == 0) { + var refNum = $(this).text().match(/\d+/); + + if (refNum != null) { + var self = $(this); + + $(this).mouseenter(function() { + $.get('/get_post/' + refNum, function(data) { + var popup = $('
').html(data) + + popup.dialog({ + modal: false, + minHeight: 0, + }); + + popup.position({ + my: "left+20 top+20", + at: "right bottom", + of: self + }) + + self.mouseleave(function() { + if (popup != null) { + popup.remove(); + } + }); + }) + }); + } + } + }); + +} diff --git a/boards/static/js/refmaps.js b/boards/static/js/refmaps.js --- a/boards/static/js/refmaps.js +++ b/boards/static/js/refmaps.js @@ -30,9 +30,10 @@ function addRefLinkMap() { if(typeof refMap[pNum] === 'object') { //append refmap panel if(!$("#refmap_"+pNum).length) { - var data = label_replies + refMap[pNum].toString().replace(/(\d+)/g, ' >>$1'); - $('#'+pNum+'').find('.message').after($('
'+data+'
')); + $('#'+pNum+'').find('.message').after( + $('
'+label_replies + refMap[pNum].toString().replace(/(\d+)/g, ' >>$1')+'
') + ); } } } -} +} \ No newline at end of file diff --git a/boards/static/js/thread.js b/boards/static/js/thread.js --- a/boards/static/js/thread.js +++ b/boards/static/js/thread.js @@ -1,75 +1,28 @@ -var image_mode = 0; -var normal_dom, table_dom; - -function add_panel(after) -{ - var nav_top = $(after); - if (nav_top.length === 0) return; - nav_top = nav_top[0]; - - var tab_bar = $('
'); - - var tab; - - tab = $(''); - tab.on("change", tab_handler); - - var label_normal = gettext('Normal'); - tab = $('').prepend(tab); - tab_bar.append(tab); - - tab = $(''); - tab.on("change", tab_handler); - - var label_gallery = gettext('Gallery'); - tab = $('').prepend(tab); - tab_bar.append(tab); - - tab_bar.insertAfter(nav_top); -} - -function tab_handler(ev) -{ - var current_el = $(this); +function addGalleryPanel() { + var gallery = $('a[class="thumb"]').clone(true), + normal = $('.post').clone(true); - if (!current_el.prop('checked')) return; - - var new_mode = parseInt(current_el.val(), 10); - if (new_mode === image_mode) return; - image_mode = new_mode; - - make_normal_dom(); - make_table_dom(); + $('.navigation_panel').filter(':first').after( + '
' + + '' + + '' + + '
' + ); - switch(new_mode) { - case 0: - $('#posts-table').replaceWith(normal_dom); - break; - case 1: - $('#posts').replaceWith(table_dom); - break; - } -} - -function make_normal_dom() -{ - if (typeof normal_dom === 'undefined') { - normal_dom = $('#posts').clone(true); - } -} - -function make_table_dom() -{ - if (typeof table_dom !== 'undefined') return; - - table_dom = $('
'); - $('#posts > .post > .image > a').each( - function(){ - table_dom.append( - $(this).clone().attr('target', '_blank') + $('input[name="image-mode"]').change(function() { + //gallery mode + if($(this).val() === '1') { + $('.thread').replaceWith( + $('
').append(gallery) ); } - ); + //normal mode + else { + $('#posts-table').replaceWith( + $('
').append(normal) + ); + } + }); } function moveCaretToEnd(el) { @@ -98,6 +51,6 @@ function addQuickReply(postId) { $(document).ready(function(){ - add_panel('.navigation_panel'); + addGalleryPanel(); addRefLinkMap(); }); diff --git a/boards/templates/boards/base.html b/boards/templates/boards/base.html --- a/boards/templates/boards/base.html +++ b/boards/templates/boards/base.html @@ -1,29 +1,35 @@ {% load staticfiles %} {% load i18n %} +{% load static from staticfiles %} + href="{% static 'css/base.css' %}" media="all"/> - + href="{% static theme_css %}" media="all"/> + + href="{% static 'favicon.png' %}"> + {% block head %}{% endblock %} - - + + + - - + + + + + diff --git a/boards/templates/boards/post.html b/boards/templates/boards/post.html new file mode 100644 --- /dev/null +++ b/boards/templates/boards/post.html @@ -0,0 +1,47 @@ +{% load i18n %} + +
+{% if post.image %} +
+ {% trans 'Post image' %} + +
+{% endif %} +
+ + {% autoescape off %} + {{ post.text.rendered }} + {% endautoescape %} +
+{% if post.tags.exists %} + +{% endif %} +
\ No newline at end of file diff --git a/boards/templates/boards/posting_general.html b/boards/templates/boards/posting_general.html --- a/boards/templates/boards/posting_general.html +++ b/boards/templates/boards/posting_general.html @@ -38,10 +38,10 @@ {% endif %} {% if thread.thread.image %}
- {% trans 'Post image' %} @@ -94,10 +94,10 @@ {% endif %} {% if post.image %}
- {% trans 'Post image' %} @@ -137,6 +137,16 @@
{{ form.title.errors }}
+
{% trans 'Formatting' %}
+
+ >{% trans 'quote' %} + {% trans 'italic' %} + {% trans 'bold' %} + {% trans 'spoiler' %} + // {% trans 'comment' %} +
+
+
{% trans 'Text' %}
{{ form.text }}
{{ form.text.errors }}
@@ -151,6 +161,11 @@
{{ form.tags }}
{{ form.tags.errors }}
+
{{ form.captcha }}
{{ form.captcha.errors }}
@@ -174,7 +189,7 @@ {% block metapanel %} - Neboard 1.1 + Neboard 1.2 {% trans "Pages:" %} {% for page in pages %} [ + {% get_current_language as LANGUAGE_CODE %} + + {% if posts %} - {% cache 600 thread_view posts.0.last_edit_time moderator %} -
- {% for post in posts %} + {% cache 600 thread_view posts.0.last_edit_time moderator LANGUAGE_CODE %} +
+ {% for post in posts %} {% if bumpable %}
{% else %} @@ -23,10 +26,10 @@ {% if post.image %}
{% trans 'Post image' %} @@ -82,6 +85,16 @@
{{ form.title.errors }}
+
{% trans 'Formatting' %}
+
+ >{% trans 'quote' %} + {% trans 'italic' %} + {% trans 'bold' %} + {% trans 'spoiler' %} + // {% trans 'comment' %} +
+
+
{% trans 'Text' %}
{{ form.text }}
{{ form.text.errors }}
@@ -91,6 +104,11 @@
{{ form.image }}
{{ form.image.errors }}
+
{{ form.captcha }}
{{ form.captcha.errors }}
@@ -111,8 +129,10 @@ {% block metapanel %} + {% get_current_language as LANGUAGE_CODE %} + - {% cache 600 thread_meta posts.0.last_edit_time moderator %} + {% cache 600 thread_meta posts.0.last_edit_time moderator LANGUAGE_CODE %} {{ posts.0.get_reply_count }} {% trans 'replies' %}, {{ posts.0.get_images_count }} {% trans 'images' %}. {% trans 'Last update: ' %}{{ posts.0.last_edit_time }} diff --git a/boards/urls.py b/boards/urls.py --- a/boards/urls.py +++ b/boards/urls.py @@ -30,7 +30,6 @@ urlpatterns = patterns('', # /boards/thread/ url(r'^thread/(?P\w+)/$', views.thread, name='thread'), - # /boards/theme/theme_name/ url(r'^settings/$', views.settings, name='settings'), url(r'^tags/$', views.all_tags, name='tags'), url(r'^captcha/', include('captcha.urls')), @@ -49,5 +48,9 @@ urlpatterns = patterns('', url(r'^tag/(?P\w+)/page/(?P\w+)/rss/$', TagThreadsFeed()), url(r'^thread/(?P\w+)/rss/$', ThreadPostsFeed()), + # i18n url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict), + + # API + url(r'^get_post/(?P\w+)/$', views.get_post, name="get_post"), ) diff --git a/boards/utils.py b/boards/utils.py --- a/boards/utils.py +++ b/boards/utils.py @@ -62,3 +62,12 @@ def update_captcha_access(request, passe session[KEY_CAPTCHA_LAST_ACTIVITY] = int(time.time()) session[KEY_CAPTCHA_DELAY_TIME] = delay_time + + +def get_client_ip(request): + x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') + if x_forwarded_for: + ip = x_forwarded_for.split(',')[-1].strip() + else: + ip = request.META.get('REMOTE_ADDR') + return ip \ No newline at end of file diff --git a/boards/views.py b/boards/views.py --- a/boards/views.py +++ b/boards/views.py @@ -1,7 +1,9 @@ import hashlib import string +from django.core import serializers from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect +from django.http.response import HttpResponse from django.template import RequestContext from django.shortcuts import render, redirect, get_object_or_404 from django.utils import timezone @@ -14,6 +16,7 @@ from boards.forms import ThreadForm, Pos from boards.models import Post, Tag, Ban, User, RANK_USER, SETTING_MODERATE from boards import authors +from boards.utils import get_client_ip import neboard @@ -34,6 +37,9 @@ def index(request, page=0): if form.is_valid(): return _new_post(request, form) + if form.need_to_ban: + # Ban user because he is suspected to be a bot + _ban_current_user(request) else: form = threadFormClass(error_class=PlainErrorList, **kwargs) @@ -53,8 +59,8 @@ def index(request, page=0): def _new_post(request, form, thread_id=boards.models.NO_PARENT): """Add a new post (in thread or as a reply).""" - ip = _get_client_ip(request) - is_banned = Ban.objects.filter(ip=ip).count() > 0 + ip = get_client_ip(request) + is_banned = Ban.objects.filter(ip=ip).exists() if is_banned: return redirect(you_are_banned) @@ -99,7 +105,10 @@ def _new_post(request, form, thread_id=b def tag(request, tag_name, page=0): - """Get all tag threads (posts without a parent).""" + """ + Get all tag threads. Threads are split in pages, so some page is + requested. Default page is 0. + """ tag = get_object_or_404(Tag, name=tag_name) threads = [] @@ -112,6 +121,9 @@ def tag(request, tag_name, page=0): error_class=PlainErrorList) if form.is_valid(): return _new_post(request, form) + if form.need_to_ban: + # Ban user because he is suspected to be a bot + _ban_current_user(request) else: form = forms.ThreadForm(initial={'tags': tag_name}, error_class=PlainErrorList) @@ -144,6 +156,9 @@ def thread(request, post_id): if form.is_valid(): return _new_post(request, form, post_id) + if form.need_to_ban: + # Ban user because he is suspected to be a bot + _ban_current_user(request) else: form = postFormClass(error_class=PlainErrorList, **kwargs) @@ -166,6 +181,8 @@ def login(request): if request.method == 'POST': form = LoginForm(request.POST, request.FILES, error_class=PlainErrorList) + form.session = request.session + if form.is_valid(): user = User.objects.get(user_id=form.cleaned_data['user_id']) request.session['user_id'] = user.id @@ -241,6 +258,8 @@ def jump_to_post(request, post_id): def authors(request): + """Show authors list""" + context = _init_default_context(request) context['authors'] = boards.authors.authors @@ -248,6 +267,8 @@ def authors(request): def delete(request, post_id): + """Delete post""" + user = _get_user(request) post = get_object_or_404(Post, id=post_id) @@ -262,6 +283,8 @@ def delete(request, post_id): def ban(request, post_id): + """Ban user""" + user = _get_user(request) post = get_object_or_404(Post, id=post_id) @@ -273,16 +296,22 @@ def ban(request, post_id): def you_are_banned(request): + """Show the page that notifies that user is banned""" + context = _init_default_context(request) return render(request, 'boards/staticpages/banned.html', context) def page_404(request): + """Show page 404 (not found error)""" + context = _init_default_context(request) return render(request, 'boards/404.html', context) def tag_subscribe(request, tag_name): + """Add tag to favorites""" + user = _get_user(request) tag = get_object_or_404(Tag, name=tag_name) @@ -293,6 +322,8 @@ def tag_subscribe(request, tag_name): def tag_unsubscribe(request, tag_name): + """Remove tag from favorites""" + user = _get_user(request) tag = get_object_or_404(Tag, name=tag_name) @@ -303,10 +334,39 @@ def tag_unsubscribe(request, tag_name): def static_page(request, name): + """Show a static page that needs only tags list and a CSS""" + context = _init_default_context(request) return render(request, 'boards/staticpages/' + name + '.html', context) +def api_get_post(request, post_id): + """ + Get the JSON of a post. This can be + used as and API for external clients. + """ + + post = get_object_or_404(Post, id=post_id) + + json = serializers.serialize("json", [post], fields=( + "pub_time", "_text_rendered", "title", "text", "image", + "image_width", "image_height", "replies", "tags" + )) + + return HttpResponse(content=json) + + +def get_post(request, post_id): + """Get the html of a post. Used for popups.""" + + post = get_object_or_404(Post, id=post_id) + + context = RequestContext(request) + context["post"] = post + + return render(request, 'boards/post.html', context) + + def _get_theme(request, user=None): """Get user's CSS theme""" @@ -319,15 +379,6 @@ def _get_theme(request, user=None): return theme -def _get_client_ip(request): - x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') - if x_forwarded_for: - ip = x_forwarded_for.split(',')[-1].strip() - else: - ip = request.META.get('REMOTE_ADDR') - return ip - - def _init_default_context(request): """Create context with default values that are used in most views""" @@ -336,8 +387,12 @@ def _init_default_context(request): user = _get_user(request) context['user'] = user context['tags'] = user.get_sorted_fav_tags() - context['theme'] = _get_theme(request, user) + theme = _get_theme(request, user) + context['theme'] = theme + context['theme_css'] = 'css/' + theme + '/base_page.css' + + # This shows the moderator panel moderate = user.get_setting(SETTING_MODERATE) if moderate == 'True': context['moderator'] = user.is_moderator() @@ -348,7 +403,10 @@ def _init_default_context(request): def _get_user(request): - """Get current user from the session""" + """ + Get current user from the session. If the user does not exist, create + a new one. + """ session = request.session if not 'user_id' in session: @@ -370,8 +428,21 @@ def _get_user(request): def _redirect_to_next(request): + """ + If a 'next' parameter was specified, redirect to the next page. This is + used when the user is required to return to some page after the current + view has finished its work. + """ + if 'next' in request.GET: next_page = request.GET['next'] return HttpResponseRedirect(next_page) else: return redirect(index) + + +def _ban_current_user(request): + """Add current user to the IP ban list""" + + ip = utils.get_client_ip(request) + Ban.objects.get_or_create(ip=ip) diff --git a/neboard/settings.py b/neboard/settings.py --- a/neboard/settings.py +++ b/neboard/settings.py @@ -24,13 +24,6 @@ DATABASES = { } } -CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', - 'LOCATION': 'neboard_cache', - } -} - # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. @@ -92,6 +85,8 @@ STATICFILES_FINDERS = ( # 'django.contrib.staticfiles.finders.DefaultStorageFinder', ) +STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.CachedStaticFilesStorage' + # Make this unique, and don't share it with anybody. SECRET_KEY = '@1rc$o(7=tt#kd+4s$u6wchm**z^)4x90)7f6z(i&55@o11*8o' @@ -117,7 +112,8 @@ MIDDLEWARE_CLASSES = ( 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', # Uncomment the next line for simple clickjacking protection: - # 'django.middleware.clickjacking.XFrameOptionsMiddleware', + # 'django.middleware.clickjacking.XFrameOptionsMiddleware' + 'boards.middlewares.BanMiddleware', ) ROOT_URLCONF = 'neboard.urls' @@ -195,6 +191,7 @@ SITE_NAME = 'Neboard' THEMES = [ ('md', 'Mystic Dark'), + ('md_centered', 'Mystic Dark (centered)'), ('sw', 'Snow White'), ('pg', 'Photon Gray'), ]