Change problem page

This commit is contained in:
cuom1999 2022-04-13 00:52:03 -05:00
parent 5c6391fb76
commit f539a90635
13 changed files with 6941 additions and 543 deletions

View file

@ -111,13 +111,14 @@ urlpatterns = [
url(r'^', include('social_django.urls')), url(r'^', include('social_django.urls')),
url(r'^feed/', include([ url(r'^feed/', include([
url(r'^problems/$', problem.ProblemFeed.as_view(), name='problem_feed'),
url(r'^tickets/$', blog.TicketFeed.as_view(), name='ticket_feed'), url(r'^tickets/$', blog.TicketFeed.as_view(), name='ticket_feed'),
url(r'^comments/$', blog.CommentFeed.as_view(), name='comment_feed'), url(r'^comments/$', blog.CommentFeed.as_view(), name='comment_feed'),
])), ])),
url(r'^problems/$', problem.ProblemList.as_view(), name='problem_list'), url(r'^problems/$', problem.ProblemList.as_view(), name='problem_list'),
url(r'^problems/random/$', problem.RandomProblem.as_view(), name='problem_random'), url(r'^problems/random/$', problem.RandomProblem.as_view(), name='problem_random'),
url(r'^problems/feed$', problem.ProblemFeed.as_view(feed_type='for_you'), name='problem_feed'),
url(r'^problems/feed/new$', problem.ProblemFeed.as_view(feed_type='new'), name='problem_feed_new'),
url(r'^problem/(?P<problem>[^/]+)', include([ url(r'^problem/(?P<problem>[^/]+)', include([
url(r'^$', problem.ProblemDetail.as_view(), name='problem_detail'), url(r'^$', problem.ProblemDetail.as_view(), name='problem_detail'),
url(r'^/editorial$', problem.ProblemSolution.as_view(), name='problem_editorial'), url(r'^/editorial$', problem.ProblemSolution.as_view(), name='problem_editorial'),

View file

@ -6,8 +6,10 @@ import os
class CollabFilter: class CollabFilter:
DOT = 'dot' DOT = 'dot'
COSINE = 'cosine' COSINE = 'cosine'
def __init__(self):
embeddings = np.load(os.path.join(settings.ML_OUTPUT_PATH, 'collab_filter/embeddings.npz'), # name = 'collab_filter' or 'collab_filter_time'
def __init__(self, name):
embeddings = np.load(os.path.join(settings.ML_OUTPUT_PATH, name + '/embeddings.npz'),
allow_pickle=True) allow_pickle=True)
arr0, arr1 = embeddings.files arr0, arr1 = embeddings.files
self.user_embeddings = embeddings[arr0] self.user_embeddings = embeddings[arr0]

View file

@ -93,7 +93,7 @@ class PostList(FeedView):
context['title'] = self.title or _('Page %d of Posts') % context['page_obj'].number context['title'] = self.title or _('Page %d of Posts') % context['page_obj'].number
context['first_page_href'] = reverse('home') context['first_page_href'] = reverse('home')
context['page_prefix'] = reverse('blog_post_list') context['page_prefix'] = reverse('blog_post_list')
context['feed_type'] = 'blog' context['page_type'] = 'blog'
context['post_comment_counts'] = { context['post_comment_counts'] = {
int(page[2:]): count for page, count in int(page[2:]): count for page, count in
Comment.objects Comment.objects
@ -128,7 +128,7 @@ class TicketFeed(FeedView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(TicketFeed, self).get_context_data(**kwargs) context = super(TicketFeed, self).get_context_data(**kwargs)
context['feed_type'] = 'ticket' context['page_type'] = 'ticket'
context['first_page_href'] = self.request.path context['first_page_href'] = self.request.path
context['page_prefix'] = '?page=' context['page_prefix'] = '?page='
context['title'] = _('Ticket feed') context['title'] = _('Ticket feed')
@ -146,7 +146,7 @@ class CommentFeed(FeedView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(CommentFeed, self).get_context_data(**kwargs) context = super(CommentFeed, self).get_context_data(**kwargs)
context['feed_type'] = 'comment' context['page_type'] = 'comment'
context['first_page_href'] = self.request.path context['first_page_href'] = self.request.path
context['page_prefix'] = '?page=' context['page_prefix'] = '?page='
context['title'] = _('Comment feed') context['title'] = _('Comment feed')

View file

@ -38,7 +38,6 @@ from judge.utils.problems import contest_attempted_ids, contest_completed_ids, h
from judge.utils.strings import safe_float_or_none, safe_int_or_none from judge.utils.strings import safe_float_or_none, safe_int_or_none
from judge.utils.tickets import own_ticket_filter from judge.utils.tickets import own_ticket_filter
from judge.utils.views import QueryStringSortMixin, SingleObjectFormView, TitleMixin, generic_message from judge.utils.views import QueryStringSortMixin, SingleObjectFormView, TitleMixin, generic_message
from judge.views.blog import FeedView
from judge.ml.collab_filter import CollabFilter from judge.ml.collab_filter import CollabFilter
@ -455,10 +454,9 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
queryset = queryset.filter(points__gte=self.point_start) queryset = queryset.filter(points__gte=self.point_start)
if self.point_end is not None: if self.point_end is not None:
queryset = queryset.filter(points__lte=self.point_end) queryset = queryset.filter(points__lte=self.point_end)
if self.show_editorial: queryset = queryset.annotate(
queryset = queryset.annotate( has_public_editorial=Sum(Case(When(solution__is_public=True, then=1),
has_public_editorial=Sum(Case(When(solution__is_public=True, then=1), default=0, output_field=IntegerField())))
default=0, output_field=IntegerField())))
return queryset.distinct() return queryset.distinct()
@ -474,6 +472,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
context['show_types'] = 0 if self.in_contest else int(self.show_types) context['show_types'] = 0 if self.in_contest else int(self.show_types)
context['full_text'] = 0 if self.in_contest else int(self.full_text) context['full_text'] = 0 if self.in_contest else int(self.full_text)
context['show_editorial'] = 0 if self.in_contest else int(self.show_editorial) context['show_editorial'] = 0 if self.in_contest else int(self.show_editorial)
context['have_editorial'] = 0 if self.in_contest else int(self.have_editorial)
context['organizations'] = Organization.objects.all() context['organizations'] = Organization.objects.all()
context['category'] = self.category context['category'] = self.category
@ -486,7 +485,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
context['search_query'] = self.search_query context['search_query'] = self.search_query
context['completed_problem_ids'] = self.get_completed_problems() context['completed_problem_ids'] = self.get_completed_problems()
context['attempted_problems'] = self.get_attempted_problems() context['attempted_problems'] = self.get_attempted_problems()
context['page_type'] = 'list'
context.update(self.get_sort_paginate_context()) context.update(self.get_sort_paginate_context())
if not self.in_contest: if not self.in_contest:
context.update(self.get_sort_context()) context.update(self.get_sort_context())
@ -498,6 +497,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
context['hide_contest_scoreboard'] = self.contest.scoreboard_visibility in \ context['hide_contest_scoreboard'] = self.contest.scoreboard_visibility in \
(self.contest.SCOREBOARD_AFTER_CONTEST, self.contest.SCOREBOARD_AFTER_PARTICIPATION) (self.contest.SCOREBOARD_AFTER_CONTEST, self.contest.SCOREBOARD_AFTER_PARTICIPATION)
context['has_clarifications'] = False context['has_clarifications'] = False
if self.request.user.is_authenticated: if self.request.user.is_authenticated:
participation = self.request.profile.current_contest participation = self.request.profile.current_contest
if participation: if participation:
@ -537,6 +537,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
self.show_types = self.GET_with_session(request, 'show_types') self.show_types = self.GET_with_session(request, 'show_types')
self.full_text = self.GET_with_session(request, 'full_text') self.full_text = self.GET_with_session(request, 'full_text')
self.show_editorial = self.GET_with_session(request, 'show_editorial') self.show_editorial = self.GET_with_session(request, 'show_editorial')
self.have_editorial = self.GET_with_session(request, 'have_editorial')
self.search_query = None self.search_query = None
self.category = None self.category = None
@ -573,44 +574,33 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
return generic_message(request, 'FTS syntax error', e.args[1], status=400) return generic_message(request, 'FTS syntax error', e.args[1], status=400)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
to_update = ('hide_solved', 'show_types', 'full_text') to_update = ('hide_solved', 'show_types', 'full_text',
'show_editorial', 'have_editorial')
for key in to_update: for key in to_update:
if key in request.GET: if key in request.GET:
val = request.GET.get(key) == '1' val = request.GET.get(key) == '1'
request.session[key] = val request.session[key] = val
else: else:
request.session.pop(key, None) request.session[key] = False
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
class ProblemFeed(FeedView): class ProblemFeed(ProblemList):
model = Problem model = Problem
context_object_name = 'problems' context_object_name = 'problems'
paginate_by = 50 paginate_by = 50
title = _('Problem feed') title = _('Problem feed')
feed_type = None
@cached_property def GET_with_session(self, request, key):
def profile(self): if not request.GET:
if not self.request.user.is_authenticated: return request.session.get(key, key=='hide_solved')
return None return request.GET.get(key, None) == '1'
return self.request.profile
def get_unsolved_queryset(self): def get_paginator(self, queryset, per_page, orphans=0,
filter = Q(is_public=True) allow_empty_first_page=True, **kwargs):
if self.profile is not None: return DiggPaginator(queryset, per_page, body=6, padding=2,
filter |= Q(authors=self.profile) orphans=orphans, allow_empty_first_page=allow_empty_first_page, **kwargs)
filter |= Q(curators=self.profile)
filter |= Q(testers=self.profile)
queryset = Problem.objects.filter(filter).select_related('group').defer('description')
if not self.request.user.has_perm('see_organization_problem'):
filter = Q(is_organization_private=False)
if self.profile is not None:
filter |= Q(organizations__in=self.profile.organizations.all())
queryset = queryset.filter(filter)
if self.profile is not None:
queryset = queryset.exclude(id__in=Submission.objects.filter(user=self.profile, points=F('problem__points'))
.values_list('problem__id', flat=True))
return queryset.distinct()
# arr = [[], [], ..] # arr = [[], [], ..]
def merge_recommendation(self, arr): def merge_recommendation(self, arr):
@ -636,31 +626,50 @@ class ProblemFeed(FeedView):
stop = False stop = False
return res return res
def get_queryset(self): def get_queryset(self):
queryset = self.get_unsolved_queryset() queryset = super(ProblemFeed, self).get_queryset()
if self.have_editorial:
queryset = queryset.filter(has_public_editorial=1)
user = self.request.profile user = self.request.profile
if self.feed_type == 'new':
return queryset.order_by('-date')
if not settings.ML_OUTPUT_PATH or not user: if not settings.ML_OUTPUT_PATH or not user:
return queryset.order_by('?') return queryset.order_by('?')
cl_model = CollabFilter() cf_model = CollabFilter('collab_filter')
dot_rec = cl_model.user_recommendations(user, queryset, cl_model.DOT, 100) cf_time_model = CollabFilter('collab_filter_time')
cosine_rec = cl_model.user_recommendations(user, queryset, cl_model.COSINE, 100) hot_problems_recommendations = [
hot_problems_rec = [problem for problem in hot_problems(timedelta(days=7), 10) problem for problem in hot_problems(timedelta(days=7), 20)
if problem in queryset] if problem in queryset
]
q = self.merge_recommendation([dot_rec, cosine_rec, hot_problems_rec]) q = self.merge_recommendation([
cf_model.user_recommendations(user, queryset, cf_model.DOT, 100),
cf_model.user_recommendations(user, queryset, cf_model.COSINE, 100),
cf_time_model.user_recommendations(user, queryset, cf_time_model.COSINE, 100),
cf_time_model.user_recommendations(user, queryset, cf_time_model.DOT, 100),
hot_problems_recommendations
])
return q return q
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ProblemFeed, self).get_context_data(**kwargs) context = super(ProblemFeed, self).get_context_data(**kwargs)
context['first_page_href'] = self.request.path context['first_page_href'] = self.request.path
context['page_prefix'] = '?page=' context['page_prefix'] = '?page='
context['feed_type'] = 'problem' context['page_type'] = 'feed'
context['title'] = self.title context['title'] = self.title
context['feed_type'] = self.feed_type
return context return context
def get(self, request, *args, **kwargs):
if request.in_contest_mode:
return HttpResponseRedirect(reverse('problem_list'))
return super(ProblemFeed, self).get(request, *args, **kwargs)
class LanguageTemplateAjax(View): class LanguageTemplateAjax(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):

View file

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: lqdoj2\n" "Project-Id-Version: lqdoj2\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-22 04:37+0700\n" "POT-Creation-Date: 2022-04-13 12:01+0700\n"
"PO-Revision-Date: 2021-07-20 03:44\n" "PO-Revision-Date: 2021-07-20 03:44\n"
"Last-Translator: Icyene\n" "Last-Translator: Icyene\n"
"Language-Team: Vietnamese\n" "Language-Team: Vietnamese\n"
@ -112,27 +112,27 @@ msgstr "Đăng nhập"
msgid "Home" msgid "Home"
msgstr "Trang chủ" msgstr "Trang chủ"
#: judge/admin/comments.py:40 #: judge/admin/comments.py:41
#, python-format #, python-format
msgid "%d comment successfully hidden." msgid "%d comment successfully hidden."
msgid_plural "%d comments successfully hidden." msgid_plural "%d comments successfully hidden."
msgstr[0] "Đã ẩn %d bình luận." msgstr[0] "Đã ẩn %d bình luận."
#: judge/admin/comments.py:43 #: judge/admin/comments.py:44
msgid "Hide comments" msgid "Hide comments"
msgstr "Ẩn bình luận" msgstr "Ẩn bình luận"
#: judge/admin/comments.py:47 #: judge/admin/comments.py:48
#, python-format #, python-format
msgid "%d comment successfully unhidden." msgid "%d comment successfully unhidden."
msgid_plural "%d comments successfully unhidden." msgid_plural "%d comments successfully unhidden."
msgstr[0] "Không ẩn được %d bình luận." msgstr[0] "Không ẩn được %d bình luận."
#: judge/admin/comments.py:50 #: judge/admin/comments.py:51
msgid "Unhide comments" msgid "Unhide comments"
msgstr "Hiện bình luận" msgstr "Hiện bình luận"
#: judge/admin/comments.py:58 #: judge/admin/comments.py:59
msgid "Associated page" msgid "Associated page"
msgstr "Trang liên kết" msgstr "Trang liên kết"
@ -142,8 +142,8 @@ msgstr ""
#: judge/admin/contest.py:66 templates/contest/clarification.html:42 #: judge/admin/contest.py:66 templates/contest/clarification.html:42
#: templates/contest/contest.html:83 templates/contest/moss.html:43 #: templates/contest/contest.html:83 templates/contest/moss.html:43
#: templates/problem/list.html:214 templates/problem/list.html:232 #: templates/problem/list.html:189 templates/problem/list.html:205
#: templates/problem/list.html:350 templates/user/user-problems.html:56 #: templates/problem/list.html:323 templates/user/user-problems.html:56
#: templates/user/user-problems.html:98 #: templates/user/user-problems.html:98
msgid "Problem" msgid "Problem"
msgstr "Bài tập" msgstr "Bài tập"
@ -173,7 +173,7 @@ msgstr ""
msgid "Access" msgid "Access"
msgstr "Truy cập" msgstr "Truy cập"
#: judge/admin/contest.py:127 judge/admin/problem.py:131 #: judge/admin/contest.py:127 judge/admin/problem.py:133
msgid "Justice" msgid "Justice"
msgstr "Xử phạt" msgstr "Xử phạt"
@ -225,7 +225,7 @@ msgstr "ảo"
msgid "link path" msgid "link path"
msgstr "đường dẫn" msgstr "đường dẫn"
#: judge/admin/interface.py:65 templates/blog/list.html:114 #: judge/admin/interface.py:65
msgid "Content" msgid "Content"
msgstr "Nội dung" msgstr "Nội dung"
@ -237,78 +237,90 @@ msgstr "Tổng kết"
msgid "object" msgid "object"
msgstr "" msgstr ""
#: judge/admin/organization.py:34 judge/admin/problem.py:171 #: judge/admin/organization.py:34 judge/admin/problem.py:173
#: judge/admin/profile.py:80 #: judge/admin/profile.py:80
msgid "View on site" msgid "View on site"
msgstr "Xem trên trang" msgstr "Xem trên trang"
#: judge/admin/problem.py:28 #: judge/admin/problem.py:30
msgid "Describe the changes you made (optional)" msgid "Describe the changes you made (optional)"
msgstr "Mô tả các thay đổi (tùy chọn)" msgstr "Mô tả các thay đổi (tùy chọn)"
#: judge/admin/problem.py:126 #: judge/admin/problem.py:128
msgid "Social Media" msgid "Social Media"
msgstr "Mạng Xã Hội" msgstr "Mạng Xã Hội"
#: judge/admin/problem.py:127 #: judge/admin/problem.py:129
msgid "Taxonomy" msgid "Taxonomy"
msgstr "" msgstr ""
#: judge/admin/problem.py:128 judge/admin/problem.py:258 #: judge/admin/problem.py:130 judge/admin/problem.py:284
#: templates/contest/contest.html:84 templates/problem/data.html:469 #: templates/contest/contest.html:84 templates/problem/data.html:469
#: templates/problem/list.html:222 templates/problem/list.html:248 #: templates/problem/list.html:195 templates/problem/list.html:221
#: templates/user/base-users-table.html:10 templates/user/user-about.html:36 #: templates/user/base-users-table.html:10 templates/user/user-about.html:36
#: templates/user/user-about.html:52 templates/user/user-problems.html:58 #: templates/user/user-about.html:52 templates/user/user-problems.html:58
msgid "Points" msgid "Points"
msgstr "Điểm" msgstr "Điểm"
#: judge/admin/problem.py:129 #: judge/admin/problem.py:131
msgid "Limits" msgid "Limits"
msgstr "Giới hạn" msgstr "Giới hạn"
#: judge/admin/problem.py:130 judge/admin/submission.py:232 #: judge/admin/problem.py:132 judge/admin/submission.py:232
#: templates/stats/base.html:14 templates/submission/list.html:322 #: templates/stats/base.html:14 templates/submission/list.html:322
msgid "Language" msgid "Language"
msgstr "Ngôn ngữ" msgstr "Ngôn ngữ"
#: judge/admin/problem.py:132 #: judge/admin/problem.py:134
msgid "History" msgid "History"
msgstr "Lịch sử" msgstr "Lịch sử"
#: judge/admin/problem.py:168 #: judge/admin/problem.py:170
msgid "Authors" msgid "Authors"
msgstr "Các tác giả" msgstr "Các tác giả"
#: judge/admin/problem.py:183 #: judge/admin/problem.py:185
#, python-format #, python-format
msgid "%d problem successfully marked as public." msgid "%d problem successfully marked as public."
msgid_plural "%d problems successfully marked as public." msgid_plural "%d problems successfully marked as public."
msgstr[0] "%d bài tập đã được đánh dấu công khai." msgstr[0] "%d bài tập đã được đánh dấu công khai."
#: judge/admin/problem.py:187 #: judge/admin/problem.py:189
msgid "Mark problems as public" msgid "Mark problems as public"
msgstr "Công khai bài tập" msgstr "Công khai bài tập"
#: judge/admin/problem.py:193 #: judge/admin/problem.py:195
#, python-format #, python-format
msgid "%d problem successfully marked as private." msgid "%d problem successfully marked as private."
msgid_plural "%d problems successfully marked as private." msgid_plural "%d problems successfully marked as private."
msgstr[0] "%d bài tập đã được đánh dấu riêng tư." msgstr[0] "%d bài tập đã được đánh dấu riêng tư."
#: judge/admin/problem.py:197 #: judge/admin/problem.py:199
msgid "Mark problems as private" msgid "Mark problems as private"
msgstr "Đánh dấu các bài tập là riêng tư" msgstr "Đánh dấu các bài tập là riêng tư"
#: judge/admin/problem.py:253 judge/admin/submission.py:200 #: judge/admin/problem.py:279 judge/admin/submission.py:200
#: templates/problem/list.html:216 templates/problem/list.html:236 #: templates/problem/list.html:190 templates/problem/list.html:209
msgid "Problem code" msgid "Problem code"
msgstr "Mã bài" msgstr "Mã bài"
#: judge/admin/problem.py:263 judge/admin/submission.py:205 #: judge/admin/problem.py:289 judge/admin/submission.py:205
msgid "Problem name" msgid "Problem name"
msgstr "Tên bài" msgstr "Tên bài"
#: judge/admin/problem.py:268 #: judge/admin/problem.py:294
#, fuzzy
#| msgid "contest rating"
msgid "Voter rating"
msgstr "rating kỳ thi"
#: judge/admin/problem.py:299
#, fuzzy
#| msgid "Total points"
msgid "Voter point"
msgstr "Tổng điểm"
#: judge/admin/problem.py:304
msgid "Vote" msgid "Vote"
msgstr "" msgstr ""
@ -357,7 +369,7 @@ msgstr "Các bài tập không được cho phép"
msgid "These problems are NOT allowed to be submitted in this language" msgid "These problems are NOT allowed to be submitted in this language"
msgstr "Các bài này không cho phép sử dụng ngôn ngữ này" msgstr "Các bài này không cho phép sử dụng ngôn ngữ này"
#: judge/admin/runtime.py:83 templates/problem/list.html:352 #: judge/admin/runtime.py:83 templates/problem/list.html:325
msgid "Description" msgid "Description"
msgstr "Mô tả" msgstr "Mô tả"
@ -417,7 +429,7 @@ msgstr "Tính điểm lại cái bài nộp"
#: judge/admin/submission.py:215 templates/notification/list.html:15 #: judge/admin/submission.py:215 templates/notification/list.html:15
#: templates/organization/requests/log.html:10 #: templates/organization/requests/log.html:10
#: templates/organization/requests/pending.html:13 #: templates/organization/requests/pending.html:13
#: templates/problem/list.html:351 #: templates/problem/list.html:324
#: templates/submission/status-testcases.html:125 #: templates/submission/status-testcases.html:125
#: templates/submission/status-testcases.html:127 #: templates/submission/status-testcases.html:127
msgid "Time" msgid "Time"
@ -528,7 +540,7 @@ msgstr "Two Factor Authentication phải chứa 6 chữ số."
msgid "Invalid Two Factor Authentication token." msgid "Invalid Two Factor Authentication token."
msgstr "Token Two Factor Authentication không hợp lệ." msgstr "Token Two Factor Authentication không hợp lệ."
#: judge/forms.py:148 judge/models/problem.py:97 #: judge/forms.py:148 judge/models/problem.py:98
msgid "Problem code must be ^[a-z0-9]+$" msgid "Problem code must be ^[a-z0-9]+$"
msgstr "Mã bài phải có dạng ^[a-z0-9]+$" msgstr "Mã bài phải có dạng ^[a-z0-9]+$"
@ -591,7 +603,7 @@ msgstr "người bình luận"
msgid "associated page" msgid "associated page"
msgstr "trang tương ứng" msgstr "trang tương ứng"
#: judge/models/comment.py:46 judge/models/problem.py:493 #: judge/models/comment.py:46 judge/models/problem.py:494
msgid "votes" msgid "votes"
msgstr "bình chọn" msgstr "bình chọn"
@ -611,7 +623,7 @@ msgstr "bình luận"
msgid "comments" msgid "comments"
msgstr "" msgstr ""
#: judge/models/comment.py:139 judge/models/problem.py:463 #: judge/models/comment.py:139 judge/models/problem.py:464
#, python-format #, python-format
msgid "Editorial for %s" msgid "Editorial for %s"
msgstr "" msgstr ""
@ -729,7 +741,7 @@ msgstr ""
msgid "description" msgid "description"
msgstr "mô tả" msgstr "mô tả"
#: judge/models/contest.py:72 judge/models/problem.py:410 #: judge/models/contest.py:72 judge/models/problem.py:411
#: judge/models/runtime.py:138 #: judge/models/runtime.py:138
msgid "problems" msgid "problems"
msgstr "bài tập" msgstr "bài tập"
@ -742,12 +754,12 @@ msgstr "thời gian bắt đầu"
msgid "end time" msgid "end time"
msgstr "thời gian kết thúc" msgstr "thời gian kết thúc"
#: judge/models/contest.py:75 judge/models/problem.py:118 #: judge/models/contest.py:75 judge/models/problem.py:119
#: judge/models/problem.py:434 #: judge/models/problem.py:435
msgid "time limit" msgid "time limit"
msgstr "giới hạn thời gian" msgstr "giới hạn thời gian"
#: judge/models/contest.py:76 judge/models/problem.py:136 #: judge/models/contest.py:76 judge/models/problem.py:137
msgid "publicly visible" msgid "publicly visible"
msgstr "công khai" msgstr "công khai"
@ -846,12 +858,12 @@ msgstr ""
"kỳ thi, hãy bỏ đánh dấu ô này và chấm lại tất cả các bài." "kỳ thi, hãy bỏ đánh dấu ô này và chấm lại tất cả các bài."
#: judge/models/contest.py:110 judge/models/interface.py:77 #: judge/models/contest.py:110 judge/models/interface.py:77
#: judge/models/problem.py:157 #: judge/models/problem.py:158
msgid "private to organizations" msgid "private to organizations"
msgstr "riêng tư với các tổ chức" msgstr "riêng tư với các tổ chức"
#: judge/models/contest.py:111 judge/models/interface.py:75 #: judge/models/contest.py:111 judge/models/interface.py:75
#: judge/models/problem.py:155 judge/models/profile.py:77 #: judge/models/problem.py:156 judge/models/profile.py:77
msgid "organizations" msgid "organizations"
msgstr "tổ chức" msgstr "tổ chức"
@ -859,7 +871,7 @@ msgstr "tổ chức"
msgid "If private, only these organizations may see the contest" msgid "If private, only these organizations may see the contest"
msgstr "Nếu riêng tư, chỉ những tổ chức này thấy được kỳ thi" msgstr "Nếu riêng tư, chỉ những tổ chức này thấy được kỳ thi"
#: judge/models/contest.py:113 judge/models/problem.py:145 #: judge/models/contest.py:113 judge/models/problem.py:146
msgid "OpenGraph image" msgid "OpenGraph image"
msgstr "Hình ảnh OpenGraph" msgstr "Hình ảnh OpenGraph"
@ -880,7 +892,7 @@ msgstr "số lượng thí sinh thi trực tiếp"
msgid "contest summary" msgid "contest summary"
msgstr "tổng kết kỳ thi" msgstr "tổng kết kỳ thi"
#: judge/models/contest.py:121 judge/models/problem.py:147 #: judge/models/contest.py:121 judge/models/problem.py:148
msgid "Plain-text, shown in meta description tag, e.g. for social media." msgid "Plain-text, shown in meta description tag, e.g. for social media."
msgstr "" msgstr ""
@ -896,7 +908,7 @@ msgstr ""
"Mật khẩu truy cập cho các thí sinh muốn tham gia kỳ thi. Để trống nếu không " "Mật khẩu truy cập cho các thí sinh muốn tham gia kỳ thi. Để trống nếu không "
"dùng." "dùng."
#: judge/models/contest.py:125 judge/models/problem.py:141 #: judge/models/contest.py:125 judge/models/problem.py:142
msgid "personae non gratae" msgid "personae non gratae"
msgstr "" msgstr ""
@ -1041,14 +1053,14 @@ msgid "contest participations"
msgstr "lần tham gia kỳ thi" msgstr "lần tham gia kỳ thi"
#: judge/models/contest.py:491 judge/models/contest.py:513 #: judge/models/contest.py:491 judge/models/contest.py:513
#: judge/models/contest.py:554 judge/models/problem.py:409 #: judge/models/contest.py:554 judge/models/problem.py:410
#: judge/models/problem.py:414 judge/models/problem.py:432 #: judge/models/problem.py:415 judge/models/problem.py:433
#: judge/models/problem_data.py:40 #: judge/models/problem_data.py:40
msgid "problem" msgid "problem"
msgstr "bài tập" msgstr "bài tập"
#: judge/models/contest.py:493 judge/models/contest.py:517 #: judge/models/contest.py:493 judge/models/contest.py:517
#: judge/models/problem.py:129 #: judge/models/problem.py:130
msgid "points" msgid "points"
msgstr "điểm" msgstr "điểm"
@ -1180,7 +1192,7 @@ msgstr "mục cha"
msgid "post title" msgid "post title"
msgstr "tiêu đề bài đăng" msgstr "tiêu đề bài đăng"
#: judge/models/interface.py:67 judge/models/problem.py:452 #: judge/models/interface.py:67 judge/models/problem.py:453
msgid "authors" msgid "authors"
msgstr "tác giả" msgstr "tác giả"
@ -1188,7 +1200,7 @@ msgstr "tác giả"
msgid "slug" msgid "slug"
msgstr "slug" msgstr "slug"
#: judge/models/interface.py:69 judge/models/problem.py:450 #: judge/models/interface.py:69 judge/models/problem.py:451
msgid "public visibility" msgid "public visibility"
msgstr "khả năng hiển thị công khai" msgstr "khả năng hiển thị công khai"
@ -1252,287 +1264,287 @@ msgstr "thời gian gửi"
msgid "messages in the thread" msgid "messages in the thread"
msgstr "tin nhắn trong chuỗi" msgstr "tin nhắn trong chuỗi"
#: judge/models/problem.py:26 #: judge/models/problem.py:27
msgid "problem category ID" msgid "problem category ID"
msgstr "mã của nhóm bài" msgstr "mã của nhóm bài"
#: judge/models/problem.py:27 #: judge/models/problem.py:28
msgid "problem category name" msgid "problem category name"
msgstr "tên nhóm bài" msgstr "tên nhóm bài"
#: judge/models/problem.py:34 #: judge/models/problem.py:35
msgid "problem type" msgid "problem type"
msgstr "dạng bài" msgstr "dạng bài"
#: judge/models/problem.py:35 judge/models/problem.py:113 #: judge/models/problem.py:36 judge/models/problem.py:114
msgid "problem types" msgid "problem types"
msgstr "dạng bài" msgstr "dạng bài"
#: judge/models/problem.py:39 #: judge/models/problem.py:40
msgid "problem group ID" msgid "problem group ID"
msgstr "mã của nhóm bài" msgstr "mã của nhóm bài"
#: judge/models/problem.py:40 #: judge/models/problem.py:41
msgid "problem group name" msgid "problem group name"
msgstr "tên nhóm bài" msgstr "tên nhóm bài"
#: judge/models/problem.py:47 judge/models/problem.py:116 #: judge/models/problem.py:48 judge/models/problem.py:117
msgid "problem group" msgid "problem group"
msgstr "nhóm bài" msgstr "nhóm bài"
#: judge/models/problem.py:48 #: judge/models/problem.py:49
msgid "problem groups" msgid "problem groups"
msgstr "nhóm bài" msgstr "nhóm bài"
#: judge/models/problem.py:52 #: judge/models/problem.py:53
msgid "key" msgid "key"
msgstr "" msgstr ""
#: judge/models/problem.py:54 #: judge/models/problem.py:55
msgid "link" msgid "link"
msgstr "đường dẫn" msgstr "đường dẫn"
#: judge/models/problem.py:55 #: judge/models/problem.py:56
msgid "full name" msgid "full name"
msgstr "tên đầy đủ" msgstr "tên đầy đủ"
#: judge/models/problem.py:56 judge/models/profile.py:33 #: judge/models/problem.py:57 judge/models/profile.py:33
#: judge/models/runtime.py:24 #: judge/models/runtime.py:24
msgid "short name" msgid "short name"
msgstr "tên ngắn" msgstr "tên ngắn"
#: judge/models/problem.py:57 #: judge/models/problem.py:58
msgid "Displayed on pages under this license" msgid "Displayed on pages under this license"
msgstr "Được hiển thị trên các trang theo giấy phép này" msgstr "Được hiển thị trên các trang theo giấy phép này"
#: judge/models/problem.py:58 #: judge/models/problem.py:59
msgid "icon" msgid "icon"
msgstr "icon" msgstr "icon"
#: judge/models/problem.py:58 #: judge/models/problem.py:59
msgid "URL to the icon" msgid "URL to the icon"
msgstr "Đường dẫn icon" msgstr "Đường dẫn icon"
#: judge/models/problem.py:59 #: judge/models/problem.py:60
msgid "license text" msgid "license text"
msgstr "văn bản giấy phép" msgstr "văn bản giấy phép"
#: judge/models/problem.py:68 #: judge/models/problem.py:69
msgid "license" msgid "license"
msgstr "" msgstr ""
#: judge/models/problem.py:69 #: judge/models/problem.py:70
msgid "licenses" msgid "licenses"
msgstr "" msgstr ""
#: judge/models/problem.py:96 #: judge/models/problem.py:97
msgid "problem code" msgid "problem code"
msgstr "" msgstr ""
#: judge/models/problem.py:98 #: judge/models/problem.py:99
msgid "A short, unique code for the problem, used in the url after /problem/" msgid "A short, unique code for the problem, used in the url after /problem/"
msgstr "" msgstr ""
#: judge/models/problem.py:100 #: judge/models/problem.py:101
msgid "problem name" msgid "problem name"
msgstr "" msgstr ""
#: judge/models/problem.py:101 #: judge/models/problem.py:102
msgid "The full name of the problem, as shown in the problem list." msgid "The full name of the problem, as shown in the problem list."
msgstr "" msgstr ""
#: judge/models/problem.py:103 #: judge/models/problem.py:104
msgid "problem body" msgid "problem body"
msgstr "" msgstr ""
#: judge/models/problem.py:104 #: judge/models/problem.py:105
msgid "creators" msgid "creators"
msgstr "" msgstr ""
#: judge/models/problem.py:105 #: judge/models/problem.py:106
msgid "These users will be able to edit the problem, and be listed as authors." msgid "These users will be able to edit the problem, and be listed as authors."
msgstr "" msgstr ""
#: judge/models/problem.py:107 #: judge/models/problem.py:108
msgid "curators" msgid "curators"
msgstr "" msgstr ""
#: judge/models/problem.py:108 #: judge/models/problem.py:109
msgid "" msgid ""
"These users will be able to edit the problem, but not be listed as authors." "These users will be able to edit the problem, but not be listed as authors."
msgstr "" msgstr ""
#: judge/models/problem.py:110 #: judge/models/problem.py:111
msgid "testers" msgid "testers"
msgstr "" msgstr ""
#: judge/models/problem.py:112 #: judge/models/problem.py:113
msgid "These users will be able to view the private problem, but not edit it." msgid "These users will be able to view the private problem, but not edit it."
msgstr "" msgstr ""
#: judge/models/problem.py:114 #: judge/models/problem.py:115
msgid "The type of problem, as shown on the problem's page." msgid "The type of problem, as shown on the problem's page."
msgstr "" msgstr ""
#: judge/models/problem.py:117 #: judge/models/problem.py:118
msgid "The group of problem, shown under Category in the problem list." msgid "The group of problem, shown under Category in the problem list."
msgstr "" msgstr ""
#: judge/models/problem.py:119 #: judge/models/problem.py:120
msgid "" msgid ""
"The time limit for this problem, in seconds. Fractional seconds (e.g. 1.5) " "The time limit for this problem, in seconds. Fractional seconds (e.g. 1.5) "
"are supported." "are supported."
msgstr "" msgstr ""
#: judge/models/problem.py:123 judge/models/problem.py:437 #: judge/models/problem.py:124 judge/models/problem.py:438
msgid "memory limit" msgid "memory limit"
msgstr "" msgstr ""
#: judge/models/problem.py:124 #: judge/models/problem.py:125
msgid "" msgid ""
"The memory limit for this problem, in kilobytes (e.g. 64mb = 65536 " "The memory limit for this problem, in kilobytes (e.g. 64mb = 65536 "
"kilobytes)." "kilobytes)."
msgstr "" msgstr ""
#: judge/models/problem.py:130 #: judge/models/problem.py:131
msgid "" msgid ""
"Points awarded for problem completion. Points are displayed with a 'p' " "Points awarded for problem completion. Points are displayed with a 'p' "
"suffix if partial." "suffix if partial."
msgstr "" msgstr ""
#: judge/models/problem.py:133 #: judge/models/problem.py:134
msgid "allows partial points" msgid "allows partial points"
msgstr "" msgstr ""
#: judge/models/problem.py:134 #: judge/models/problem.py:135
msgid "allowed languages" msgid "allowed languages"
msgstr "" msgstr ""
#: judge/models/problem.py:135 #: judge/models/problem.py:136
msgid "List of allowed submission languages." msgid "List of allowed submission languages."
msgstr "" msgstr ""
#: judge/models/problem.py:137 #: judge/models/problem.py:138
msgid "manually managed" msgid "manually managed"
msgstr "" msgstr ""
#: judge/models/problem.py:138 #: judge/models/problem.py:139
msgid "Whether judges should be allowed to manage data or not." msgid "Whether judges should be allowed to manage data or not."
msgstr "" msgstr ""
#: judge/models/problem.py:139 #: judge/models/problem.py:140
msgid "date of publishing" msgid "date of publishing"
msgstr "" msgstr ""
#: judge/models/problem.py:140 #: judge/models/problem.py:141
msgid "" msgid ""
"Doesn't have magic ability to auto-publish due to backward compatibility" "Doesn't have magic ability to auto-publish due to backward compatibility"
msgstr "" msgstr ""
#: judge/models/problem.py:142 #: judge/models/problem.py:143
msgid "Bans the selected users from submitting to this problem." msgid "Bans the selected users from submitting to this problem."
msgstr "" msgstr ""
#: judge/models/problem.py:144 #: judge/models/problem.py:145
msgid "The license under which this problem is published." msgid "The license under which this problem is published."
msgstr "" msgstr ""
#: judge/models/problem.py:146 #: judge/models/problem.py:147
msgid "problem summary" msgid "problem summary"
msgstr "" msgstr ""
#: judge/models/problem.py:148 #: judge/models/problem.py:149
msgid "number of users" msgid "number of users"
msgstr "" msgstr ""
#: judge/models/problem.py:149 #: judge/models/problem.py:150
msgid "The number of users who solved the problem." msgid "The number of users who solved the problem."
msgstr "" msgstr ""
#: judge/models/problem.py:150 #: judge/models/problem.py:151
msgid "solve rate" msgid "solve rate"
msgstr "" msgstr ""
#: judge/models/problem.py:156 #: judge/models/problem.py:157
msgid "If private, only these organizations may see the problem." msgid "If private, only these organizations may see the problem."
msgstr "" msgstr ""
#: judge/models/problem.py:415 judge/models/problem.py:433 #: judge/models/problem.py:416 judge/models/problem.py:434
#: judge/models/runtime.py:111 #: judge/models/runtime.py:111
msgid "language" msgid "language"
msgstr "" msgstr ""
#: judge/models/problem.py:416 #: judge/models/problem.py:417
msgid "translated name" msgid "translated name"
msgstr "" msgstr ""
#: judge/models/problem.py:417 #: judge/models/problem.py:418
msgid "translated description" msgid "translated description"
msgstr "" msgstr ""
#: judge/models/problem.py:421 #: judge/models/problem.py:422
msgid "problem translation" msgid "problem translation"
msgstr "" msgstr ""
#: judge/models/problem.py:422 #: judge/models/problem.py:423
msgid "problem translations" msgid "problem translations"
msgstr "" msgstr ""
#: judge/models/problem.py:426 #: judge/models/problem.py:427
msgid "clarified problem" msgid "clarified problem"
msgstr "" msgstr ""
#: judge/models/problem.py:427 #: judge/models/problem.py:428
msgid "clarification body" msgid "clarification body"
msgstr "" msgstr ""
#: judge/models/problem.py:428 #: judge/models/problem.py:429
msgid "clarification timestamp" msgid "clarification timestamp"
msgstr "" msgstr ""
#: judge/models/problem.py:443 #: judge/models/problem.py:444
msgid "language-specific resource limit" msgid "language-specific resource limit"
msgstr "" msgstr ""
#: judge/models/problem.py:444 #: judge/models/problem.py:445
msgid "language-specific resource limits" msgid "language-specific resource limits"
msgstr "" msgstr ""
#: judge/models/problem.py:448 #: judge/models/problem.py:449
msgid "associated problem" msgid "associated problem"
msgstr "" msgstr ""
#: judge/models/problem.py:451 #: judge/models/problem.py:452
msgid "publish date" msgid "publish date"
msgstr "" msgstr ""
#: judge/models/problem.py:453 #: judge/models/problem.py:454
msgid "editorial content" msgid "editorial content"
msgstr "nội dung lời giải" msgstr "nội dung lời giải"
#: judge/models/problem.py:469 #: judge/models/problem.py:470
msgid "solution" msgid "solution"
msgstr "lời giải" msgstr "lời giải"
#: judge/models/problem.py:470 #: judge/models/problem.py:471
msgid "solutions" msgid "solutions"
msgstr "lời giải" msgstr "lời giải"
#: judge/models/problem.py:475 #: judge/models/problem.py:476
#, fuzzy #, fuzzy
#| msgid "point value" #| msgid "point value"
msgid "proposed point value" msgid "proposed point value"
msgstr "điểm" msgstr "điểm"
#: judge/models/problem.py:476 #: judge/models/problem.py:477
msgid "The amount of points you think this problem deserves." msgid "The amount of points you think this problem deserves."
msgstr "" msgstr ""
#: judge/models/problem.py:486 #: judge/models/problem.py:487
msgid "The time this vote was cast" msgid "The time this vote was cast"
msgstr "" msgstr ""
#: judge/models/problem.py:492 #: judge/models/problem.py:493
msgid "vote" msgid "vote"
msgstr "" msgstr ""
@ -2386,16 +2398,12 @@ msgid "Page %d of Posts"
msgstr "Trang %d" msgstr "Trang %d"
#: judge/views/blog.py:134 #: judge/views/blog.py:134
#, fuzzy
#| msgid "Ticket title"
msgid "Ticket feed" msgid "Ticket feed"
msgstr "Tiêu đề báo cáo" msgstr "Báo cáo"
#: judge/views/blog.py:152 #: judge/views/blog.py:152
#, fuzzy
#| msgid "Comment body"
msgid "Comment feed" msgid "Comment feed"
msgstr "Nội dung bình luận" msgstr "Bình luận"
#: judge/views/comment.py:28 #: judge/views/comment.py:28
msgid "Messing around, are we?" msgid "Messing around, are we?"
@ -2710,42 +2718,40 @@ msgstr "Hướng dẫn cho {0}"
msgid "Editorial for <a href=\"{1}\">{0}</a>" msgid "Editorial for <a href=\"{1}\">{0}</a>"
msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>" msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>"
#: judge/views/problem.py:342 templates/blog/list.html:121 #: judge/views/problem.py:342 templates/contest/contest.html:79
#: templates/contest/contest.html:79 templates/user/user-about.html:28 #: templates/user/user-about.html:28 templates/user/user-tabs.html:5
#: templates/user/user-tabs.html:5 templates/user/users-table.html:29 #: templates/user/users-table.html:29
msgid "Problems" msgid "Problems"
msgstr "Bài tập" msgstr "Bài tập"
#: judge/views/problem.py:589 #: judge/views/problem.py:592
#, fuzzy
#| msgid "Problem code"
msgid "Problem feed" msgid "Problem feed"
msgstr "Mã bài" msgstr "Bài tập"
#: judge/views/problem.py:685 #: judge/views/problem.py:731
msgid "Banned from submitting" msgid "Banned from submitting"
msgstr "Bị cấm nộp bài" msgstr "Bị cấm nộp bài"
#: judge/views/problem.py:686 #: judge/views/problem.py:732
msgid "" msgid ""
"You have been declared persona non grata for this problem. You are " "You have been declared persona non grata for this problem. You are "
"permanently barred from submitting this problem." "permanently barred from submitting this problem."
msgstr "Bạn đã bị cấm nộp bài này." msgstr "Bạn đã bị cấm nộp bài này."
#: judge/views/problem.py:700 #: judge/views/problem.py:746
msgid "Too many submissions" msgid "Too many submissions"
msgstr "Quá nhiều lần nộp" msgstr "Quá nhiều lần nộp"
#: judge/views/problem.py:701 #: judge/views/problem.py:747
msgid "You have exceeded the submission limit for this problem." msgid "You have exceeded the submission limit for this problem."
msgstr "Bạn đã vượt quá số lần nộp cho bài này." msgstr "Bạn đã vượt quá số lần nộp cho bài này."
#: judge/views/problem.py:761 judge/views/problem.py:764 #: judge/views/problem.py:807 judge/views/problem.py:810
#, python-format #, python-format
msgid "Submit to %(problem)s" msgid "Submit to %(problem)s"
msgstr "Nộp bài cho %(problem)s" msgstr "Nộp bài cho %(problem)s"
#: judge/views/problem.py:779 #: judge/views/problem.py:825
msgid "Clone Problem" msgid "Clone Problem"
msgstr "Nhân bản bài tập" msgstr "Nhân bản bài tập"
@ -3228,10 +3234,8 @@ msgstr "Xem bài nộp"
#: templates/admin/judge/problem/change_form.html:19 #: templates/admin/judge/problem/change_form.html:19
#: templates/admin/judge/problem/change_form.html:22 #: templates/admin/judge/problem/change_form.html:22
#, fuzzy
#| msgid "View on site"
msgid "View votes" msgid "View votes"
msgstr "Xem trên trang" msgstr "Xem bình chọn"
#: templates/admin/judge/profile/change_form.html:14 #: templates/admin/judge/profile/change_form.html:14
#: templates/admin/judge/profile/change_form.html:17 #: templates/admin/judge/profile/change_form.html:17
@ -3322,61 +3326,57 @@ msgstr ""
" vào %(time)s\n" " vào %(time)s\n"
" " " "
#: templates/blog/list.html:107 #: templates/blog/list.html:59
msgid "Feed"
msgstr ""
#: templates/blog/list.html:109
msgid "Events"
msgstr "Sự kiện"
#: templates/blog/list.html:117
msgid "News" msgid "News"
msgstr "Tin tức" msgstr "Tin tức"
#: templates/blog/list.html:125 templates/comments/list.html:2 #: templates/blog/list.html:60 templates/comments/list.html:2
msgid "Comments" msgid "Comments"
msgstr "Bình luận" msgstr "Bình luận"
#: templates/blog/list.html:129 #: templates/blog/list.html:61
msgid "Tickets" msgid "Tickets"
msgstr "Báo cáo" msgstr "Báo cáo"
#: templates/blog/list.html:148 #: templates/blog/list.html:62
msgid "Events"
msgstr "Sự kiện"
#: templates/blog/list.html:78
msgid "You have no ticket" msgid "You have no ticket"
msgstr "Bạn không có báo cáo" msgstr "Bạn không có báo cáo"
#: templates/blog/list.html:163 templates/problem/list.html:347 #: templates/blog/list.html:94 templates/problem/list.html:320
#: templates/problem/problem.html:407 #: templates/problem/problem.html:407
msgid "Clarifications" msgid "Clarifications"
msgstr "Thông báo" msgstr "Thông báo"
#: templates/blog/list.html:169 #: templates/blog/list.html:100
msgid "Add" msgid "Add"
msgstr "Thêm mới" msgstr "Thêm mới"
#: templates/blog/list.html:188 templates/problem/list.html:369 #: templates/blog/list.html:119 templates/problem/list.html:342
#: templates/problem/problem.html:418 #: templates/problem/problem.html:418
msgid "No clarifications have been made at this time." msgid "No clarifications have been made at this time."
msgstr "Không có thông báo nào." msgstr "Không có thông báo nào."
#: templates/blog/list.html:196 #: templates/blog/list.html:127
msgid "Ongoing contests" msgid "Ongoing contests"
msgstr "Kỳ thi đang diễn ra" msgstr "Kỳ thi đang diễn ra"
#: templates/blog/list.html:204 #: templates/blog/list.html:135
msgid "Ends in" msgid "Ends in"
msgstr "Còn" msgstr "Còn"
#: templates/blog/list.html:214 #: templates/blog/list.html:145
msgid "Upcoming contests" msgid "Upcoming contests"
msgstr "Kỳ thi sắp diễn ra" msgstr "Kỳ thi sắp diễn ra"
#: templates/blog/list.html:230 #: templates/blog/list.html:161
msgid "Top Rating" msgid "Top Rating"
msgstr "Top Rating" msgstr "Top Rating"
#: templates/blog/list.html:246 #: templates/blog/list.html:177
msgid "Top Score" msgid "Top Score"
msgstr "Top Score" msgstr "Top Score"
@ -3593,7 +3593,7 @@ msgstr "Hôm nay"
msgid "Next" msgid "Next"
msgstr "Tiếp" msgstr "Tiếp"
#: templates/contest/contest-list-tabs.html:21 #: templates/contest/contest-list-tabs.html:21 templates/problem/list.html:174
#: templates/problem/problem-list-tabs.html:5 #: templates/problem/problem-list-tabs.html:5
msgid "List" msgid "List"
msgstr "Danh sách" msgstr "Danh sách"
@ -3714,11 +3714,12 @@ msgstr "Tỷ lệ AC"
#: templates/contest/contest.html:86 templates/contest/list.html:237 #: templates/contest/contest.html:86 templates/contest/list.html:237
#: templates/contest/list.html:291 templates/contest/list.html:371 #: templates/contest/list.html:291 templates/contest/list.html:371
#: templates/problem/list.html:223 templates/problem/list.html:254 #: templates/problem/list.html:196 templates/problem/list.html:227
msgid "Users" msgid "Users"
msgstr "Số lượng" msgstr "Số lượng"
#: templates/contest/contest.html:111 templates/problem/list.html:330 #: templates/contest/contest.html:111 templates/problem/list.html:231
#: templates/problem/list.html:303
msgid "Editorial" msgid "Editorial"
msgstr "Hướng dẫn" msgstr "Hướng dẫn"
@ -3738,7 +3739,7 @@ msgstr ""
msgid "Show" msgid "Show"
msgstr "Hiển thị" msgstr "Hiển thị"
#: templates/contest/list.html:102 templates/problem/list.html:68 #: templates/contest/list.html:102 templates/problem/list.html:76
msgid "Organizations..." msgid "Organizations..."
msgstr "Tổ chức..." msgstr "Tổ chức..."
@ -3864,7 +3865,7 @@ msgstr "Thêm vào đó, chỉ những tổ chức này mới được tham gia
msgid "Only the following organizations may access this contest:" msgid "Only the following organizations may access this contest:"
msgstr "Chỉ những tổ chức sau được tham gia kỳ thi:" msgstr "Chỉ những tổ chức sau được tham gia kỳ thi:"
#: templates/contest/ranking-table.html:9 templates/problem/search-form.html:35 #: templates/contest/ranking-table.html:9 templates/problem/search-form.html:36
msgid "Organization" msgid "Organization"
msgstr "Tổ chức" msgstr "Tổ chức"
@ -4249,32 +4250,40 @@ msgstr ""
"viết hướng dẫn này. <br><br> <b>Chép code từ bài hướng dẫn để nộp bài là " "viết hướng dẫn này. <br><br> <b>Chép code từ bài hướng dẫn để nộp bài là "
"hành vi có thể dẫn đến khóa tài khoản.</b>" "hành vi có thể dẫn đến khóa tài khoản.</b>"
#: templates/problem/list.html:66 #: templates/problem/list.html:74
msgid "Filter by type..." msgid "Filter by type..."
msgstr "Lọc theo dạng..." msgstr "Lọc theo dạng..."
#: templates/problem/list.html:193 #: templates/problem/list.html:173
msgid "Hot problems" msgid "Feed"
msgstr "Bài tập mới" msgstr "Gợi ý"
#: templates/problem/list.html:218 templates/problem/list.html:240 #: templates/problem/list.html:191 templates/problem/list.html:213
#: templates/problem/search-form.html:45 templates/user/user-problems.html:57 #: templates/problem/search-form.html:46 templates/user/user-problems.html:57
msgid "Category" msgid "Category"
msgstr "Nhóm" msgstr "Nhóm"
#: templates/problem/list.html:220 templates/problem/list.html:244 #: templates/problem/list.html:193 templates/problem/list.html:217
msgid "Types" msgid "Types"
msgstr "Dạng" msgstr "Dạng"
#: templates/problem/list.html:251 #: templates/problem/list.html:224
#, python-format #, python-format
msgid "AC %%" msgid "AC %%"
msgstr "AC %%" msgstr "AC %%"
#: templates/problem/list.html:342 #: templates/problem/list.html:315
msgid "Add clarifications" msgid "Add clarifications"
msgstr "Thêm thông báo" msgstr "Thêm thông báo"
#: templates/problem/list.html:351
msgid "FOR YOU"
msgstr "DÀNH CHO BẠN"
#: templates/problem/list.html:354
msgid "NEW"
msgstr "MỚI NHẤT"
#: templates/problem/manage_submission.html:55 #: templates/problem/manage_submission.html:55
msgid "Leave empty to not filter by language" msgid "Leave empty to not filter by language"
msgstr "Để trống nếu không lọc theo ngôn ngữ" msgstr "Để trống nếu không lọc theo ngôn ngữ"
@ -4492,40 +4501,40 @@ msgid "Search problems..."
msgstr "Tìm bài tập..." msgstr "Tìm bài tập..."
#: templates/problem/search-form.html:14 #: templates/problem/search-form.html:14
msgid "Full text search"
msgstr ""
#: templates/problem/search-form.html:21
msgid "Hide solved problems" msgid "Hide solved problems"
msgstr "Ẩn các bài đã giải" msgstr "Ẩn các bài đã giải"
#: templates/problem/search-form.html:27 #: templates/problem/search-form.html:20
msgid "Show problem types" msgid "Show problem types"
msgstr "Hiển thị dạng bài" msgstr "Hiển thị dạng bài"
#: templates/problem/search-form.html:32 #: templates/problem/search-form.html:26
msgid "Show editorial" msgid "Show editorial"
msgstr "Hiển thị hướng dẫn" msgstr "Hiển thị hướng dẫn"
#: templates/problem/search-form.html:48 templates/problem/search-form.html:50 #: templates/problem/search-form.html:32
msgid "Have editorial"
msgstr "Có hướng dẫn"
#: templates/problem/search-form.html:49 templates/problem/search-form.html:51
#: templates/submission/submission-list-tabs.html:4 #: templates/submission/submission-list-tabs.html:4
msgid "All" msgid "All"
msgstr "Tất cả" msgstr "Tất cả"
#: templates/problem/search-form.html:62 #: templates/problem/search-form.html:63
msgid "Problem types" msgid "Problem types"
msgstr "Dạng bài" msgstr "Dạng bài"
#: templates/problem/search-form.html:73 #: templates/problem/search-form.html:74
msgid "Point range" msgid "Point range"
msgstr "Mốc điểm" msgstr "Mốc điểm"
#: templates/problem/search-form.html:79 templates/submission/list.html:331 #: templates/problem/search-form.html:80 templates/submission/list.html:331
#: templates/ticket/list.html:248 #: templates/ticket/list.html:248
msgid "Go" msgid "Go"
msgstr "Lọc" msgstr "Lọc"
#: templates/problem/search-form.html:80 #: templates/problem/search-form.html:81
msgid "Random" msgid "Random"
msgstr "Ngẫu nhiên" msgstr "Ngẫu nhiên"
@ -5340,6 +5349,9 @@ msgstr "Thông tin"
msgid "Check all" msgid "Check all"
msgstr "Chọn tất cả" msgstr "Chọn tất cả"
#~ msgid "Hot problems"
#~ msgstr "Bài tập mới"
#~ msgid "Discuss <a href=\"{1}\">{0}</a>" #~ msgid "Discuss <a href=\"{1}\">{0}</a>"
#~ msgstr "Thảo luận <a href=\"{1}\">{0}</a>" #~ msgstr "Thảo luận <a href=\"{1}\">{0}</a>"

View file

@ -1,6 +1,6 @@
@import "vars"; @import "vars";
.blog-content { .middle-content {
padding-right: 0em; padding-right: 0em;
vertical-align: top; vertical-align: top;
margin-right: 0; margin-right: 0;
@ -32,11 +32,18 @@
} }
} }
.blog-sidebar { .blog-sidebar, .right-sidebar {
width: 100%; width: 100%;
margin-left: auto; margin-left: auto;
} }
.left-sidebar-item.active {
color: green;
.sidebar-icon {
color: green;
}
}
.blog-sidebox { .blog-sidebox {
h3 { h3 {
padding-bottom: 0.25em; padding-bottom: 0.25em;
@ -95,19 +102,21 @@
} }
.left-sidebar-item { .left-sidebar-item {
display: inline-block; display: inline-block;
margin-left: 2em;
} }
.blog-left-sidebar { .left-sidebar {
text-align: right; text-align: right;
padding-right: 1em; padding-right: 1em;
margin-bottom: 1em; margin-bottom: 1em;
border-radius: 7px;
} }
} }
@media (min-width: 800px) { @media (min-width: 800px) {
.blog-content, .blog-sidebar { .middle-content, .blog-sidebar, .right-sidebar {
display: block !important; display: block !important;
} }
.blog-content { .middle-content {
margin-right: 1em !important; margin-right: 1em !important;
} }
@ -115,20 +124,20 @@
display: none; display: none;
} }
#blog-container { #three-col-container {
display: flex; display: flex;
} }
.blog-content { .middle-content {
max-width: 71.5%; max-width: 71.5%;
margin-left: 10%; margin-left: 10%;
} }
.blog-sidebar { .blog-sidebar, .right-sidebar {
width: 18%; width: 18%;
} }
.blog-left-sidebar { .left-sidebar {
width: 8%; width: 8%;
margin-right: 1em; margin-right: 1em;
position: fixed; position: fixed;
@ -203,7 +212,7 @@
color: gray; color: gray;
} }
.blog-left-sidebar { .left-sidebar {
background-color: #f0f1f3; background-color: #f0f1f3;
color: #616161; color: #616161;
} }

6338
resources/fontawesome/fontawesome.css vendored Executable file

File diff suppressed because it is too large Load diff

View file

@ -77,6 +77,7 @@
flex: 26.5%; flex: 26.5%;
max-width: unset; max-width: unset;
padding-top: 0; padding-top: 0;
padding-left: 0;
} }
} }
@ -293,3 +294,39 @@ ul.problem-list {
font-size: 13px; font-size: 13px;
} }
} }
.problem-feed-option {
width: 90%;
margin-left: auto;
margin-right: auto;
padding: 1em;
border-radius: 5px;
margin-bottom: 1em
}
.problem-feed-option-item {
padding: 10px 15px;
border-radius: 2em;
font-weight: bold;
background: lightgray;
margin-right: 1em;
color: gray;
cursor: pointer;
}
.pcodecell {
text-transform: uppercase;
}
.problem-feed-option-item.active {
background: goldenrod;
color: darkblue;
}
@media (max-width: 799px) {
.problem-middle-right {
display: flex;
flex-direction: column-reverse;
}
}

View file

@ -1,21 +1,17 @@
{% extends "base.html" %} {% extends "three-column-content.html" %}
{% block title_row %}{% endblock %} {% block three_col_media %}
{% block title_ruler %}{% endblock %}
{% block media %}
<link rel="alternate" type="application/atom+xml" href="{{ url('blog_atom') }}" title="Atom Blog Feed">
<link rel="alternate" type="application/rss+xml" href="{{ url('blog_rss') }}" title="RSS Blog Feed">
<link rel="alternate" type="application/atom+xml" href="{{ url('comment_atom') }}" title="Atom Comment Feed">
<link rel="alternate" type="application/rss+xml" href="{{ url('comment_rss') }}" title="RSS Comment Feed">
<link rel="alternate" type="application/atom+xml" href="{{ url('problem_atom') }}" title="Atom Problem Feed">
<link rel="alternate" type="application/rss+xml" href="{{ url('problem_rss') }}" title="RSS Problem Feed">
{% include "blog/media-css.html" %} {% include "blog/media-css.html" %}
<style> <style>
@media (max-width: 800px) { @media (max-width: 799px) {
.title { .title {
clear: both; clear: both;
} }
} }
@media (min-width: 800px) {
#event-tab {
display: none;
}
}
.time { .time {
margin-left: 0; margin-left: 0;
} }
@ -36,237 +32,162 @@
#add-clarification:hover { #add-clarification:hover {
color: cyan; color: cyan;
} }
#content {
width: 99%;
margin-left: 0;
}
</style> </style>
{% endblock %} {% endblock %}
{% block js_media %} {% block three_col_js %}
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () { $(document).ready(function () {
$('.time-remaining').each(function () { $('.time-remaining').each(function () {
count_down($(this)); count_down($(this));
}); });
$('.blog-sidebar').hide(); $('.right-sidebar').hide();
$('#blog-tab').find('a').click(function (e) { $('#event-tab').click(function (e) {
e.preventDefault();
$('#blog-tab').addClass('active');
$('#event-tab').removeClass('active');
$('.blog-content').show();
$('.blog-sidebar').hide();
});
$('#event-tab').find('a').click(function (e) {
e.preventDefault(); e.preventDefault();
$('.left-sidebar-item').removeClass('active');
$('#event-tab').addClass('active'); $('#event-tab').addClass('active');
$('#blog-tab').removeClass('active'); $('.middle-content').hide();
$('.blog-content').hide(); $('.right-sidebar').show();
$('.blog-sidebar').show();
}); });
$('.blog-description').on('click', function() {
var max_height = $(this).css('max-height');
if (max_height !== 'fit-content') {
$(this).css('max-height', 'fit-content');
$(this).parent().css('background-image', 'inherit')
.css('padding-bottom', '0.5em');
$(this).css('cursor', 'auto');
}
})
$('.blog-description').each(function() {
if ($(this).prop('scrollHeight') > $(this).height() ) {
$(this).parent().css('background-image', '-webkit-linear-gradient(bottom, gray, lightgray 3%, transparent 8%, transparent 100%)');
$(this).parent().css('padding-bottom', '0');
$(this).css('cursor', 'pointer');
}
});
$('.left-sidebar-item').on('click', function() {
var url = $(this).attr('data-href');
window.location.replace(url);
});
{% if feed_type == 'blog' %}
$('#news-icon').css('color', 'green');
{% elif feed_type == 'problem' %}
$('#problems-icon').css('color', 'green');
{% elif feed_type == 'ticket' %}
$('#tickets-icon').css('color', 'green');
{% elif feed_type == 'comment' %}
$('#comments-icon').css('color', 'green');
{% endif %}
}); });
</script> </script>
{% endblock %} {% endblock %}
{% block body %} {% block left_sidebar %}
{% block before_posts %}{% endblock %} <div class="left-sidebar">
<div id="mobile" class="tabs"> {{ make_tab_item('blog', 'fa fa-rss', url('home'), _('News')) }}
<ul> {{ make_tab_item('comment', 'fa fa-comments', url('comment_feed'), _('Comments')) }}
<li id="blog-tab" class="tab active"><a href="#"> {{ make_tab_item('ticket', 'fa fa-question-circle', url('ticket_feed'), _('Tickets')) }}
<i class="tab-icon fa fa-info-circle"></i> {{ _('Feed') }} {{ make_tab_item('event', 'fa fa-calendar', '#', _('Events')) }}
</a></li>
<li id="event-tab" class="tab"><a href="#"><i class="tab-icon fa fa-rss"></i> {{ _('Events') }}</a></li>
</ul>
</div> </div>
<div id="blog-container">
<div class="blog-left-sidebar">
<h3 class="left-sidebar-header">{{_('Content')}}</h3>
<div class="left-sidebar-item" data-href="{{url('home')}}">
<div class="sidebar-icon" id="news-icon"><i class="fa fa-rss"></i></div>
{{_('News')}}
</div>
<div class="left-sidebar-item" data-href="{{url('problem_feed')}}">
<div class="sidebar-icon" id="problems-icon"><i class="fa fa-tasks"></i></div>
{{_('Problems')}}
</div>
<div class="left-sidebar-item" data-href="{{url('comment_feed')}}">
<div class="sidebar-icon" id="comments-icon"><i class="fa fa-comments"></i></div>
{{_('Comments')}}
</div>
<div class="left-sidebar-item" data-href="{{url('ticket_feed')}}">
<div class="sidebar-icon" id="tickets-icon"><i class="fa fa-question-circle"></i></div>
{{_('Tickets')}}
</div>
</div>
<div class="blog-content">
{% set show_organization_private_icon=True %}
{% if feed_type == 'blog' %}
{% for post in posts %}
{% include "blog/content.html" %}
{% endfor %}
{% elif feed_type == 'problem' %}
{% for problem in problems %}
{% include "problem/feed.html" %}
{% endfor %}
{% elif feed_type == 'ticket' %}
{% if tickets %}
{% for ticket in tickets %}
{% include "ticket/feed.html" %}
{% endfor %}
{% else %}
<h3 style="text-align: center">{{_('You have no ticket')}}</h3>
{% endif %}
{% elif feed_type == 'comment' %}
{% for comment in comments %}
{% include "comments/feed.html" %}
{% endfor %}
{% endif %}
{% if page_obj.num_pages > 1 %}
<div style="margin-bottom:10px;margin-top:10px">{% include "list-pages.html" %}</div>
{% endif %}
</div>
<div class="blog-sidebar">
{% if request.in_contest_mode and request.participation.contest.use_clarifications %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Clarifications') }}
<i class="fa fa-question-circle"></i>
{% if can_edit_contest %}
<a href="{{url('new_contest_clarification', request.participation.contest.key)}}"
class="fa fa-plus-circle"
id="add-clarification"
title="{{_('Add')}}">
</a>
{% endif %}
</h3>
<div class="sidebox-content">
{% if has_clarifications %}
<ul>
{% for clarification in clarifications %}
<li class="clarification">
<a href="{{ url('problem_detail', clarification.problem.code) }}"
class="problem">
{{ clarification.problem.name }}
</a>
<span class="time">{{ relative_time(clarification.date) }}</span>
</li>
{% endfor %}
</ul>
{% else %}
<p class="no-clarifications-message">
{{ _('No clarifications have been made at this time.') }}
</p>
{% endif %}
</div>
</div>
{% endif %}
{% if current_contests %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Ongoing contests') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content">
{% for contest in current_contests %}
<div class="contest">
<div class="contest-list-title">
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
</div>
<div class="time">
{{ _('Ends in') }} {{ _('%(countdown)s.', countdown=contest.end_time|as_countdown) }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if future_contests %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Upcoming contests') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content">
{% for contest in future_contests %}
<div class="contest">
<div class="contest-list-title">
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
</div>
<div class="time">
{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Top Rating') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content" style="padding: 0; border: 0">
<table class="table feed-table">
<tbody>
{% for user in top_rated %}
<tr>
<td style="padding: 7px 2px"><b>{{loop.index}}</b></td>
<td>{{link_user(user)}}</td>
<td>{{user.rating}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="blog-sidebox sidebox">
<h3>{{ _('Top Score') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content" style="padding: 0; border: 0">
<table class="table feed-table">
<tbody>
{% for user in top_scorer %}
<tr>
<td style="padding: 7px 2px"><b>{{loop.index}}</b></td>
<td>{{link_user(user)}}</td>
<td>{{ user.performance_points|floatformat(0) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% block after_posts %}{% endblock %}
{% endblock %} {% endblock %}
{% block bodyend %} {% block middle_content %}
{{ super() }} {% set show_organization_private_icon=True %}
{% if REQUIRE_JAX %} {% if page_type == 'blog' %}
{% include "mathjax-load.html" %} {% for post in posts %}
{% include "blog/content.html" %}
{% endfor %}
{% elif page_type == 'ticket' %}
{% if tickets %}
{% for ticket in tickets %}
{% include "ticket/feed.html" %}
{% endfor %}
{% else %}
<h3 style="text-align: center">{{_('You have no ticket')}}</h3>
{% endif %}
{% elif page_type == 'comment' %}
{% for comment in comments %}
{% include "comments/feed.html" %}
{% endfor %}
{% endif %}
{% if page_obj.num_pages > 1 %}
<div style="margin-bottom:10px;margin-top:10px">{% include "list-pages.html" %}</div>
{% endif %} {% endif %}
{% include "comments/math.html" %}
{% endblock %} {% endblock %}
{% block right_sidebar %}
<div class="right-sidebar">
{% if request.in_contest_mode and request.participation.contest.use_clarifications %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Clarifications') }}
<i class="fa fa-question-circle"></i>
{% if can_edit_contest %}
<a href="{{url('new_contest_clarification', request.participation.contest.key)}}"
class="fa fa-plus-circle"
id="add-clarification"
title="{{_('Add')}}">
</a>
{% endif %}
</h3>
<div class="sidebox-content">
{% if has_clarifications %}
<ul>
{% for clarification in clarifications %}
<li class="clarification">
<a href="{{ url('problem_detail', clarification.problem.code) }}"
class="problem">
{{ clarification.problem.name }}
</a>
<span class="time">{{ relative_time(clarification.date) }}</span>
</li>
{% endfor %}
</ul>
{% else %}
<p class="no-clarifications-message">
{{ _('No clarifications have been made at this time.') }}
</p>
{% endif %}
</div>
</div>
{% endif %}
{% if current_contests %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Ongoing contests') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content">
{% for contest in current_contests %}
<div class="contest">
<div class="contest-list-title">
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
</div>
<div class="time">
{{ _('Ends in') }} {{ _('%(countdown)s.', countdown=contest.end_time|as_countdown) }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if future_contests %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Upcoming contests') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content">
{% for contest in future_contests %}
<div class="contest">
<div class="contest-list-title">
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
</div>
<div class="time">
{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Top Rating') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content" style="padding: 0; border: 0">
<table class="table feed-table">
<tbody>
{% for user in top_rated %}
<tr>
<td style="padding: 7px 2px"><b>{{loop.index}}</b></td>
<td>{{link_user(user)}}</td>
<td>{{user.rating}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="blog-sidebox sidebox">
<h3>{{ _('Top Score') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content" style="padding: 0; border: 0">
<table class="table feed-table">
<tbody>
{% for user in top_scorer %}
<tr>
<td style="padding: 7px 2px"><b>{{loop.index}}</b></td>
<td>{{link_user(user)}}</td>
<td>{{ user.performance_points|floatformat(0) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}

View file

@ -3,6 +3,13 @@
<a href="{{ url('problem_detail', problem.code) }}"> <a href="{{ url('problem_detail', problem.code) }}">
{{ problem.name }} {{ problem.name }}
</a> </a>
{% if problem.id in completed_problem_ids %}
<i class="solved-problem-color fa fa-check-circle"></i>
{% elif problem.id in attempted_problems %}
<i class="attempted-problem-color fa fa-minus-circle"></i>
{% else %}
<i class="unsolved-problem-color fa fa-minus-circle"></i>
{% endif %}
</h3> </h3>
{% with authors=problem.authors.all() %} {% with authors=problem.authors.all() %}
{% if authors %} {% if authors %}
@ -12,7 +19,7 @@
</div> </div>
{% endif %} {% endif %}
{% endwith %} {% endwith %}
{% if true %} {% if show_types %}
<div class="problem-feed-types"> <div class="problem-feed-types">
<i class="fa fa-tag"></i> <i class="fa fa-tag"></i>
{% for type in problem.types_list %} {% for type in problem.types_list %}

View file

@ -1,6 +1,5 @@
{% extends "common-content.html" %} {% extends "three-column-content.html" %}
{% block three_col_media %}
{% block media %}
<link rel="stylesheet" href="{{ static('libs/nouislider.min.css') }}"> <link rel="stylesheet" href="{{ static('libs/nouislider.min.css') }}">
<noscript> <noscript>
<style> <style>
@ -34,11 +33,15 @@
ul.problem-list { ul.problem-list {
padding: 0 !important; padding: 0 !important;
} }
#content {
width: 99%;
margin-left: 0;
}
</style> </style>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block js_media %} {% block three_col_js %}
<script> <script>
window.point_start = {{point_start}}; window.point_start = {{point_start}};
window.point_end = {{point_end}}; window.point_end = {{point_end}};
@ -48,6 +51,13 @@
<script src="{{ static('libs/nouislider.min.js') }}" type="text/javascript"></script> <script src="{{ static('libs/nouislider.min.js') }}" type="text/javascript"></script>
<script> <script>
$(function () { $(function () {
{% if not request.in_contest_mode %}
// wrap middle and write column
if (window.matchMedia('(max-width: 799px)').matches) {
$('.middle-content').next().addBack().wrapAll('<div class="problem-middle-right"/>');
}
{% endif %}
var $form = $('form#filter-form'); var $form = $('form#filter-form');
var $search = $('#search'); var $search = $('#search');
var $category = $('#category'); var $category = $('#category');
@ -83,7 +93,7 @@
$('#go').click(clean_submit); $('#go').click(clean_submit);
$('input#full_text, input#hide_solved, input#show_types, input#show_editorial').click(function () { $('input#full_text, input#hide_solved, input#show_types, input#show_editorial, input#have_editorial').click(function () {
prep_form(); prep_form();
($('<form>').attr('action', window.location.pathname + '?' + $form.serialize()) ($('<form>').attr('action', window.location.pathname + '?' + $form.serialize())
.append($('<input>').attr('type', 'hidden').attr('name', 'csrfmiddlewaretoken') .append($('<input>').attr('type', 'hidden').attr('name', 'csrfmiddlewaretoken')
@ -91,18 +101,6 @@
.attr('method', 'POST').appendTo($('body')).submit()); .attr('method', 'POST').appendTo($('body')).submit());
}); });
var info_float = $('.info-float');
var container = $('#content-right');
if (window.bad_browser) {
container.css('float', 'right');
} else if (!featureTest('position', 'sticky')) {
fix_div(info_float, 55);
$(window).resize(function () {
info_float.width(container.width());
});
info_float.width(container.width());
}
var intFormatter = { var intFormatter = {
to: function (value) { to: function (value) {
return value; return value;
@ -159,50 +157,30 @@
return (node.hasClass('p') ? text.replace(/p$/, '') : text); return (node.hasClass('p') ? text.replace(/p$/, '') : text);
} }
}); });
window.register_contest_notification("{{url('contest_clarification_ajax', request.participation.contest.key)}}"); window.register_contest_notification("{{url('contest_clarification_ajax', request.participation.contest.key)}}");
{% if request.in_contest_mode %}
$('.left-sidebar').hide();
$('.middle-content').css('max-width', '80%');
{% endif %}
}); });
</script> </script>
{% endcompress %} {% endcompress %}
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block title_ruler %}{% endblock %} {% block left_sidebar %}
{% if not request.in_contest_mode %}
{% block title_row %} <div class="left-sidebar">
{% set tab = 'list' %} {{ make_tab_item('feed', 'fa fa-pagelines', url('problem_feed'), _('Feed')) }}
{% set title = 'Problems' %} {{ make_tab_item('list', 'fa fa-list', url('problem_list'), _('List')) }}
{% include "problem/problem-list-tabs.html" %} {{ make_tab_item('admin', 'fa fa-edit', url('admin:judge_problem_changelist'), _('Admin')) }}
{% endblock %}
{% block body %}
{% if page_obj.num_pages > 1 %}
<div style="margin-bottom: 7px; margin-top: 11px;">
{% include "list-pages.html" %}
</div> </div>
{% endif %} {% endif %}
{% endblock %}
<div id="common-content"> {% block middle_content %}
{% block before_table %}{% endblock %} {% if in_contest_mode or page_type == 'list' %}
{% if not request.in_contest_mode %}
<div id="content-right" class="problems">
<div class="info-float">
{% include "problem/search-form.html" %}
{% if hot_problems %}
<div class="sidebox">
<h3>{{ _('Hot problems') }} <i class="fa fa-fire"></i></h3>
<div class="sidebox-content">
<ul class="problem-list">{% for problem in hot_problems %}
<li><a href="{{ url('problem_detail', problem.code) }}" class="hot-problem-link">
{{ problem.name }}
</a></li>
{% endfor %}</ul>
</div>
</div>
{% endif %}
</div>
</div>
{% endif %}
<div id="content-left" class="problems"> <div id="content-left" class="problems">
<table id="problem-table" class="table striped"> <table id="problem-table" class="table striped">
<thead> <thead>
@ -212,9 +190,7 @@
<th class="solved"><i class="fa fa-check"></i></th> <th class="solved"><i class="fa fa-check"></i></th>
{% endif %} {% endif %}
<th class="problem">{{ _('Problem') }}</th> <th class="problem">{{ _('Problem') }}</th>
<!-- Luong begin -->
<th class="pcode">{{ _('Problem code') }}</th> <th class="pcode">{{ _('Problem code') }}</th>
<!-- Luong end -->
<th class="category">{{ _('Category') }}</th> <th class="category">{{ _('Category') }}</th>
{% if show_types %} {% if show_types %}
<th>{{ _('Types') }}</th> <th>{{ _('Types') }}</th>
@ -255,7 +231,7 @@
</th> </th>
{% if show_editorial %} {% if show_editorial %}
<th class="editorial"> <th class="editorial">
Editorial {{_('Editorial')}}
</th> </th>
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -370,18 +346,34 @@
</p> </p>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if page_obj.num_pages > 1 %}
<div style="margin-top:10px;">{% include "list-pages.html" %}</div>
{% endif %}
</div> </div>
</div> {% elif page_type == 'feed' %}
<br> <div class="problem-feed-option">
<!-- Luong begin --> <a href="{{url('problem_feed')}}" class="problem-feed-option-item {{'active' if feed_type=='for_you'}}">
<script> {{_('FOR YOU')}}
$(".pcodecell").each(function(idx, elt){ </a>
var pcode = elt.text; <a href="{{url('problem_feed_new')}}" class="problem-feed-option-item {{'active' if feed_type=='new'}}">
elt.text = pcode.toUpperCase(); {{_('NEW')}}
}); </a>
</script> </div>
<!-- Luong end --> {% for problem in problems %}
{% include "problem/feed.html" %}
{% endfor %}
{% endif %}
{% if page_obj.num_pages > 1 %}
<div style="margin-top:10px;">{% include "list-pages.html" %}</div>
{% endif %}
{% endblock %} {% endblock %}
{% block right_sidebar %}
{% if not request.in_contest_mode %}
<div class="right-sidebar">
<div id="content-right" class="problems">
<div class="info-float">
{% include "problem/search-form.html" %}
</div>
</div>
</div>
{% endif %}
{% endblock %}

View file

@ -7,13 +7,6 @@
<input id="search" type="text" name="search" value="{{ search_query or '' }}" <input id="search" type="text" name="search" value="{{ search_query or '' }}"
placeholder="{{ _('Search problems...') }}"> placeholder="{{ _('Search problems...') }}">
</div> </div>
<!-- {% if has_fts %}
<div>
<input id="full_text" type="checkbox" name="full_text" value="1"
{% if full_text %}checked{% endif %}>
<label for="full_text">{{ _('Full text search') }}</label>
</div>
{% endif %} -->
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<div> <div>
<input id="hide_solved" type="checkbox" name="hide_solved" value="1" <input id="hide_solved" type="checkbox" name="hide_solved" value="1"
@ -26,11 +19,19 @@
{% if show_types %} checked{% endif %}> {% if show_types %} checked{% endif %}>
<label for="show_types">{{ _('Show problem types') }}</label> <label for="show_types">{{ _('Show problem types') }}</label>
</div> </div>
<div> {% if page_type == 'list' %}
<input id="show_editorial" type="checkbox" name="show_editorial" value="1" <div>
{% if show_editorial %} checked{% endif %}> <input id="show_editorial" type="checkbox" name="show_editorial" value="1"
<label for="show_editorial">{{ _('Show editorial') }}</label> {% if show_editorial %} checked{% endif %}>
</div> <label for="show_editorial">{{ _('Show editorial') }}</label>
</div>
{% elif page_type == 'feed' %}
<div>
<input id="have_editorial" type="checkbox" name="have_editorial" value="1"
{% if have_editorial %} checked{% endif %}>
<label for="have_editorial">{{ _('Have editorial') }}</label>
</div>
{% endif %}
<div class="filter-form-group"> <div class="filter-form-group">
<label for="type"><i>{{ _('Organization') }}</i></label> <label for="type"><i>{{ _('Organization') }}</i></label>
<select id="search-org" name="orgs" multiple> <select id="search-org" name="orgs" multiple>

View file

@ -0,0 +1,69 @@
{% extends "base.html" %}
{% block title_row %}{% endblock %}
{% block title_ruler %}{% endblock %}
{% block media %}
<style>
#content {
width: 98%;
margin-left: 0;
}
</style>
{% block three_col_media %}{% endblock %}
{% endblock %}
{% block js_media %}
<script type="text/javascript">
$(document).ready(function () {
$('.left-sidebar-item').on('click', function() {
var url = $(this).attr('data-href');
if (url === '#') return;
window.location.href = url;
});
$('.blog-description').on('click', function() {
var max_height = $(this).css('max-height');
if (max_height !== 'fit-content') {
$(this).css('max-height', 'fit-content');
$(this).parent().css('background-image', 'inherit')
.css('padding-bottom', '0.5em');
$(this).css('cursor', 'auto');
}
})
$('.blog-description').each(function() {
if ($(this).prop('scrollHeight') > $(this).height() ) {
$(this).parent().css('background-image', '-webkit-linear-gradient(bottom, gray, lightgray 3%, transparent 8%, transparent 100%)');
$(this).parent().css('padding-bottom', '0');
$(this).css('cursor', 'pointer');
}
});
});
</script>
{% block three_col_js %}{% endblock %}
{% endblock %}
{% macro make_tab_item(name, fa, url, text) %}
<div class="left-sidebar-item {% if page_type == name %}active{% endif %}" data-href="{{ url }}" id="{{ name }}-tab">
<div class="sidebar-icon"><i class="{{ fa }}"></i></div>
{{ text }}
</div>
{% endmacro %}
{% block body %}
{% block before_posts %}{% endblock %}
<div id="three-col-container">
{% block left_sidebar %}{% endblock %}
<div class="middle-content">
{% block middle_content %}{% endblock %}
</div>
{% block right_sidebar %}{% endblock %}
</div>
{% block after_posts %}{% endblock %}
{% endblock %}
{% block bodyend %}
{{ super() }}
{% if REQUIRE_JAX %}
{% include "mathjax-load.html" %}
{% endif %}
{% include "comments/math.html" %}
{% endblock %}