diff --git a/course/validation.py b/course/validation.py
index 3bbcf6584c031b26aa0acf0e65b9c58a7ca50186..4e8024c79b896574be72cb19ff2215a34c8d2168 100644
--- a/course/validation.py
+++ b/course/validation.py
@@ -881,8 +881,15 @@ def validate_course_content(repo, course_file, events_file,
         events_desc = get_yaml_from_repo(repo, events_file,
                 commit_sha=validate_sha, cached=False)
     except ObjectDoesNotExist:
-        # That's OK--no calendar info.
-        pass
+        if events_file != "events.yml":            
+            vctx.add_warning(
+                    _("Events file"), 
+                    _("Your course repository does not have an events "
+                        "file named '%s'.")
+                    % events_file)
+        else:
+            # That's OK--no calendar info.
+            pass
     else:
         validate_calendar_desc_struct(vctx, events_file, events_desc)
 
@@ -941,13 +948,17 @@ def validate_course_content(repo, course_file, events_file,
 
                 if len(flow_grade_identifiers) > 1:
                     vctx.add_warning(
-                            location, "flow uses more than one grade_identifier: %s"
+                            location,
+                            string_concat(_("flow uses more than one "
+                                          "grade_identifier"), ": %s")
                             % ", ".join(flow_grade_identifiers))
 
             if flow_grade_identifiers & used_grade_identifiers:
                 raise ValidationError(
-                        "%s: flow uses the same grade_identifier "
-                        "as another flow: %s"
+                        string_concat("%s: ", 
+                                      _("flow uses the same grade_identifier "
+                                        "as another flow"),
+                                      ": %s")
                         % (
                             location,
                             ", ".join(
diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index 79608856a40d4534b53858821636e09d9f76f573..09ee7443c1a4e123d1c3a6e6911f7e7e09653299 100644
--- a/locale/de/LC_MESSAGES/django.po
+++ b/locale/de/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-09-08 15:11+0800\n"
+"POT-Creation-Date: 2015-09-11 12:45+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,93 +18,93 @@ msgstr ""
 "Language: \n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: .\course\admin.py:82 .\course\admin.py:258
+#: .\course\admin.py:84 .\course\admin.py:266
 msgid "First name"
 msgstr ""
 
-#: .\course\admin.py:88 .\course\admin.py:264
+#: .\course\admin.py:90 .\course\admin.py:272
 msgid "Last name"
 msgstr ""
 
-#: .\course\admin.py:248
+#: .\course\admin.py:256
 msgid "Tags must belong to same course as participation."
 msgstr ""
 
-#: .\course\admin.py:367 .\course\admin.py:488 .\course\admin.py:572
-#: .\course\admin.py:685 .\course\admin.py:760 .\course\exam.py:90
-#: .\course\templates\course\gradebook-single.html:17 .\course\views.py:501
+#: .\course\admin.py:375 .\course\admin.py:496 .\course\admin.py:580
+#: .\course\admin.py:693 .\course\admin.py:768 .\course\exam.py:90
+#: .\course\templates\course\gradebook-single.html:17 .\course\views.py:500
 msgid "Participant"
 msgstr ""
 
-#: .\course\admin.py:465 .\course\admin.py:567 .\course\admin.py:675
-#: .\course\admin.py:755 .\course\models.py:223 .\course\models.py:243
-#: .\course\models.py:285 .\course\models.py:317 .\course\models.py:364
-#: .\course\models.py:391 .\course\models.py:412 .\course\models.py:952
-#: .\course\models.py:1306
+#: .\course\admin.py:473 .\course\admin.py:575 .\course\admin.py:683
+#: .\course\admin.py:763 .\course\models.py:228 .\course\models.py:251
+#: .\course\models.py:296 .\course\models.py:331 .\course\models.py:381
+#: .\course\models.py:411 .\course\models.py:432 .\course\models.py:993
+#: .\course\models.py:1357
 msgid "Course"
 msgstr ""
 
-#: .\course\admin.py:470 .\course\flow.py:1520 .\course\models.py:393
-#: .\course\models.py:427 .\course\models.py:791 .\course\models.py:857
-#: .\course\models.py:966 .\course\models.py:1310
+#: .\course\admin.py:478 .\course\flow.py:1516 .\course\models.py:413
+#: .\course\models.py:447 .\course\models.py:823 .\course\models.py:895
+#: .\course\models.py:1007 .\course\models.py:1361
 #: .\course\templates\course\gradebook-opp-list.html:26
 #: .\course\templates\course\gradebook-single.html:140 .\course\views.py:346
-#: .\course\views.py:429 .\course\views.py:505
+#: .\course\views.py:428 .\course\views.py:504
 msgid "Flow ID"
 msgstr ""
 
-#: .\course\admin.py:479 .\course\models.py:527
+#: .\course\admin.py:487 .\course\models.py:550
 #: .\course\templates\course\gradebook-single.html:225
 msgid "Page ID"
 msgstr ""
 
-#: .\course\admin.py:486
+#: .\course\admin.py:494
 msgid "anonymous"
 msgstr ""
 
-#: .\course\admin.py:493
+#: .\course\admin.py:501
 msgid "Has answer"
 msgstr ""
 
-#: .\course\admin.py:498
+#: .\course\admin.py:506
 msgid "Flow Session ID"
 msgstr ""
 
-#: .\course\admin.py:680
+#: .\course\admin.py:688
 msgid "Opportunity"
 msgstr ""
 
-#: .\course\admin.py:881
+#: .\course\admin.py:889
 msgid "Revoke Exam Tickets"
 msgstr ""
 
 #. Translators: "TA" is short for Teaching Assistant.
-#: .\course\analytics.py:57 .\course\analytics.py:415
-#: .\course\analytics.py:452
+#: .\course\analytics.py:58 .\course\analytics.py:416
+#: .\course\analytics.py:453
 msgid "must be at least TA to view analytics"
 msgstr ""
 
-#: .\course\analytics.py:105
+#: .\course\analytics.py:106
 msgctxt "No data"
 msgid "None"
 msgstr ""
 
-#: .\course\analytics.py:114
+#: .\course\analytics.py:115
 msgctxt "Value of grade"
 msgid "value greater than max"
 msgstr ""
 
-#: .\course\analytics.py:122
+#: .\course\analytics.py:123
 msgctxt "Value of grade"
 msgid "value smaller than min"
 msgstr ""
 
-#: .\course\analytics.py:240 .\course\analytics.py:384
+#: .\course\analytics.py:241 .\course\analytics.py:385
 msgctxt "Status of session"
 msgid "in progress"
 msgstr ""
 
-#: .\course\analytics.py:378
+#: .\course\analytics.py:379
 msgctxt "Minute (time unit)"
 msgid "min"
 msgstr ""
@@ -121,7 +121,7 @@ msgstr ""
 #. userfor impersonating. Customize how the name is
 #. shown, but leave email first to retain usability
 #. of form sorted by last name.
-#: .\course\auth.py:137 .\course\exam.py:67 .\course\views.py:479
+#: .\course\auth.py:137 .\course\exam.py:67 .\course\views.py:478
 #, python-format
 msgid "%(user_email)s - %(user_lastname)s, %(user_firstname)s"
 msgstr ""
@@ -130,7 +130,7 @@ msgstr ""
 msgid "Select user to impersonate."
 msgstr ""
 
-#: .\course\auth.py:149 .\course\models.py:422
+#: .\course\auth.py:149 .\course\models.py:442
 #: .\course\templates\course\grade-import-preview.html:18
 msgid "User"
 msgstr ""
@@ -139,83 +139,83 @@ msgstr ""
 msgid "Impersonate"
 msgstr ""
 
-#: .\course\auth.py:159
+#: .\course\auth.py:158
 msgid "Already impersonating someone."
 msgstr ""
 
-#: .\course\auth.py:168
+#: .\course\auth.py:167
 #, python-format
 msgid "Now impersonating '%s'."
 msgstr ""
 
-#: .\course\auth.py:177 .\relate\templates\base.html:79
+#: .\course\auth.py:176 .\relate\templates\base.html:76
 msgid "Impersonate user"
 msgstr ""
 
-#: .\course\auth.py:187 .\relate\templates\base.html:77
+#: .\course\auth.py:186 .\relate\templates\base.html:74
 msgid "Stop impersonating"
 msgstr ""
 
-#: .\course\auth.py:193
+#: .\course\auth.py:192
 msgid "Not currently impersonating anyone."
 msgstr ""
 
-#: .\course\auth.py:200
+#: .\course\auth.py:199
 msgid "No longer impersonating anyone."
 msgstr ""
 
-#: .\course\auth.py:209
+#: .\course\auth.py:208
 msgid "Stop impersonating user"
 msgstr ""
 
-#: .\course\auth.py:281 .\course\templates\course\course-page.html:38
+#: .\course\auth.py:280 .\course\templates\course\course-page.html:38
 #: .\course\templates\course\flow-start.html:186
 #: .\course\templates\course\login.html:7 .\relate\templates\403.html:14
-#: .\relate\templates\base.html:114
+#: .\relate\templates\base.html:111
 msgid "Sign in"
 msgstr ""
 
-#: .\course\auth.py:310 .\course\auth.py:667
+#: .\course\auth.py:308 .\course\auth.py:662
 msgid "Sign-in not allowed in this facility."
 msgstr ""
 
-#: .\course\auth.py:312 .\course\auth.py:668
+#: .\course\auth.py:310 .\course\auth.py:663
 msgid "user not allowed to sign in in facility"
 msgstr ""
 
-#: .\course\auth.py:335
+#: .\course\auth.py:333
 msgid "Username"
 msgstr ""
 
-#: .\course\auth.py:339
+#: .\course\auth.py:337
 msgid "Enter a valid username."
 msgstr ""
 
-#: .\course\auth.py:340
+#: .\course\auth.py:338
 msgid "This value may contain only letters, numbers and @/./+/-/_ characters."
 msgstr ""
 
-#: .\course\auth.py:356 .\course\auth.py:439
+#: .\course\auth.py:354 .\course\auth.py:436
 msgid "Send email"
 msgstr ""
 
-#: .\course\auth.py:363 .\course\auth.py:445
+#: .\course\auth.py:360 .\course\auth.py:442
 msgid "password-based sign-in is not being used"
 msgstr ""
 
-#: .\course\auth.py:371
+#: .\course\auth.py:368
 msgid "A user with that username already exists."
 msgstr ""
 
-#: .\course\auth.py:376
+#: .\course\auth.py:373
 #, python-format
 msgid ""
 "That email address is already in use. Would you like to <a href='%s'>reset "
 "your password</a> instead?"
 msgstr ""
 
-#: .\course\auth.py:411 .\course\auth.py:479 .\course\auth.py:496
-#: .\course\auth.py:570 .\course\auth.py:629
+#: .\course\auth.py:408 .\course\auth.py:476 .\course\auth.py:493
+#: .\course\auth.py:566 .\course\auth.py:624
 #: .\course\templates\course\analytics-flow.html:5
 #: .\course\templates\course\analytics-flows.html:5
 #: .\course\templates\course\analytics-page.html:5
@@ -239,180 +239,180 @@ msgstr ""
 #: .\course\templates\course\home.html:30
 #: .\course\templates\course\sandbox-page.html:17
 #: .\course\templates\course\sign-in-email.txt:2
-#: .\relate\templates\admin\base_site.html:5 .\relate\templates\base.html:15
-#: .\relate\templates\base.html.py:60 .\relate\templates\maintenance.html:6
+#: .\relate\templates\admin\base_site.html:5 .\relate\templates\base.html:12
+#: .\relate\templates\base.html.py:57 .\relate\templates\maintenance.html:6
 msgid "RELATE"
 msgstr ""
 
-#: .\course\auth.py:412
+#: .\course\auth.py:409
 msgid "Verify your email"
 msgstr ""
 
-#: .\course\auth.py:418 .\course\auth.py:486 .\course\auth.py:635
+#: .\course\auth.py:415 .\course\auth.py:483 .\course\auth.py:630
 msgid "Email sent. Please check your email and click the link."
 msgstr ""
 
-#: .\course\auth.py:427
+#: .\course\auth.py:424
 msgid "Sign up"
 msgstr ""
 
-#: .\course\auth.py:433 .\course\auth.py:580 .\course\models.py:362
+#: .\course\auth.py:430 .\course\auth.py:576 .\course\models.py:379
 msgid "Email"
 msgstr ""
 
-#: .\course\auth.py:459
+#: .\course\auth.py:456
 msgid ""
 "That email address doesn't have an associated user account. Are you sure "
 "you've registered?"
 msgstr ""
 
-#: .\course\auth.py:480
+#: .\course\auth.py:477
 msgid "Password reset"
 msgstr ""
 
-#: .\course\auth.py:495 .\course\auth.py:569
+#: .\course\auth.py:492 .\course\auth.py:565
 #, python-format
 msgid "Password reset on %(site_name)s"
 msgstr ""
 
-#: .\course\auth.py:503
+#: .\course\auth.py:500
 msgid "Password"
 msgstr ""
 
-#: .\course\auth.py:505
+#: .\course\auth.py:502
 msgid "Password confirmation"
 msgstr ""
 
-#: .\course\auth.py:511 .\course\auth.py:699 .\course\auth.py:712
+#: .\course\auth.py:508 .\course\auth.py:694 .\course\auth.py:706
 #: .\course\templates\course\course-page.html:30
-#: .\course\templates\course\home.html:22 .\course\versioning.py:388
+#: .\course\templates\course\home.html:22 .\course\versioning.py:384
 msgid "Update"
 msgstr ""
 
-#: .\course\auth.py:520
+#: .\course\auth.py:516
 msgid "The two password fields didn't match."
 msgstr ""
 
-#: .\course\auth.py:525 .\course\auth.py:594 .\course\auth.py:649
+#: .\course\auth.py:521 .\course\auth.py:589 .\course\auth.py:644
 msgid "email-based sign-in is not being used"
 msgstr ""
 
-#: .\course\auth.py:529 .\course\auth.py:655
+#: .\course\auth.py:525 .\course\auth.py:650
 msgid "Invalid sign-in token. Perhaps you've used an old token email?"
 msgstr ""
 
-#: .\course\auth.py:531 .\course\auth.py:539 .\course\auth.py:544
-#: .\course\auth.py:657 .\course\auth.py:662
+#: .\course\auth.py:527 .\course\auth.py:535 .\course\auth.py:540
+#: .\course\auth.py:652 .\course\auth.py:657
 msgid "invalid sign-in token"
 msgstr ""
 
-#: .\course\auth.py:543 .\course\auth.py:661
+#: .\course\auth.py:539 .\course\auth.py:656
 msgid "Account disabled."
 msgstr ""
 
-#: .\course\auth.py:554 .\course\auth.py:674
+#: .\course\auth.py:550 .\course\auth.py:669
 msgid ""
 "Successfully signed in. Please complete your registration information below."
 msgstr ""
 
-#: .\course\auth.py:561 .\course\auth.py:681
+#: .\course\auth.py:557 .\course\auth.py:676
 msgid "Successfully signed in."
 msgstr ""
 
-#: .\course\auth.py:588
+#: .\course\auth.py:584
 msgid "Send sign-in email"
 msgstr ""
 
-#: .\course\auth.py:629
+#: .\course\auth.py:624
 #, python-format
 msgid "Your %(RELATE)s sign-in link"
 msgstr ""
 
-#: .\course\auth.py:733 .\course\auth.py:743
+#: .\course\auth.py:726 .\course\auth.py:736
 msgid "Profile data saved."
 msgstr ""
 
 #. Translators: format of event kind in Event model
-#: .\course\calendar.py:48 .\course\calendar.py:190 .\course\models.py:246
+#: .\course\calendar.py:50 .\course\calendar.py:192 .\course\models.py:254
 msgid "Should be lower_case_with_underscores, no spaces allowed."
 msgstr ""
 
-#: .\course\calendar.py:50 .\course\calendar.py:192
+#: .\course\calendar.py:52 .\course\calendar.py:194
 msgctxt "Kind of event"
 msgid "Kind of event"
 msgstr ""
 
-#: .\course\calendar.py:54
+#: .\course\calendar.py:56
 msgctxt "Starting time of event"
 msgid "Starting time"
 msgstr ""
 
-#: .\course\calendar.py:56
+#: .\course\calendar.py:58
 msgid "Duration in minutes"
 msgstr ""
 
-#: .\course\calendar.py:59
+#: .\course\calendar.py:61
 msgid "Weekly"
 msgstr ""
 
-#: .\course\calendar.py:61
+#: .\course\calendar.py:63
 msgctxt "Interval of recurring events"
 msgid "Interval"
 msgstr ""
 
-#: .\course\calendar.py:64 .\course\calendar.py:195
+#: .\course\calendar.py:66 .\course\calendar.py:197
 msgctxt "Starting ordinal of recurring events"
 msgid "Starting ordinal"
 msgstr ""
 
-#: .\course\calendar.py:66
+#: .\course\calendar.py:68
 msgctxt "Count of recurring events"
 msgid "Count"
 msgstr ""
 
-#: .\course\calendar.py:72
+#: .\course\calendar.py:74
 msgid "Create"
 msgstr ""
 
-#: .\course\calendar.py:100
+#: .\course\calendar.py:102
 #, python-format
 msgid "'%(event_kind)s %(event_ordinal)d' already exists"
 msgstr ""
 
-#: .\course\calendar.py:115
+#: .\course\calendar.py:117
 msgctxt "Unkown time interval"
 msgid "unknown interval"
 msgstr ""
 
-#: .\course\calendar.py:128 .\course\calendar.py:211
+#: .\course\calendar.py:130 .\course\calendar.py:213
 msgid "only instructors and TAs may do that"
 msgstr ""
 
-#: .\course\calendar.py:158 .\course\calendar.py:170
+#: .\course\calendar.py:160 .\course\calendar.py:172
 msgid "No events created."
 msgstr ""
 
-#: .\course\calendar.py:176
+#: .\course\calendar.py:178
 msgid "Events created."
 msgstr ""
 
-#: .\course\calendar.py:184 .\course\templates\course\course-base.html:105
+#: .\course\calendar.py:186 .\course\templates\course\course-base.html:105
 msgid "Create recurring events"
 msgstr ""
 
-#: .\course\calendar.py:201
+#: .\course\calendar.py:203
 msgid "Renumber"
 msgstr ""
 
-#: .\course\calendar.py:243
+#: .\course\calendar.py:245
 msgid "Events renumbered."
 msgstr ""
 
-#: .\course\calendar.py:246
+#: .\course\calendar.py:248
 msgid "No events found."
 msgstr ""
 
-#: .\course\calendar.py:253 .\course\templates\course\course-base.html:106
+#: .\course\calendar.py:255 .\course\templates\course\course-base.html:106
 msgid "Renumber events"
 msgstr ""
 
@@ -709,7 +709,7 @@ msgstr ""
 msgid "Deny enrollment"
 msgstr ""
 
-#: .\course\enrollment.py:226 .\course\models.py:367
+#: .\course\enrollment.py:226 .\course\models.py:384
 #: .\course\templates\course\gradebook-participant-list.html:27
 msgid "Role"
 msgstr ""
@@ -726,25 +726,25 @@ msgstr ""
 msgid "Preapprove"
 msgstr ""
 
-#: .\course\enrollment.py:244
+#: .\course\enrollment.py:243
 msgid "only instructors may do that"
 msgstr ""
 
-#: .\course\enrollment.py:282
+#: .\course\enrollment.py:281
 #, python-format
 msgid "%(n_created)d preapprovals created, %(n_exist)d already existed."
 msgstr ""
 
-#: .\course\enrollment.py:293
+#: .\course\enrollment.py:292
 msgid "Create Participation Preapprovals"
 msgstr ""
 
-#: .\course\exam.py:88 .\course\views.py:499
+#: .\course\exam.py:88 .\course\views.py:498
 msgid "Select participant for whom exception is to be granted."
 msgstr ""
 
-#: .\course\exam.py:97 .\course\exam.py:180 .\course\models.py:1329
-#: .\course\models.py:1342
+#: .\course\exam.py:97 .\course\exam.py:179 .\course\models.py:1380
+#: .\course\models.py:1396
 msgid "Exam"
 msgstr ""
 
@@ -756,79 +756,79 @@ msgstr ""
 msgid "Issue ticket"
 msgstr ""
 
-#: .\course\exam.py:127
+#: .\course\exam.py:126
 msgid "User is not enrolled in course."
 msgstr ""
 
-#: .\course\exam.py:148
+#: .\course\exam.py:147
 #, python-format
 msgid ""
 "Ticket issued for <b>%(participation)s</b>. The ticket code is <b>%"
 "(ticket_code)s</b>."
 msgstr ""
 
-#: .\course\exam.py:160
+#: .\course\exam.py:159
 msgid "Issue Exam Ticket"
 msgstr ""
 
-#: .\course\exam.py:183
+#: .\course\exam.py:182
 msgid "List"
 msgstr ""
 
-#: .\course\exam.py:184
+#: .\course\exam.py:183
 msgid "Cards"
 msgstr ""
 
-#: .\course\exam.py:186
+#: .\course\exam.py:185
 msgid "Ticket Format"
 msgstr ""
 
-#: .\course\exam.py:189
+#: .\course\exam.py:188
 msgid "Revoke prior exam tickets"
 msgstr ""
 
-#: .\course\exam.py:196
+#: .\course\exam.py:195
 msgid "Issue tickets"
 msgstr ""
 
-#: .\course\exam.py:207
+#: .\course\exam.py:205
 msgid "must be instructor or TA to batch-issue tickets"
 msgstr ""
 
-#: .\course\exam.py:247
+#: .\course\exam.py:245
 #, python-format
 msgid "%d tickets issued."
 msgstr ""
 
-#: .\course\exam.py:257
+#: .\course\exam.py:255
 msgid "Batch-Issue Exam Tickets"
 msgstr ""
 
-#: .\course\exam.py:298
+#: .\course\exam.py:296
 msgid "User name"
 msgstr ""
 
-#: .\course\exam.py:301
+#: .\course\exam.py:299
 msgid "This is typically your full email address."
 msgstr ""
 
-#: .\course\exam.py:302
+#: .\course\exam.py:300
 msgid "Code"
 msgstr ""
 
-#: .\course\exam.py:309
+#: .\course\exam.py:307
 msgid "Check in"
 msgstr ""
 
-#: .\course\exam.py:328
+#: .\course\exam.py:325
 msgid "Invalid check-in data."
 msgstr ""
 
-#: .\course\exam.py:353
+#: .\course\exam.py:350
 msgid "Check in for Exam"
 msgstr ""
 
-#: .\course\exam.py:440
+#: .\course\exam.py:437
 msgid "Error while processing exam lockdown: ticket not found."
 msgstr ""
 
@@ -836,7 +836,7 @@ msgstr ""
 msgid "cannot grade ungraded answer"
 msgstr ""
 
-#: .\course\flow.py:467 .\course\flow.py:1451
+#: .\course\flow.py:467 .\course\flow.py:1447
 msgid "Can't end a session that's already ended"
 msgstr ""
 
@@ -900,64 +900,64 @@ msgstr ""
 msgid "may not view other people's sessions"
 msgstr ""
 
-#: .\course\flow.py:951
+#: .\course\flow.py:947
 msgid "Save answer"
 msgstr ""
 
-#: .\course\flow.py:958
+#: .\course\flow.py:954
 msgid "Submit answer for grading"
 msgstr ""
 
-#: .\course\flow.py:962
+#: .\course\flow.py:958
 msgid "Submit final answer"
 msgstr ""
 
-#: .\course\flow.py:971
+#: .\course\flow.py:967
 msgid "Save answer and move on"
 msgstr ""
 
-#: .\course\flow.py:979
+#: .\course\flow.py:975
 msgid "Save answer and finish"
 msgstr ""
 
-#: .\course\flow.py:992
+#: .\course\flow.py:988
 msgid "could not find which button was pressed"
 msgstr ""
 
-#: .\course\flow.py:1016
+#: .\course\flow.py:1012
 msgid ""
 "No in-progress session record found for this flow. Redirected to flow start "
 "page."
 msgstr ""
 
-#: .\course\flow.py:1057
+#: .\course\flow.py:1053
 msgid "not allowed to view flow"
 msgstr ""
 
-#: .\course\flow.py:1069
+#: .\course\flow.py:1065
 msgid "Answer submission not allowed."
 msgstr ""
 
-#: .\course\flow.py:1078
+#: .\course\flow.py:1074
 msgid "Already have final answer."
 msgstr ""
 
-#: .\course\flow.py:1100
+#: .\course\flow.py:1096
 msgid "Answer saved."
 msgstr ""
 
-#: .\course\flow.py:1186
+#: .\course\flow.py:1182
 msgid "Failed to submit answer."
 msgstr ""
 
-#: .\course\flow.py:1260
+#: .\course\flow.py:1256
 msgid ""
 "Changes to this session are being prevented because this session yields a "
 "permanent grade, but you have not completed your enrollment process in this "
 "course."
 msgstr ""
 
-#: .\course\flow.py:1276
+#: .\course\flow.py:1272
 msgid ""
 "<p><b>WARNING!</b> What you enter on this page will not be associated with "
 "your user account, likely because you have not completed your enrollment in "
@@ -971,315 +971,315 @@ msgid ""
 "work.</b>"
 msgstr ""
 
-#: .\course\flow.py:1362
+#: .\course\flow.py:1358
 msgid "only POST allowed"
 msgstr ""
 
-#: .\course\flow.py:1368
+#: .\course\flow.py:1364
 msgid "may only change your own flow sessions"
 msgstr ""
 
-#: .\course\flow.py:1371
+#: .\course\flow.py:1367
 msgid "may only change in-progress flow sessions"
 msgstr ""
 
-#: .\course\flow.py:1376
+#: .\course\flow.py:1372
 msgid "invalid expiration mode"
 msgstr ""
 
-#: .\course\flow.py:1447
+#: .\course\flow.py:1443
 msgid "odd POST parameters"
 msgstr ""
 
-#: .\course\flow.py:1455
+#: .\course\flow.py:1451
 msgid "not permitted to end session"
 msgstr ""
 
-#: .\course\flow.py:1523
+#: .\course\flow.py:1519
 msgid ""
 "If non-empty, limit the regrading to sessions started under this access "
 "rules tag."
 msgstr ""
 
-#: .\course\flow.py:1525 .\course\models.py:439
+#: .\course\flow.py:1521 .\course\models.py:459
 msgid "Access rules tag"
 msgstr ""
 
-#: .\course\flow.py:1529
+#: .\course\flow.py:1525
 msgid "Regrade in-progress and not-in-progress sessions"
 msgstr ""
 
-#: .\course\flow.py:1531
+#: .\course\flow.py:1527
 msgid "Regrade in-progress sessions only"
 msgstr ""
 
-#: .\course\flow.py:1533
+#: .\course\flow.py:1529
 msgid "Regrade not-in-progress sessions only"
 msgstr ""
 
-#: .\course\flow.py:1535
+#: .\course\flow.py:1531
 msgid "Regraded session in progress"
 msgstr ""
 
-#: .\course\flow.py:1538 .\course\templates\course\gradebook-single.html:257
+#: .\course\flow.py:1534 .\course\templates\course\gradebook-single.html:257
 msgid "Regrade"
 msgstr ""
 
-#: .\course\flow.py:1556
+#: .\course\flow.py:1552
 msgid "must be instructor to regrade flows"
 msgstr ""
 
-#: .\course\flow.py:1586
+#: .\course\flow.py:1582
 #, python-format
 msgid "%d sessions regraded."
 msgstr ""
 
-#: .\course\flow.py:1594
+#: .\course\flow.py:1590
 msgid ""
 "This regrading process is only intended for flows that donot show up in the "
 "grade book. If you would like to regradefor-credit flows, use the "
 "corresponding functionality in the grade book."
 msgstr ""
 
-#: .\course\flow.py:1599
+#: .\course\flow.py:1595
 msgid "Regrade not-for-credit Flow Sessions"
 msgstr ""
 
-#: .\course\grades.py:60
+#: .\course\grades.py:61
 msgid "must be enrolled to view grades"
 msgstr ""
 
-#: .\course\grades.py:73 .\course\grades.py:802
+#: .\course\grades.py:74 .\course\grades.py:812
 msgid "may not view other people's grades"
 msgstr ""
 
-#: .\course\grades.py:151 .\course\grades.py:174 .\course\grades.py:271
-#: .\course\grades.py:468 .\course\grading.py:61
+#: .\course\grades.py:152 .\course\grades.py:175 .\course\grades.py:272
+#: .\course\grades.py:475 .\course\grading.py:61
 msgid "must be instructor or TA to view grades"
 msgstr ""
 
-#: .\course\grades.py:293
+#: .\course\grades.py:296
 msgid "must be instructor or TA to export grades"
 msgstr ""
 
-#: .\course\grades.py:342
+#: .\course\grades.py:350
 msgid "Session tag"
 msgstr ""
 
-#: .\course\grades.py:346
+#: .\course\grades.py:354
 msgid ""
 "Only act on in-progress sessions that are past their access rule's due date "
 "(applies to 'expire')"
 msgstr ""
 
 #. Translators: see help text above.
-#: .\course\grades.py:349
+#: .\course\grades.py:357
 msgid "Past due only"
 msgstr ""
 
-#: .\course\grades.py:352
+#: .\course\grades.py:360
 msgid "Impose deadline (Expire sessions)"
 msgstr ""
 
-#: .\course\grades.py:357
+#: .\course\grades.py:364
 msgid "Regrade ended sessions"
 msgstr ""
 
-#: .\course\grades.py:359
+#: .\course\grades.py:366
 msgid "Recalculate grades of ended sessions"
 msgstr ""
 
-#: .\course\grades.py:473
+#: .\course\grades.py:480
 msgid "opportunity from wrong course"
 msgstr ""
 
-#: .\course\grades.py:499 .\course\views.py:380 .\course\views.py:407
-#: .\course\views.py:455
+#: .\course\grades.py:506 .\course\views.py:379 .\course\views.py:406
+#: .\course\views.py:454
 msgid "invalid operation"
 msgstr ""
 
-#: .\course\grades.py:515
+#: .\course\grades.py:522
 #, python-format
 msgid "%d session(s) expired."
 msgstr ""
 
-#: .\course\grades.py:524
+#: .\course\grades.py:531
 #, python-format
 msgid "%d session(s) ended."
 msgstr ""
 
-#: .\course\grades.py:532
+#: .\course\grades.py:539
 #, python-format
 msgid "%d session(s) regraded."
 msgstr ""
 
-#: .\course\grades.py:540
+#: .\course\grades.py:547
 #, python-format
 msgid "Grade recalculated for %d session(s)."
 msgstr ""
 
-#: .\course\grades.py:549 .\course\grades.py:869 .\course\grades.py:1176
-#: .\course\versioning.py:454
+#: .\course\grades.py:556 .\course\grades.py:879 .\course\grades.py:1183
+#: .\course\versioning.py:450
 msgctxt "Starting of Error message"
 msgid "Error"
 msgstr ""
 
-#: .\course\grades.py:660 .\course\views.py:757
+#: .\course\grades.py:670 .\course\views.py:752
 msgid "Set access rules tag"
 msgstr ""
 
-#: .\course\grades.py:664 .\course\models.py:821 .\course\models.py:869
-#: .\course\models.py:1037 .\course\views.py:801
+#: .\course\grades.py:674 .\course\models.py:853 .\course\models.py:907
+#: .\course\models.py:1082 .\course\views.py:796
 msgid "Comment"
 msgstr ""
 
-#: .\course\grades.py:668 .\course\templates\course\gradebook-single.html:271
+#: .\course\grades.py:678 .\course\templates\course\gradebook-single.html:271
 msgid "Reopen"
 msgstr ""
 
-#: .\course\grades.py:705
+#: .\course\grades.py:715
 #, python-format
 msgid ""
 "Session reopened at %(now)s by %(user)s, previous completion time was '%"
 "(completion_time)s': %(comment)s."
 msgstr ""
 
-#: .\course\grades.py:729
+#: .\course\grades.py:739
 msgid "Reopen session"
 msgstr ""
 
-#: .\course\grades.py:786
+#: .\course\grades.py:796
 msgid "participation does not match course"
 msgstr ""
 
-#: .\course\grades.py:795
+#: .\course\grades.py:805
 msgid "This grade is not shown in the grade book."
 msgstr ""
 
-#: .\course\grades.py:798
+#: .\course\grades.py:808
 msgid "This grade is not shown in the student grade book."
 msgstr ""
 
-#: .\course\grades.py:805
+#: .\course\grades.py:815
 msgid "grade has not been released"
 msgstr ""
 
-#: .\course\grades.py:825
+#: .\course\grades.py:835
 msgid "unknown action"
 msgstr ""
 
-#: .\course\grades.py:841
+#: .\course\grades.py:851
 msgid "Session expired."
 msgstr ""
 
-#: .\course\grades.py:848
+#: .\course\grades.py:858
 msgid "Session ended."
 msgstr ""
 
-#: .\course\grades.py:854
+#: .\course\grades.py:864
 msgid "Session regraded."
 msgstr ""
 
-#: .\course\grades.py:860
+#: .\course\grades.py:870
 msgid "Session grade recalculated."
 msgstr ""
 
-#: .\course\grades.py:863
+#: .\course\grades.py:873
 msgid "invalid session operation"
 msgstr ""
 
-#: .\course\grades.py:959
+#: .\course\grades.py:969
 #, python-format
 msgid ""
 "Click to <a href='%s' target='_blank'>create</a> a new grading opportunity. "
 "Reload this form when done."
 msgstr ""
 
-#: .\course\grades.py:963
+#: .\course\grades.py:973
 msgctxt "Field name in Import grades form"
 msgid "Grading opportunity"
 msgstr ""
 
-#: .\course\grades.py:968 .\course\models.py:1028
+#: .\course\grades.py:978 .\course\models.py:1073
 msgid "Attempt ID"
 msgstr ""
 
-#: .\course\grades.py:970
+#: .\course\grades.py:980
 msgid "File"
 msgstr ""
 
-#: .\course\grades.py:974
+#: .\course\grades.py:984
 msgid "CSV with Header"
 msgstr ""
 
-#: .\course\grades.py:977
+#: .\course\grades.py:987
 msgid "Format"
 msgstr ""
 
 #. Translators: the following strings are for the format
 #. informatioin for a CSV file to be imported.
-#: .\course\grades.py:982
+#: .\course\grades.py:992
 msgid ""
 "1-based column index for the Email or NetID used to locate student record"
 msgstr ""
 
-#: .\course\grades.py:985
+#: .\course\grades.py:995
 msgid "User ID column"
 msgstr ""
 
-#: .\course\grades.py:987
+#: .\course\grades.py:997
 msgid "1-based column index for the (numerical) grade"
 msgstr ""
 
-#: .\course\grades.py:989
+#: .\course\grades.py:999
 msgid "Points column"
 msgstr ""
 
-#: .\course\grades.py:991
+#: .\course\grades.py:1001
 msgid "1-based column index for further (textual) feedback"
 msgstr ""
 
-#: .\course\grades.py:993
+#: .\course\grades.py:1003
 msgid "Feedback column"
 msgstr ""
 
 #. Translators: "Max point" refers to full credit in points.
-#: .\course\grades.py:997 .\course\models.py:670 .\course\models.py:1034
+#: .\course\grades.py:1007 .\course\models.py:699 .\course\models.py:1079
 msgid "Max points"
 msgstr ""
 
-#: .\course\grades.py:1000 .\course\sandbox.py:70
+#: .\course\grades.py:1009 .\course\sandbox.py:70
 #: .\course\templates\course\grade-import-preview.html:14
-#: .\course\versioning.py:394
+#: .\course\versioning.py:390
 msgid "Preview"
 msgstr ""
 
-#: .\course\grades.py:1003
+#: .\course\grades.py:1010
 msgid "Import"
 msgstr ""
 
 #. Translators: use id_string to find user (participant).
-#: .\course\grades.py:1038
+#: .\course\grades.py:1045
 #, python-format
 msgid "no participant found for '%(id_string)s'"
 msgstr ""
 
-#: .\course\grades.py:1042
+#: .\course\grades.py:1049
 #, python-format
 msgid "more than one participant found for '%(id_string)s'"
 msgstr ""
 
-#: .\course\grades.py:1184
+#: .\course\grades.py:1191
 #, python-format
 msgid "%(total)d grades found, %(unchaged)d unchanged."
 msgstr ""
 
-#: .\course\grades.py:1198
+#: .\course\grades.py:1205
 #, python-format
 msgid "%d grades imported."
 msgstr ""
 
-#: .\course\grades.py:1211
+#: .\course\grades.py:1218
 msgid "Import Grade Data"
 msgstr ""
 
@@ -1311,47 +1311,47 @@ msgctxt "Send instant messages"
 msgid "Send"
 msgstr ""
 
-#: .\course\im.py:142
+#: .\course\im.py:141
 msgid "unable to connect"
 msgstr ""
 
-#: .\course\im.py:160
+#: .\course\im.py:159
 msgid "only enrolled folks may do that"
 msgstr ""
 
-#: .\course\im.py:167
+#: .\course\im.py:166
 msgid "Instant messaging is not enabled for this course."
 msgstr ""
 
-#: .\course\im.py:173
+#: .\course\im.py:172
 msgid "Recipient is <span class='label label-success'>Online</span>."
 msgstr ""
 
-#: .\course\im.py:176
+#: .\course\im.py:175
 msgid "Recipient is <span class='label label-danger'>Offline</span>."
 msgstr ""
 
-#: .\course\im.py:190
+#: .\course\im.py:189
 msgid "no recipient XMPP ID"
 msgstr ""
 
-#: .\course\im.py:193
+#: .\course\im.py:192
 msgid "no XMPP password"
 msgstr ""
 
-#: .\course\im.py:205
+#: .\course\im.py:204
 msgid "An error occurred while sending the message. Sorry."
 msgstr ""
 
-#: .\course\im.py:209
+#: .\course\im.py:208
 msgid "Message sent."
 msgstr ""
 
-#: .\course\im.py:218 .\course\templates\course\course-base.html:35
+#: .\course\im.py:217 .\course\templates\course\course-base.html:35
 msgid "Send instant message"
 msgstr ""
 
-#: .\course\models.py:73 .\course\models.py:315
+#: .\course\models.py:75 .\course\models.py:329
 #: .\course\templates\course\gradebook-by-opp.html:97
 #: .\course\templates\course\gradebook-participant-list.html:24
 #: .\course\templates\course\gradebook-participant.html:31
@@ -1359,994 +1359,994 @@ msgstr ""
 msgid "User ID"
 msgstr ""
 
-#: .\course\models.py:76 .\course\models.py:99
+#: .\course\models.py:78 .\course\models.py:101
 msgid "User status"
 msgstr ""
 
-#: .\course\models.py:78
+#: .\course\models.py:80
 msgid "The sign in token sent out in email."
 msgstr ""
 
 #. Translators: the sign in token of the user.
-#: .\course\models.py:81
+#: .\course\models.py:83
 msgid "Sign in key"
 msgstr ""
 
-#: .\course\models.py:83
+#: .\course\models.py:85
 msgid "The time stamp of the sign in token."
 msgstr ""
 
 #. Translators: the time when the token is sent out.
-#: .\course\models.py:85
+#: .\course\models.py:87
 msgid "Key time"
 msgstr ""
 
-#: .\course\models.py:89
+#: .\course\models.py:91
 msgid "Default"
 msgstr ""
 
 #. Translators: the text editor used by participants
-#: .\course\models.py:96
+#: .\course\models.py:98
 msgid "Editor mode"
 msgstr ""
 
-#: .\course\models.py:100
+#: .\course\models.py:102
 msgid "User statuses"
 msgstr ""
 
-#: .\course\models.py:104
+#: .\course\models.py:106
 #, python-format
 msgid "User status for %(user)s"
 msgstr ""
 
-#: .\course\models.py:113
+#: .\course\models.py:118
 msgid ""
 "A course identifier. Alphanumeric with dashes, no spaces. This is visible in "
 "URLs and determines the location on your file system where the course's git "
 "repository lives."
 msgstr ""
 
-#: .\course\models.py:116
+#: .\course\models.py:121
 msgid "Course identifier"
 msgstr ""
 
-#: .\course\models.py:122
+#: .\course\models.py:127
 msgid "Identifier may only contain letters, numbers, and hypens ('-')."
 msgstr ""
 
-#: .\course\models.py:129
+#: .\course\models.py:134
 msgid "Is the course only accessible to course staff?"
 msgstr ""
 
-#: .\course\models.py:130
+#: .\course\models.py:135
 msgid "Only visible to course staff"
 msgstr ""
 
-#: .\course\models.py:133
+#: .\course\models.py:138
 msgid "Should the course be listed on the main page?"
 msgstr ""
 
-#: .\course\models.py:134
+#: .\course\models.py:139
 msgid "Listed on main page"
 msgstr ""
 
-#: .\course\models.py:137
+#: .\course\models.py:142
 msgid "Accepts enrollment"
 msgstr ""
 
-#: .\course\models.py:140
+#: .\course\models.py:145
 msgid "Whether the course content has passed validation."
 msgstr ""
 
-#: .\course\models.py:141
+#: .\course\models.py:146
 msgid "Valid"
 msgstr ""
 
-#: .\course\models.py:144
+#: .\course\models.py:149
 msgid ""
 "A Git URL from which to pull course updates. If you're just starting out, "
 "enter <tt>git://github.com/inducer/relate-sample</tt> to get some sample "
 "content."
 msgstr ""
 
-#: .\course\models.py:148
+#: .\course\models.py:153
 msgid "git source"
 msgstr ""
 
-#: .\course\models.py:150
+#: .\course\models.py:155
 msgid ""
 "An SSH private key to use for Git authentication. Not needed for the sample "
 "URL above.You may use <a href='/generate-ssh-key'>this tool</a> to generate "
 "a key pair."
 msgstr ""
 
-#: .\course\models.py:154
+#: .\course\models.py:159
 msgid "SSH private key"
 msgstr ""
 
-#: .\course\models.py:157
+#: .\course\models.py:162
 msgid ""
 "Subdirectory in git repository to use as course root directory. Should not "
 "include trailing slash."
 msgstr ""
 
-#: .\course\models.py:160
+#: .\course\models.py:165
 msgid "Course root directory"
 msgstr ""
 
-#: .\course\models.py:164
+#: .\course\models.py:169
 msgid ""
 "Name of a YAML file in the git repository that contains the root course "
 "descriptor."
 msgstr ""
 
-#: .\course\models.py:166
+#: .\course\models.py:171
 msgid "Course file"
 msgstr ""
 
-#: .\course\models.py:169
+#: .\course\models.py:174
 msgid ""
 "Name of a YAML file in the git repository that contains calendar information."
 msgstr ""
 
-#: .\course\models.py:171
+#: .\course\models.py:176 .\course\validation.py:886
 msgid "Events file"
 msgstr ""
 
-#: .\course\models.py:175
+#: .\course\models.py:180
 msgid "If set, each enrolling student must be individually approved."
 msgstr ""
 
-#: .\course\models.py:177
+#: .\course\models.py:182
 msgid "Enrollment approval required"
 msgstr ""
 
-#: .\course\models.py:180
+#: .\course\models.py:185
 msgid ""
 "Enrollee's email addresses must end in the specified suffix, such as "
 "'@illinois.edu'."
 msgstr ""
 
-#: .\course\models.py:182
+#: .\course\models.py:187
 msgid "Enrollment required email suffix"
 msgstr ""
 
 #. Translators: replace "RELATE" with the brand name of your
 #. website if necessary.
-#: .\course\models.py:187
+#: .\course\models.py:192
 msgid ""
 "This email address will be used in the 'From' line of automated emails sent "
 "by RELATE."
 msgstr ""
 
-#: .\course\models.py:189
+#: .\course\models.py:194
 msgid "From email"
 msgstr ""
 
-#: .\course\models.py:192
+#: .\course\models.py:197
 msgid "This email address will receive notifications about the course."
 msgstr ""
 
-#: .\course\models.py:194
+#: .\course\models.py:199
 msgid "Notify email"
 msgstr ""
 
-#: .\course\models.py:199
+#: .\course\models.py:204
 msgid ""
 "(Required only if the instant message feature is desired.) The Jabber/XMPP "
 "ID (JID) the course will use to sign in to an XMPP server."
 msgstr ""
 
-#: .\course\models.py:202
+#: .\course\models.py:207
 msgid "Course xmpp ID"
 msgstr ""
 
-#: .\course\models.py:204
+#: .\course\models.py:209
 msgid ""
 "(Required only if the instant message feature is desired.) The password to "
 "go with the JID above."
 msgstr ""
 
-#: .\course\models.py:206
+#: .\course\models.py:211
 msgid "Course xmpp password"
 msgstr ""
 
-#: .\course\models.py:209
+#: .\course\models.py:214
 msgid ""
 "(Required only if the instant message feature is desired.) The JID to which "
 "instant messages will be sent."
 msgstr ""
 
-#: .\course\models.py:211
+#: .\course\models.py:216
 msgid "Recipient xmpp ID"
 msgstr ""
 
-#: .\course\models.py:217 .\course\models.py:425
+#: .\course\models.py:222 .\course\models.py:445
 msgid "Active git commit SHA"
 msgstr ""
 
-#: .\course\models.py:224
+#: .\course\models.py:229
 msgid "Courses"
 msgstr ""
 
-#: .\course\models.py:248
+#: .\course\models.py:256
 msgid "Kind of event"
 msgstr ""
 
 #. Translators: ordinal of event of the same kind
-#: .\course\models.py:251
+#: .\course\models.py:259
 msgid "Ordinal of event"
 msgstr ""
 
-#: .\course\models.py:253 .\course\models.py:395 .\course\models.py:429
+#: .\course\models.py:261 .\course\models.py:415 .\course\models.py:449
 #: .\course\templates\course\flow-start.html:23
 msgid "Start time"
 msgstr ""
 
-#: .\course\models.py:255 .\course\models.py:397
+#: .\course\models.py:263 .\course\models.py:417
 msgid "End time"
 msgstr ""
 
 #. Translators: for when the due time is "All day", how the webpage
 #. of a event is displayed.
-#: .\course\models.py:259
+#: .\course\models.py:267
 msgid ""
 "Only affects the rendering in the class calendar, in that a start time is "
 "not shown"
 msgstr ""
 
-#: .\course\models.py:261
+#: .\course\models.py:269
 msgid "All day"
 msgstr ""
 
-#: .\course\models.py:264
+#: .\course\models.py:272
 msgid "Shown in calendar"
 msgstr ""
 
-#: .\course\models.py:267
+#: .\course\models.py:275
 msgid "Event"
 msgstr ""
 
-#: .\course\models.py:268
+#: .\course\models.py:276
 msgid "Events"
 msgstr ""
 
 #. Translators: name format of ParticipationTag
-#: .\course\models.py:288
+#: .\course\models.py:299
 msgid "Format is lower-case-with-hyphens. Do not use spaces."
 msgstr ""
 
-#: .\course\models.py:290
+#: .\course\models.py:301
 msgid "Name of participation tag"
 msgstr ""
 
-#: .\course\models.py:301
+#: .\course\models.py:312
 msgid "Name contains invalid characters."
 msgstr ""
 
-#: .\course\models.py:307
+#: .\course\models.py:321
 msgid "Participation tag"
 msgstr ""
 
-#: .\course\models.py:308
+#: .\course\models.py:322
 msgid "Participation tags"
 msgstr ""
 
-#: .\course\models.py:320
+#: .\course\models.py:334
 msgid "Enroll time"
 msgstr ""
 
-#: .\course\models.py:323
+#: .\course\models.py:337
 msgid ""
 "Instructors may update course content. Teaching assistants may access and "
 "change grade data. Observers may access analytics. Each role includes "
 "privileges from subsequent roles."
 msgstr ""
 
-#: .\course\models.py:327
+#: .\course\models.py:341
 msgid "Participation role"
 msgstr ""
 
-#: .\course\models.py:330
+#: .\course\models.py:344
 msgid "Participation status"
 msgstr ""
 
-#: .\course\models.py:335
+#: .\course\models.py:349
 msgid "Multiplier for time available on time-limited flows"
 msgstr ""
 
-#: .\course\models.py:337
+#: .\course\models.py:351
 msgid "Time factor"
 msgstr ""
 
-#: .\course\models.py:341
+#: .\course\models.py:355
 msgid "Preview git commit SHA"
 msgstr ""
 
-#: .\course\models.py:344
+#: .\course\models.py:358
 msgid "Tags"
 msgstr ""
 
 #. Translators: displayed format of Participation: some user in some
 #. course as some role
-#: .\course\models.py:349
+#: .\course\models.py:363
 #, python-format
 msgid "%(user)s in %(course)s as %(role)s"
 msgstr ""
 
-#: .\course\models.py:354 .\course\models.py:416 .\course\models.py:789
-#: .\course\models.py:859 .\course\models.py:1015 .\course\models.py:1285
-#: .\course\models.py:1345 .\course\templates\course\course-base.html:116
+#: .\course\models.py:371 .\course\models.py:436 .\course\models.py:821
+#: .\course\models.py:897 .\course\models.py:1060 .\course\models.py:1333
+#: .\course\models.py:1399 .\course\templates\course\course-base.html:116
 msgid "Participation"
 msgstr ""
 
-#: .\course\models.py:355
+#: .\course\models.py:372
 msgid "Participations"
 msgstr ""
 
-#: .\course\models.py:370 .\course\models.py:807 .\course\models.py:864
-#: .\course\models.py:1043 .\course\models.py:1348
+#: .\course\models.py:387 .\course\models.py:839 .\course\models.py:902
+#: .\course\models.py:1088 .\course\models.py:1402
 msgid "Creator"
 msgstr ""
 
-#: .\course\models.py:372 .\course\models.py:809 .\course\models.py:866
-#: .\course\models.py:977 .\course\models.py:1350
+#: .\course\models.py:389 .\course\models.py:841 .\course\models.py:904
+#: .\course\models.py:1018 .\course\models.py:1404
 msgid "Creation time"
 msgstr ""
 
 #. Translators: somebody's email in some course in Participation
 #. Preapproval
-#: .\course\models.py:377
+#: .\course\models.py:394
 #, python-format
 msgid "%(email)s in %(course)s"
 msgstr ""
 
-#: .\course\models.py:381
+#: .\course\models.py:401
 msgid "Participation preapproval"
 msgstr ""
 
-#: .\course\models.py:382
+#: .\course\models.py:402
 msgid "Participation preapprovals"
 msgstr ""
 
-#: .\course\models.py:399
+#: .\course\models.py:419
 msgid "Cancelled"
 msgstr ""
 
-#: .\course\models.py:402
+#: .\course\models.py:422
 msgid "Instant flow request"
 msgstr ""
 
-#: .\course\models.py:403 .\course\templates\course\course-base.html:120
+#: .\course\models.py:423 .\course\templates\course\course-base.html:120
 msgid "Instant flow requests"
 msgstr ""
 
-#: .\course\models.py:431
+#: .\course\models.py:451
 msgid "Completition time"
 msgstr ""
 
-#: .\course\models.py:433
+#: .\course\models.py:453
 msgid "Page count"
 msgstr ""
 
-#: .\course\models.py:436
+#: .\course\models.py:456
 msgid "In progress"
 msgstr ""
 
-#: .\course\models.py:443 .\course\templates\course\gradebook-single.html:168
+#: .\course\models.py:463 .\course\templates\course\gradebook-single.html:168
 msgid "Expiration mode"
 msgstr ""
 
-#: .\course\models.py:452 .\course\models.py:1032
+#: .\course\models.py:472 .\course\models.py:1077
 #: .\course\templates\course\gradebook-single.html:227
 msgid "Points"
 msgstr ""
 
-#: .\course\models.py:455
+#: .\course\models.py:475
 msgid "Max point"
 msgstr ""
 
-#: .\course\models.py:457
+#: .\course\models.py:477
 msgid "Result comment"
 msgstr ""
 
-#: .\course\models.py:460 .\course\models.py:520 .\course\models.py:564
-#: .\course\models.py:1049 .\course\templates\course\grade-flow-page.html:58
+#: .\course\models.py:480 .\course\models.py:543 .\course\models.py:590
+#: .\course\models.py:1094 .\course\templates\course\grade-flow-page.html:58
 msgid "Flow session"
 msgstr ""
 
-#: .\course\models.py:461 .\course\templates\course\gradebook-single.html:133
+#: .\course\models.py:481 .\course\templates\course\gradebook-single.html:133
 msgid "Flow sessions"
 msgstr ""
 
-#: .\course\models.py:466
+#: .\course\models.py:486
 #, python-format
 msgid "anonymous session %(session_id)d on '%(flow_id)s'"
 msgstr ""
 
-#: .\course\models.py:470
+#: .\course\models.py:490
 #, python-format
 msgid "%(user)s's session %(session_id)d on '%(flow_id)s'"
 msgstr ""
 
-#: .\course\models.py:522
+#: .\course\models.py:545
 msgid "Ordinal"
 msgstr ""
 
-#: .\course\models.py:525
+#: .\course\models.py:548
 msgid "Group ID"
 msgstr ""
 
-#: .\course\models.py:532
+#: .\course\models.py:555
 msgid "Data"
 msgstr ""
 
-#: .\course\models.py:535 .\course\models.py:536
+#: .\course\models.py:558 .\course\models.py:559
 msgid "Flow page data"
 msgstr ""
 
-#: .\course\models.py:540
+#: .\course\models.py:563
 #, python-format
 msgid ""
 "Data for page '%(group_id)s/%(page_id)s' (ordinal %(ordinal)s) in %"
 "(flow_session)s"
 msgstr ""
 
-#: .\course\models.py:567 .\course\models.py:720
+#: .\course\models.py:593 .\course\models.py:752
 msgid "Page data"
 msgstr ""
 
-#: .\course\models.py:569
+#: .\course\models.py:595
 msgid "Visit time"
 msgstr ""
 
-#: .\course\models.py:571
+#: .\course\models.py:597
 msgid "Remote address"
 msgstr ""
 
-#: .\course\models.py:574
+#: .\course\models.py:600
 msgid ""
 "Synthetic flow page visits are generated for unvisited pages once a flow is "
 "finished. This is needed since grade information is attached to a visit, and "
 "it needs a place to go."
 msgstr ""
 
-#: .\course\models.py:578
+#: .\course\models.py:604
 msgid "Is synthetic"
 msgstr ""
 
 #. Translators: "Answer" is a Noun.
-#: .\course\models.py:584 .\course\page\code.py:59 .\course\page\text.py:98
+#: .\course\models.py:610 .\course\page\code.py:60 .\course\page\text.py:98
 msgid "Answer"
 msgstr ""
 
 #. Translators: determine whether the answer is a final,
 #. submitted answer fit for grading.
-#: .\course\models.py:597
+#: .\course\models.py:623
 msgid "Is submitted answer"
 msgstr ""
 
 #. Translators: flow page visit
-#: .\course\models.py:602
+#: .\course\models.py:628
 #, python-format
 msgid "'%(group_id)s/%(page_id)s' in '%(session)s' on %(time)s"
 msgstr ""
 
 #. Translators: flow page visit: if an answer is
 #. provided by user then append the string.
-#: .\course\models.py:612
+#: .\course\models.py:638
 msgid " (with answer)"
 msgstr ""
 
-#: .\course\models.py:617
+#: .\course\models.py:646
 msgid "Flow page visit"
 msgstr ""
 
-#: .\course\models.py:618
+#: .\course\models.py:647
 msgid "Flow page visits"
 msgstr ""
 
-#: .\course\models.py:645
+#: .\course\models.py:674
 msgid "Visit"
 msgstr ""
 
-#: .\course\models.py:649 .\course\templates\course\gradebook-single.html:228
+#: .\course\models.py:678 .\course\templates\course\gradebook-single.html:228
 msgid "Grader"
 msgstr ""
 
-#: .\course\models.py:651 .\course\models.py:1045
+#: .\course\models.py:680 .\course\models.py:1090
 msgid "Grade time"
 msgstr ""
 
-#: .\course\models.py:655
+#: .\course\models.py:684
 msgid "Graded at git commit SHA"
 msgstr ""
 
-#: .\course\models.py:660
+#: .\course\models.py:689
 msgid "Grade data"
 msgstr ""
 
 #. Translators: max point in grade
-#: .\course\models.py:668
+#: .\course\models.py:697
 msgid "Point value of this question when receiving full credit."
 msgstr ""
 
 #. Translators: correctness in grade
-#: .\course\models.py:673
+#: .\course\models.py:702
 msgid ""
 "Real number between zero and one (inclusively) indicating the degree of "
 "correctness of the answer."
 msgstr ""
 
-#: .\course\models.py:675
+#: .\course\models.py:704
 msgid "Correctness"
 msgstr ""
 
 #. Translators: "Feedback" stands for the feedback of answers.
-#: .\course\models.py:686
+#: .\course\models.py:715
 #: .\course\templates\course\grade-import-preview.html:20
 msgid "Feedback"
 msgstr ""
 
-#: .\course\models.py:701
+#: .\course\models.py:730
 msgid "Flow page visit grade"
 msgstr ""
 
-#: .\course\models.py:702
+#: .\course\models.py:731
 msgid "Flow page visit grades"
 msgstr ""
 
 #. Translators: return the information of the grade of a user
 #. by percentage.
-#: .\course\models.py:712
+#: .\course\models.py:741
 #, python-format
 msgid "grade of %(visit)s: %(percentage)s"
 msgstr ""
 
-#: .\course\models.py:722
+#: .\course\models.py:754
 #: .\course\templates\course\grade-import-preview.html:19
 #: .\course\templates\course\gradebook-participant.html:51
 #: .\course\templates\course\gradebook-single.html:74
 msgid "Grade"
 msgstr ""
 
-#: .\course\models.py:727
+#: .\course\models.py:759
 msgid "Bulk feedback"
 msgstr ""
 
-#: .\course\models.py:763
+#: .\course\models.py:795
 msgid "stipulations must be a dictionary"
 msgstr ""
 
-#: .\course\models.py:768
+#: .\course\models.py:800
 msgid "unrecognized keys in stipulations"
 msgstr ""
 
-#: .\course\models.py:774
+#: .\course\models.py:806
 msgid "credit_percent must be a float"
 msgstr ""
 
-#: .\course\models.py:780
+#: .\course\models.py:812
 msgid "'allowed_session_count' must be a non-negative integer"
 msgstr ""
 
-#: .\course\models.py:793 .\course\models.py:861
+#: .\course\models.py:825 .\course\models.py:899
 msgid "Expiration"
 msgstr ""
 
 #. Translators: help text for stipulations in FlowAccessException
 #. (deprecated)
-#: .\course\models.py:798
+#: .\course\models.py:830
 msgid ""
 "A dictionary of the same things that can be added to a flow access rule, "
 "such as allowed_session_count or credit_percent. If not specified here, "
 "values will default to the stipulations in the course content."
 msgstr ""
 
-#: .\course\models.py:804
+#: .\course\models.py:836
 msgid "Stipulations"
 msgstr ""
 
 #. Translators: deprecated
-#: .\course\models.py:814
+#: .\course\models.py:846
 msgid ""
 "Check if a flow started under this exception rule set should stay under this "
 "rule set until it is expired."
 msgstr ""
 
 #. Translators: deprecated
-#: .\course\models.py:818
+#: .\course\models.py:850
 msgid "Is sticky"
 msgstr ""
 
 #. Translators: flow access exception in admin (deprecated)
-#: .\course\models.py:826
+#: .\course\models.py:858
 #, python-format
 msgid "Access exception for '%(user)s' to '%(flow_id)s' in '%(course)s'"
 msgstr ""
 
-#: .\course\models.py:840
+#: .\course\models.py:875
 msgid "Exception"
 msgstr ""
 
-#: .\course\models.py:843
+#: .\course\models.py:878
 msgid "Permission"
 msgstr ""
 
 #. Translators: FlowAccessExceptionEntry (deprecated)
-#: .\course\models.py:847
+#: .\course\models.py:882
 msgid "Flow access exception entries"
 msgstr ""
 
-#: .\course\models.py:873
+#: .\course\models.py:911
 msgid "Kind"
 msgstr ""
 
-#: .\course\models.py:875
+#: .\course\models.py:913
 msgid "Rule"
 msgstr ""
 
-#: .\course\models.py:878
+#: .\course\models.py:916
 msgctxt "Is the flow rule exception activated?"
 msgid "Active"
 msgstr ""
 
 #. Translators: For FlowRuleException
-#: .\course\models.py:883
+#: .\course\models.py:921
 #, python-format
 msgid "%(kind)s exception for '%(user)s' to '%(flow_id)s'in '%(course)s'"
 msgstr ""
 
-#: .\course\models.py:896
+#: .\course\models.py:937
 msgid "grading rules may not expire"
 msgstr ""
 
-#: .\course\models.py:935
+#: .\course\models.py:976
 msgid "invalid rule kind: "
 msgstr ""
 
-#: .\course\models.py:939
+#: .\course\models.py:980
 msgid "invalid existing_session_rules: "
 msgstr ""
 
-#: .\course\models.py:942
+#: .\course\models.py:983
 msgid "Flow rule exception"
 msgstr ""
 
-#: .\course\models.py:943
+#: .\course\models.py:984
 msgid "Flow rule exceptions"
 msgstr ""
 
 #. Translators: format of identifier for GradingOpportunity
-#: .\course\models.py:956
+#: .\course\models.py:997
 msgid "A symbolic name for this grade. lower_case_with_underscores, no spaces."
 msgstr ""
 
-#: .\course\models.py:958
+#: .\course\models.py:999
 msgid "Grading opportunity ID"
 msgstr ""
 
 #. Translators: name for GradingOpportunity
-#: .\course\models.py:961
+#: .\course\models.py:1002
 msgid "A human-readable identifier for the grade."
 msgstr ""
 
-#: .\course\models.py:962
+#: .\course\models.py:1003
 msgid "Grading opportunity name"
 msgstr ""
 
-#: .\course\models.py:964
+#: .\course\models.py:1005
 msgid "Flow identifier that this grading opportunity is linked to, if any"
 msgstr ""
 
 #. Translators: strategy on how the grading of mutiple sessioins
 #. are aggregated.
-#: .\course\models.py:972 .\course\templates\course\gradebook-by-opp.html:36
+#: .\course\models.py:1013 .\course\templates\course\gradebook-by-opp.html:36
 #: .\course\templates\course\gradebook-opp-list.html:27
 #: .\course\templates\course\gradebook-single.html:121
 msgid "Aggregation strategy"
 msgstr ""
 
-#: .\course\models.py:975 .\course\models.py:1040
-#: .\course\templates\course\gradebook-opp-list.html:28 .\course\views.py:790
+#: .\course\models.py:1016 .\course\models.py:1085
+#: .\course\templates\course\gradebook-opp-list.html:28 .\course\views.py:785
 msgid "Due time"
 msgstr ""
 
-#: .\course\models.py:980
+#: .\course\models.py:1021
 msgid "Shown in grade book"
 msgstr ""
 
-#: .\course\models.py:982
+#: .\course\models.py:1023
 msgid "Shown in student grade book"
 msgstr ""
 
-#: .\course\models.py:985 .\course\models.py:1012
+#: .\course\models.py:1026 .\course\models.py:1057
 msgid "Grading opportunity"
 msgstr ""
 
-#: .\course\models.py:986
+#: .\course\models.py:1027
 msgid "Grading opportunities"
 msgstr ""
 
 #. Translators: For GradingOpportunity
-#: .\course\models.py:993
+#: .\course\models.py:1034
 #, python-format
 msgid "%(opportunity_name)s (%(opportunity_id)s) in %(course)s"
 msgstr ""
 
 #. Translators: something like 'status'.
-#: .\course\models.py:1020 .\course\templates\course\flow-start.html:24
+#: .\course\models.py:1065 .\course\templates\course\flow-start.html:24
 #: .\course\templates\course\gradebook-single.html:141
 msgid "State"
 msgstr ""
 
 #. Translators: help text of "attempt_id" in GradeChange class
-#: .\course\models.py:1025
+#: .\course\models.py:1070
 msgid ""
 "Grade changes are grouped by their 'attempt ID' where later grades with the "
 "same attempt ID supersede earlier ones."
 msgstr ""
 
-#: .\course\models.py:1052
+#: .\course\models.py:1097
 msgid "Grade change"
 msgstr ""
 
-#: .\course\models.py:1053
+#: .\course\models.py:1098
 msgid "Grade changes"
 msgstr ""
 
 #. Translators: information for GradeChange
-#: .\course\models.py:1058
+#: .\course\models.py:1103
 #, python-format
 msgid "%(participation)s %(state)s on %(opportunityname)s"
 msgstr ""
 
-#: .\course\models.py:1067
+#: .\course\models.py:1115
 msgid "Participation and opportunity must live in the same course"
 msgstr ""
 
-#: .\course\models.py:1119
+#: .\course\models.py:1167
 msgid "cannot accept grade once opportunity has been marked 'unavailable'"
 msgstr ""
 
-#: .\course\models.py:1123
+#: .\course\models.py:1171
 msgid "cannot accept grade once opportunity has been marked 'exempt'"
 msgstr ""
 
-#: .\course\models.py:1166
+#: .\course\models.py:1214
 #, python-format
 msgid "invalid grade change state '%s'"
 msgstr ""
 
-#: .\course\models.py:1208
+#: .\course\models.py:1256
 #, python-format
 msgid "invalid grade aggregation strategy '%s'"
 msgstr ""
 
 #. Translators: display the name of a flow
-#: .\course\models.py:1258
+#: .\course\models.py:1306
 #, python-format
 msgid "Flow: %(flow_desc_title)s"
 msgstr ""
 
-#: .\course\models.py:1287
+#: .\course\models.py:1335
 msgid "Text"
 msgstr ""
 
-#: .\course\models.py:1289 .\course\templates\course\gradebook-single.html:71
+#: .\course\models.py:1337 .\course\templates\course\gradebook-single.html:71
 #: .\course\views.py:263
 msgid "Time"
 msgstr ""
 
-#: .\course\models.py:1292
+#: .\course\models.py:1340
 msgid "Instant message"
 msgstr ""
 
-#: .\course\models.py:1293
+#: .\course\models.py:1341
 msgid "Instant messages"
 msgstr ""
 
-#: .\course\models.py:1308
+#: .\course\models.py:1359
 msgid "Description"
 msgstr ""
 
-#: .\course\models.py:1313
+#: .\course\models.py:1364
 msgid "Currently active"
 msgstr ""
 
-#: .\course\models.py:1316
+#: .\course\models.py:1367
 msgid "No exams before"
 msgstr ""
 
-#: .\course\models.py:1319
+#: .\course\models.py:1370
 msgid "No exams after"
 msgstr ""
 
-#: .\course\models.py:1323
+#: .\course\models.py:1374
 msgid "Lock down sessions"
 msgstr ""
 
-#: .\course\models.py:1324
+#: .\course\models.py:1375
 msgid ""
 "Only allow access to exam content (and no other content in this RELATE "
 "instance) in sessions logged in through this exam"
 msgstr ""
 
-#: .\course\models.py:1330 .\course\templates\course\course-base.html:74
-#: .\relate\templates\base.html:87
+#: .\course\models.py:1381 .\course\templates\course\course-base.html:74
+#: .\relate\templates\base.html:84
 msgid "Exams"
 msgstr ""
 
-#: .\course\models.py:1334
+#: .\course\models.py:1385
 #, python-format
 msgid "Exam  %(description)s in %(course)s"
 msgstr ""
 
-#: .\course\models.py:1352
+#: .\course\models.py:1406
 msgid "Usage time"
 msgstr ""
 
-#: .\course\models.py:1357
+#: .\course\models.py:1411
 msgid "Exam ticket state"
 msgstr ""
 
-#: .\course\models.py:1362
+#: .\course\models.py:1416
 msgid "Exam ticket"
 msgstr ""
 
-#: .\course\models.py:1363
+#: .\course\models.py:1417
 msgid "Exam tickets"
 msgstr ""
 
-#: .\course\models.py:1366
+#: .\course\models.py:1420
 msgid "Can issue exam tickets to student"
 msgstr ""
 
-#: .\course\models.py:1370
+#: .\course\models.py:1424
 #, python-format
 msgid "Exam  ticket for %(participation)s in %(exam)s"
 msgstr ""
 
-#: .\course\models.py:1380
+#: .\course\models.py:1437
 msgid "Participation and exam must live in the same course"
 msgstr ""
 
-#: .\course\page\base.py:103
+#: .\course\page\base.py:104
 msgid "Your answer is not correct."
 msgstr ""
 
-#: .\course\page\base.py:105
+#: .\course\page\base.py:106
 msgid "Your answer is correct."
 msgstr ""
 
-#: .\course\page\base.py:109
+#: .\course\page\base.py:110
 msgid "Your answer is mostly correct."
 msgstr ""
 
-#: .\course\page\base.py:113
+#: .\course\page\base.py:114
 msgid "No information on correctness of answer."
 msgstr ""
 
-#: .\course\page\base.py:117
+#: .\course\page\base.py:118
 msgid "Your answer is somewhat correct."
 msgstr ""
 
-#: .\course\page\base.py:146
+#: .\course\page\base.py:147
 msgid "Invalid correctness value"
 msgstr ""
 
-#: .\course\page\base.py:535
+#: .\course\page\base.py:536
 #, python-format
 msgid ""
 "PageBaseWithTitle subclass '%s' does not implement markdown_body_for_title()"
 msgstr ""
 
-#: .\course\page\base.py:545
+#: .\course\page\base.py:546
 msgid "no title found in body or title attribute"
 msgstr ""
 
-#: .\course\page\base.py:586
+#: .\course\page\base.py:587
 msgid "Grade assigned, in percent"
 msgstr ""
 
-#: .\course\page\base.py:591
+#: .\course\page\base.py:592
 msgid "Grade percent"
 msgstr ""
 
-#: .\course\page\base.py:597
+#: .\course\page\base.py:598
 #, python-format
 msgid ""
 "Grade assigned, as points out of %.1f. Fill out either this or 'grade "
 "percent'."
 msgstr ""
 
-#: .\course\page\base.py:604
+#: .\course\page\base.py:605
 msgid "Grade points"
 msgstr ""
 
-#: .\course\page\base.py:610
+#: .\course\page\base.py:611
 msgid ""
 "Feedback to be shown to student, using <a href='http://documen.tician.de/"
 "relate/content.html#relate-markup'>RELATE-flavored Markdown</a>"
 msgstr ""
 
-#: .\course\page\base.py:614
+#: .\course\page\base.py:615
 msgid "Feedback text"
 msgstr ""
 
-#: .\course\page\base.py:617
+#: .\course\page\base.py:618
 msgid ""
 "Checking this box and submitting the form will notify the participant with a "
 "generic message containing the feedback text"
 msgstr ""
 
-#: .\course\page\base.py:620
+#: .\course\page\base.py:621
 msgid "Notify"
 msgstr ""
 
-#: .\course\page\base.py:623
+#: .\course\page\base.py:624
 msgid "Whether the grade and feedback are to be shown to student"
 msgstr ""
 
-#: .\course\page\base.py:625
+#: .\course\page\base.py:626
 msgid "Released"
 msgstr ""
 
-#: .\course\page\base.py:628
+#: .\course\page\base.py:629
 msgid "Internal notes, not shown to student"
 msgstr ""
 
-#: .\course\page\base.py:630
+#: .\course\page\base.py:631
 msgid "Notes"
 msgstr ""
 
-#: .\course\page\base.py:643 .\course\page\base.py:657
+#: .\course\page\base.py:644 .\course\page\base.py:658
 msgid "Grade (percent) and Grade (points) disagree"
 msgstr ""
 
-#: .\course\page\base.py:733
+#: .\course\page\base.py:734
 msgid "New notification"
 msgstr ""
 
-#: .\course\page\base.py:763 .\course\page\choice.py:223
-#: .\course\page\choice.py:333 .\course\page\code.py:530
-#: .\course\page\code.py:834 .\course\page\inline.py:822
-#: .\course\page\text.py:897
+#: .\course\page\base.py:764 .\course\page\choice.py:224
+#: .\course\page\choice.py:334 .\course\page\code.py:530
+#: .\course\page\code.py:834 .\course\page\inline.py:820
+#: .\course\page\text.py:898
 msgid "No answer provided."
 msgstr ""
 
-#: .\course\page\base.py:785
+#: .\course\page\base.py:786
 msgid "The following feedback was provided"
 msgstr ""
 
 #. Translators: "choice" in Choice Answer Form in a single-choice question.
-#: .\course\page\choice.py:46
+#: .\course\page\choice.py:47
 msgid "Choice"
 msgstr ""
 
 #. Translators: "Choice" in Choice Answer Form in a multiple
 #. choice question in which multiple answers can be chosen.
-#: .\course\page\choice.py:57
+#: .\course\page\choice.py:58
 msgid "Choices"
 msgstr ""
 
-#: .\course\page\choice.py:125 .\course\page\choice.py:445
-#: .\course\page\inline.py:427
+#: .\course\page\choice.py:126 .\course\page\choice.py:446
+#: .\course\page\inline.py:425
 #, python-format
 msgid "choice %(idx)d: unable to convert to string"
 msgstr ""
 
-#: .\course\page\choice.py:140
+#: .\course\page\choice.py:141
 #, python-format
 msgid "one or more correct answer(s) expected, %(n_correct)d found"
 msgstr ""
 
-#: .\course\page\choice.py:237 .\course\page\inline.py:794
-#: .\course\page\text.py:918
+#: .\course\page\choice.py:238 .\course\page\inline.py:792
+#: .\course\page\text.py:919
 msgid "A correct answer is"
 msgstr ""
 
-#: .\course\page\choice.py:377
+#: .\course\page\choice.py:378
 msgid "The correct answer is"
 msgstr ""
 
@@ -2409,81 +2409,81 @@ msgstr ""
 msgid "human_feedback_value greater than overall value of question"
 msgstr ""
 
-#: .\course\page\inline.py:134
+#: .\course\page\inline.py:132
 #, python-format
 msgid "unknown embeded question type '%(type)s'"
 msgstr ""
 
-#: .\course\page\inline.py:148
+#: .\course\page\inline.py:146
 msgid "must be struct"
 msgstr ""
 
-#: .\course\page\inline.py:239
+#: .\course\page\inline.py:237
 #, python-format
 msgid "unrecogonized width attribute string: '%(width_attr)s'"
 msgstr ""
 
-#: .\course\page\inline.py:250
+#: .\course\page\inline.py:248
 #, python-format
 msgid ""
 "unsupported length unit '%(length_unit)s', expected length unit can be %"
 "(allowed_length_unit)s"
 msgstr ""
 
-#: .\course\page\inline.py:293 .\course\page\text.py:867
+#: .\course\page\inline.py:291 .\course\page\text.py:868
 msgid "at least one answer must be provided"
 msgstr ""
 
 #. Translators: refers to optional
 #. correct answer for checking
 #. correctness sumbitted by students.
-#: .\course\page\inline.py:316
+#: .\course\page\inline.py:314
 msgid "answer"
 msgstr ""
 
-#: .\course\page\inline.py:326 .\course\page\text.py:882
+#: .\course\page\inline.py:324 .\course\page\text.py:883
 msgid "no matcher is able to provide a plain-text correct answer"
 msgstr ""
 
-#: .\course\page\inline.py:444
+#: .\course\page\inline.py:442
 #, python-format
 msgid ""
 "one or more correct answer(s) expected  for question '%(question_name)s', %"
 "(n_correct)d found"
 msgstr ""
 
-#: .\course\page\inline.py:622
+#: .\course\page\inline.py:620
 #, python-format
 msgid "invalid answers name %s. "
 msgstr ""
 
-#: .\course\page\inline.py:623 .\course\page\inline.py:641
+#: .\course\page\inline.py:621 .\course\page\inline.py:639
 msgid ""
 "A valid name should start with letters. Alphanumeric with underscores. Do "
 "not use spaces."
 msgstr ""
 
-#: .\course\page\inline.py:640
+#: .\course\page\inline.py:638
 #, python-format
 msgid "invalid embeded question name %s. "
 msgstr ""
 
-#: .\course\page\inline.py:658
+#: .\course\page\inline.py:656
 #, python-format
 msgid "embeded question name %s not unique."
 msgstr ""
 
-#: .\course\page\inline.py:669
+#: .\course\page\inline.py:667
 #, python-format
 msgid "correct answer(s) not provided for question %s."
 msgstr ""
 
-#: .\course\page\inline.py:677
+#: .\course\page\inline.py:675
 #, python-format
 msgid "redundant answers %s provided for non-existing question(s)."
 msgstr ""
 
-#: .\course\page\inline.py:710
+#: .\course\page\inline.py:708
 #, python-format
 msgid "have unpaired '%s'."
 msgstr ""
@@ -2497,7 +2497,7 @@ msgstr ""
 msgid "unknown validator type"
 msgstr ""
 
-#: .\course\page\text.py:186 .\course\page\text.py:586
+#: .\course\page\text.py:186 .\course\page\text.py:587
 msgid "must be struct or string"
 msgstr ""
 
@@ -2506,16 +2506,16 @@ msgstr ""
 msgid "regex '%(pattern)s' did not compile"
 msgstr ""
 
-#: .\course\page\text.py:340
+#: .\course\page\text.py:341
 msgid "unable to check symbolic expression"
 msgstr ""
 
-#: .\course\page\text.py:444 .\course\page\text.py:455
-#: .\course\page\text.py:465
+#: .\course\page\text.py:445 .\course\page\text.py:456
+#: .\course\page\text.py:466
 msgid "does not provide a valid float literal"
 msgstr ""
 
-#: .\course\page\text.py:475
+#: .\course\page\text.py:476
 msgid ""
 "Float match should have either rtol or atol--otherwise it will match any "
 "number"
@@ -2524,29 +2524,29 @@ msgstr ""
 #. Translators: a "matcher" is used to determine
 #. if the answer to text question (blank filling
 #. question) is correct.
-#: .\course\page\text.py:533
+#: .\course\page\text.py:534
 #, python-format
 msgid "%(matcherclassname)s only accepts '%(matchertype)s' patterns"
 msgstr ""
 
-#: .\course\page\text.py:545
+#: .\course\page\text.py:546
 #, python-format
 msgid "unknown match type '%(matchertype)s'"
 msgstr ""
 
-#: .\course\page\text.py:564
+#: .\course\page\text.py:565
 msgid "does not specify match type"
 msgstr ""
 
-#: .\course\page\text.py:572
+#: .\course\page\text.py:573
 msgid "uses deprecated 'matcher:answer' style"
 msgstr ""
 
-#: .\course\page\text.py:593
+#: .\course\page\text.py:594
 msgid "matcher must supply 'type'"
 msgstr ""
 
-#: .\course\page\text.py:644
+#: .\course\page\text.py:645
 msgid "unrecognized widget type"
 msgstr ""
 
@@ -3370,7 +3370,7 @@ msgstr ""
 msgid "at %(grade_time)s"
 msgstr ""
 
-#: .\course\templates\course\grade-flow-page.html:131 .\course\views.py:596
+#: .\course\templates\course\grade-flow-page.html:131 .\course\views.py:592
 msgid "Session"
 msgstr ""
 
@@ -3668,7 +3668,7 @@ msgstr ""
 msgid "<a href=\"%(relate-sign_in_by_user_pw)s\">Sign in</a> to get started."
 msgstr ""
 
-#: .\course\templates\course\home.html:41 .\course\versioning.py:248
+#: .\course\templates\course\home.html:41 .\course\versioning.py:251
 msgid "Set up new course"
 msgstr ""
 
@@ -3976,131 +3976,144 @@ msgstr ""
 msgid "group id '%(group_id)s' not unique"
 msgstr ""
 
-#: .\course\validation.py:900
+#: .\course\validation.py:887
+#, python-format
+msgid "Your course repository does not have an events file named '%s'."
+msgstr ""
+
+#: .\course\validation.py:907
 msgid ""
 "Your course repository has a 'media/' directory. Linking to media files "
 "using 'media:' is discouraged. Use the 'repo:' and 'repocur:' linkng schemes "
 "instead."
 msgstr ""
 
-#: .\course\validation.py:922
+#: .\course\validation.py:929
 msgid ""
 "invalid flow name. Flow names may only contain (roman) letters, numbers, "
 "dashes and underscores."
 msgstr ""
 
-#: .\course\validation.py:1046
+#: .\course\validation.py:952
+msgid "flow uses more than one grade_identifier"
+msgstr ""
+
+#: .\course\validation.py:959
+msgid "flow uses the same grade_identifier as another flow"
+msgstr ""
+
+#: .\course\validation.py:1057
 msgid "WARNINGS: "
 msgstr ""
 
-#: .\course\versioning.py:133
+#: .\course\versioning.py:137
 msgid "Validate and create"
 msgstr ""
 
-#: .\course\versioning.py:140
+#: .\course\versioning.py:143
 msgid "only staff may create courses"
 msgstr ""
 
-#: .\course\versioning.py:197
+#: .\course\versioning.py:200
 msgid "Course content validated, creation succeeded."
 msgstr ""
 
-#: .\course\versioning.py:223
+#: .\course\versioning.py:226
 #, python-format
 msgid "Failed to delete unused repository directory '%s'."
 msgstr ""
 
-#: .\course\versioning.py:235
+#: .\course\versioning.py:238
 msgid "Course creation failed"
 msgstr ""
 
-#: .\course\versioning.py:284
+#: .\course\versioning.py:287
 msgid "no git source URL specified"
 msgstr ""
 
-#: .\course\versioning.py:296
+#: .\course\versioning.py:299
 msgid "fetch would discard commits, refusing"
 msgstr ""
 
-#: .\course\versioning.py:300
+#: .\course\versioning.py:303
 msgid "Fetch successful."
 msgstr ""
 
-#: .\course\versioning.py:309
+#: .\course\versioning.py:312
 msgid "Preview ended."
 msgstr ""
 
-#: .\course\versioning.py:324
+#: .\course\versioning.py:327
 #, python-format
 msgid "Course content did not validate successfully. (%s) Update not applied."
 msgstr ""
 
-#: .\course\versioning.py:331
+#: .\course\versioning.py:334
 msgid "Course content validated successfully."
 msgstr ""
 
-#: .\course\versioning.py:335
+#: .\course\versioning.py:338
 msgid "Course content validated OK, with warnings: "
 msgstr ""
 
-#: .\course\versioning.py:346
+#: .\course\versioning.py:349
 msgid "Preview activated."
 msgstr ""
 
-#: .\course\versioning.py:357
+#: .\course\versioning.py:360
 msgid "Update applied. "
 msgstr ""
 
-#: .\course\versioning.py:360 .\course\versioning.py:439 .\course\views.py:686
+#: .\course\versioning.py:363 .\course\versioning.py:435 .\course\views.py:681
 msgid "invalid command"
 msgstr ""
 
-#: .\course\versioning.py:367
+#: .\course\versioning.py:370
 msgctxt "new git SHA for revision of course contents"
 msgid "New git SHA"
 msgstr ""
 
-#: .\course\versioning.py:369
+#: .\course\versioning.py:372
 msgid "Prevent updating to a git revision prior to the current one"
 msgstr ""
 
-#: .\course\versioning.py:387
+#: .\course\versioning.py:383
 msgid "Fetch and update"
 msgstr ""
 
-#: .\course\versioning.py:391
+#: .\course\versioning.py:387
 msgid "End preview"
 msgstr ""
 
-#: .\course\versioning.py:393
+#: .\course\versioning.py:389
 msgid "Fetch and preview"
 msgstr ""
 
-#: .\course\versioning.py:396
+#: .\course\versioning.py:392
 msgid "Fetch"
 msgstr ""
 
-#: .\course\versioning.py:407
+#: .\course\versioning.py:403
 msgid "must be instructor or TA to update course"
 msgstr ""
 
-#: .\course\versioning.py:474
+#: .\course\versioning.py:475
 msgid "Current git HEAD"
 msgstr ""
 
-#: .\course\versioning.py:481
+#: .\course\versioning.py:483
 msgid "Public active git SHA"
 msgstr ""
 
-#: .\course\versioning.py:494 .\course\versioning.py:506
+#: .\course\versioning.py:496 .\course\versioning.py:508
 msgid "Current preview git SHA"
 msgstr ""
 
-#: .\course\versioning.py:508
+#: .\course\versioning.py:510
 msgid "None"
 msgstr ""
 
-#: .\course\versioning.py:516
+#: .\course\versioning.py:518
 msgid "Update Course Revision"
 msgstr ""
 
@@ -4132,7 +4145,7 @@ msgstr ""
 msgid "only staff may set fake time"
 msgstr ""
 
-#: .\course\views.py:325 .\relate\templates\base.html:81
+#: .\course\views.py:325 .\relate\templates\base.html:78
 msgid "Set fake time"
 msgstr ""
 
@@ -4146,95 +4159,95 @@ msgctxt "Add an instant flow"
 msgid "Add"
 msgstr ""
 
-#: .\course\views.py:360
+#: .\course\views.py:359
 msgctxt "Cancel all instant flow(s)"
 msgid "Cancel all"
 msgstr ""
 
-#: .\course\views.py:367
+#: .\course\views.py:366
 msgid "must be instructor to manage instant flow requests"
 msgstr ""
 
-#: .\course\views.py:414
+#: .\course\views.py:413
 msgid "Manage Instant Flow Requests"
 msgstr ""
 
-#: .\course\views.py:436
+#: .\course\views.py:435
 msgctxt "Start an activity"
 msgid "Go"
 msgstr ""
 
-#: .\course\views.py:446
+#: .\course\views.py:445
 msgid "must be instructor or TA to test flows"
 msgstr ""
 
-#: .\course\views.py:467
+#: .\course\views.py:466
 msgid "Test Flow"
 msgstr ""
 
-#: .\course\views.py:512 .\course\views.py:603
+#: .\course\views.py:511 .\course\views.py:599
 msgctxt "Next step"
 msgid "Next"
 msgstr ""
 
-#: .\course\views.py:523 .\course\views.py:614 .\course\views.py:828
+#: .\course\views.py:521 .\course\views.py:609 .\course\views.py:822
 msgid "must be instructor or TA to grant exceptions"
 msgstr ""
 
-#: .\course\views.py:543 .\course\views.py:723 .\course\views.py:995
+#: .\course\views.py:541 .\course\views.py:718 .\course\views.py:989
 msgid "Grant Exception"
 msgstr ""
 
 #. Translators: %s is the string of the start time of a session.
-#: .\course\views.py:550
+#: .\course\views.py:548
 #, python-format
 msgid "started at %s"
 msgstr ""
 
-#: .\course\views.py:567
+#: .\course\views.py:565
 msgid ""
 "If you click 'Create session', this tag will be applied to the new session."
 msgstr ""
 
-#: .\course\views.py:569
+#: .\course\views.py:567
 msgid "Access rules tag for new session"
 msgstr ""
 
-#: .\course\views.py:575
+#: .\course\views.py:573
 msgid "Create session (override rules)"
 msgstr ""
 
-#: .\course\views.py:581
+#: .\course\views.py:578
 msgid "Create session"
 msgstr ""
 
-#: .\course\views.py:593
+#: .\course\views.py:589
 msgid ""
 "The rules that currently apply to selected session will provide the default "
 "values for the rules on the next page."
 msgstr ""
 
-#: .\course\views.py:623
+#: .\course\views.py:618
 #, python-format
 msgid "Granting exception to '%(participation)s' for '%(flow_id)s'."
 msgstr ""
 
-#: .\course\views.py:644 .\course\views.py:648
+#: .\course\views.py:639 .\course\views.py:643
 msgid "NONE"
 msgstr ""
 
-#: .\course\views.py:658
+#: .\course\views.py:653
 msgid ""
 "Creating a new session is (technically) not allowed by course rules. "
 "Clicking 'Create Session' anyway will override this rule."
 msgstr ""
 
-#: .\course\views.py:733
+#: .\course\views.py:728
 msgctxt "Time when access expires"
 msgid "Access expires"
 msgstr ""
 
-#: .\course\views.py:734
+#: .\course\views.py:729
 msgid ""
 "At the specified time, the special access granted below will expire and "
 "revert to being the same as for the rest of the class. This field may be "
@@ -4243,62 +4256,62 @@ msgid ""
 "remain valid indefinitely, unless overridden by another exception."
 msgstr ""
 
-#: .\course\views.py:759
+#: .\course\views.py:754
 msgid "Exception only applies to sessions with the above tag"
 msgstr ""
 
-#: .\course\views.py:778
+#: .\course\views.py:773
 msgid "If set, the 'Due' field will be disregarded."
 msgstr ""
 
-#: .\course\views.py:781
+#: .\course\views.py:776
 msgid "Due same as access expiration"
 msgstr ""
 
-#: .\course\views.py:786
+#: .\course\views.py:781
 msgid ""
 "The due time shown to the student. Also, the time after which any session "
 "under these rules is subject to expiration."
 msgstr ""
 
-#: .\course\views.py:794
+#: .\course\views.py:789
 msgid "Credit percent"
 msgstr ""
 
-#: .\course\views.py:807
+#: .\course\views.py:802
 msgid "Save"
 msgstr ""
 
-#: .\course\views.py:817
+#: .\course\views.py:811
 msgid ""
 "Must specify access expiration if 'due same as access expiration' is set."
 msgstr ""
 
-#: .\course\views.py:889 .\course\views.py:956
+#: .\course\views.py:883 .\course\views.py:950
 msgid "newly created exception"
 msgstr ""
 
-#: .\course\views.py:918
+#: .\course\views.py:912
 msgid "Granted excecption"
 msgstr ""
 
-#: .\course\views.py:920
+#: .\course\views.py:914
 msgid "credit"
 msgstr ""
 
-#: .\course\views.py:972
+#: .\course\views.py:966
 #, python-format
 msgid "Exception granted to '%(participation)s' for '%(flow_id)s'."
 msgstr ""
 
-#: .\course\views.py:998
+#: .\course\views.py:992
 #, python-format
 msgid ""
 "Granting exception to '%(participation)s' for '%(flow_id)s' (session %"
 "(session)s)."
 msgstr ""
 
-#: .\course\views.py:1015
+#: .\course\views.py:1009
 msgid "only staff may use this tool"
 msgstr ""
 
@@ -4377,32 +4390,32 @@ msgid ""
 "(fake_time)s."
 msgstr ""
 
-#: .\relate\templates\base.html:70
+#: .\relate\templates\base.html:67
 msgid "Staff"
 msgstr ""
 
-#: .\relate\templates\base.html:73
+#: .\relate\templates\base.html:70
 msgid "Admin site"
 msgstr ""
 
-#: .\relate\templates\base.html:75
+#: .\relate\templates\base.html:72
 msgid "Test/Troubleshoot"
 msgstr ""
 
-#: .\relate\templates\base.html:88
+#: .\relate\templates\base.html:85
 msgid "Issue exam tickets"
 msgstr ""
 
-#: .\relate\templates\base.html:89
+#: .\relate\templates\base.html:86
 msgid "Exam check-in"
 msgstr ""
 
-#: .\relate\templates\base.html:99
+#: .\relate\templates\base.html:96
 #, python-format
 msgid "Signed in as %(username)s"
 msgstr ""
 
-#: .\relate\templates\base.html:106
+#: .\relate\templates\base.html:103
 msgid "(impersonated)"
 msgstr ""
 
diff --git a/locale/zh_CN/LC_MESSAGES/django.po b/locale/zh_CN/LC_MESSAGES/django.po
index dfae02709c9599038cd18b6462cd897451973153..63e6c6285f6451fa155d3a89d58653ffb66c1ab3 100644
--- a/locale/zh_CN/LC_MESSAGES/django.po
+++ b/locale/zh_CN/LC_MESSAGES/django.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-09-08 15:11+0800\n"
+"POT-Creation-Date: 2015-09-11 12:45+0800\n"
 "Last-Translator:  Dong Zhuang <dzhuang.scut@gmail.com>\n"
 "Language-Team: Dong Zhuang <dzhuang.scut@gmail.com>\n"
 "MIME-Version: 1.0\n"
@@ -17,93 +17,93 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Language: \n"
 
-#: .\course\admin.py:82 .\course\admin.py:258
+#: .\course\admin.py:84 .\course\admin.py:266
 msgid "First name"
 msgstr "名"
 
-#: .\course\admin.py:88 .\course\admin.py:264
+#: .\course\admin.py:90 .\course\admin.py:272
 msgid "Last name"
 msgstr "姓"
 
-#: .\course\admin.py:248
+#: .\course\admin.py:256
 msgid "Tags must belong to same course as participation."
 msgstr "Tags必须与同一课程中的participation一致. "
 
-#: .\course\admin.py:367 .\course\admin.py:488 .\course\admin.py:572
-#: .\course\admin.py:685 .\course\admin.py:760 .\course\exam.py:90
-#: .\course\templates\course\gradebook-single.html:17 .\course\views.py:501
+#: .\course\admin.py:375 .\course\admin.py:496 .\course\admin.py:580
+#: .\course\admin.py:693 .\course\admin.py:768 .\course\exam.py:90
+#: .\course\templates\course\gradebook-single.html:17 .\course\views.py:500
 msgid "Participant"
 msgstr "参与者"
 
-#: .\course\admin.py:465 .\course\admin.py:567 .\course\admin.py:675
-#: .\course\admin.py:755 .\course\models.py:223 .\course\models.py:243
-#: .\course\models.py:285 .\course\models.py:317 .\course\models.py:364
-#: .\course\models.py:391 .\course\models.py:412 .\course\models.py:952
-#: .\course\models.py:1306
+#: .\course\admin.py:473 .\course\admin.py:575 .\course\admin.py:683
+#: .\course\admin.py:763 .\course\models.py:228 .\course\models.py:251
+#: .\course\models.py:296 .\course\models.py:331 .\course\models.py:381
+#: .\course\models.py:411 .\course\models.py:432 .\course\models.py:993
+#: .\course\models.py:1357
 msgid "Course"
 msgstr "课程"
 
-#: .\course\admin.py:470 .\course\flow.py:1520 .\course\models.py:393
-#: .\course\models.py:427 .\course\models.py:791 .\course\models.py:857
-#: .\course\models.py:966 .\course\models.py:1310
+#: .\course\admin.py:478 .\course\flow.py:1516 .\course\models.py:413
+#: .\course\models.py:447 .\course\models.py:823 .\course\models.py:895
+#: .\course\models.py:1007 .\course\models.py:1361
 #: .\course\templates\course\gradebook-opp-list.html:26
 #: .\course\templates\course\gradebook-single.html:140 .\course\views.py:346
-#: .\course\views.py:429 .\course\views.py:505
+#: .\course\views.py:428 .\course\views.py:504
 msgid "Flow ID"
 msgstr ""
 
-#: .\course\admin.py:479 .\course\models.py:527
+#: .\course\admin.py:487 .\course\models.py:550
 #: .\course\templates\course\gradebook-single.html:225
 msgid "Page ID"
 msgstr ""
 
-#: .\course\admin.py:486
+#: .\course\admin.py:494
 msgid "anonymous"
 msgstr "匿名"
 
-#: .\course\admin.py:493
+#: .\course\admin.py:501
 msgid "Has answer"
 msgstr "已经回答"
 
-#: .\course\admin.py:498
+#: .\course\admin.py:506
 msgid "Flow Session ID"
 msgstr ""
 
-#: .\course\admin.py:680
+#: .\course\admin.py:688
 msgid "Opportunity"
 msgstr "机会"
 
-#: .\course\admin.py:881
+#: .\course\admin.py:889
 msgid "Revoke Exam Tickets"
 msgstr "撤销测验Ticket"
 
 #. Translators: "TA" is short for Teaching Assistant.
-#: .\course\analytics.py:57 .\course\analytics.py:415
-#: .\course\analytics.py:452
+#: .\course\analytics.py:58 .\course\analytics.py:416
+#: .\course\analytics.py:453
 msgid "must be at least TA to view analytics"
 msgstr "至少是助教(TA)才能查看分析"
 
-#: .\course\analytics.py:105
+#: .\course\analytics.py:106
 msgctxt "No data"
 msgid "None"
 msgstr "无"
 
-#: .\course\analytics.py:114
+#: .\course\analytics.py:115
 msgctxt "Value of grade"
 msgid "value greater than max"
 msgstr "分值高于允许的最高值"
 
-#: .\course\analytics.py:122
+#: .\course\analytics.py:123
 msgctxt "Value of grade"
 msgid "value smaller than min"
 msgstr "分值低于允许的最低值"
 
-#: .\course\analytics.py:240 .\course\analytics.py:384
+#: .\course\analytics.py:241 .\course\analytics.py:385
 msgctxt "Status of session"
 msgid "in progress"
 msgstr "进行中"
 
-#: .\course\analytics.py:378
+#: .\course\analytics.py:379
 msgctxt "Minute (time unit)"
 msgid "min"
 msgstr "分钟"
@@ -120,7 +120,7 @@ msgstr "虚拟用户时出现错误. "
 #. userfor impersonating. Customize how the name is
 #. shown, but leave email first to retain usability
 #. of form sorted by last name.
-#: .\course\auth.py:137 .\course\exam.py:67 .\course\views.py:479
+#: .\course\auth.py:137 .\course\exam.py:67 .\course\views.py:478
 #, python-format
 msgid "%(user_email)s - %(user_lastname)s, %(user_firstname)s"
 msgstr "%(user_lastname)s%(user_firstname)s(%(user_email)s)"
@@ -129,7 +129,7 @@ msgstr "%(user_lastname)s%(user_firstname)s(%(user_email)s)"
 msgid "Select user to impersonate."
 msgstr "选择您想模拟的用户. "
 
-#: .\course\auth.py:149 .\course\models.py:422
+#: .\course\auth.py:149 .\course\models.py:442
 #: .\course\templates\course\grade-import-preview.html:18
 msgid "User"
 msgstr "用户"
@@ -138,83 +138,83 @@ msgstr "用户"
 msgid "Impersonate"
 msgstr "用户模拟"
 
-#: .\course\auth.py:159
+#: .\course\auth.py:158
 msgid "Already impersonating someone."
 msgstr "已经模拟了某个用户. "
 
-#: .\course\auth.py:168
+#: .\course\auth.py:167
 #, python-format
 msgid "Now impersonating '%s'."
 msgstr "正在模拟用户\"%s\". "
 
-#: .\course\auth.py:177 .\relate\templates\base.html:79
+#: .\course\auth.py:176 .\relate\templates\base.html:76
 msgid "Impersonate user"
 msgstr "用户模拟"
 
-#: .\course\auth.py:187 .\relate\templates\base.html:77
+#: .\course\auth.py:186 .\relate\templates\base.html:74
 msgid "Stop impersonating"
 msgstr "停止模拟用户"
 
-#: .\course\auth.py:193
+#: .\course\auth.py:192
 msgid "Not currently impersonating anyone."
 msgstr "当前未模拟任何用户. "
 
-#: .\course\auth.py:200
+#: .\course\auth.py:199
 msgid "No longer impersonating anyone."
 msgstr "未模拟任何用户. "
 
-#: .\course\auth.py:209
+#: .\course\auth.py:208
 msgid "Stop impersonating user"
 msgstr "停止模拟用户"
 
-#: .\course\auth.py:281 .\course\templates\course\course-page.html:38
+#: .\course\auth.py:280 .\course\templates\course\course-page.html:38
 #: .\course\templates\course\flow-start.html:186
 #: .\course\templates\course\login.html:7 .\relate\templates\403.html:14
-#: .\relate\templates\base.html:114
+#: .\relate\templates\base.html:111
 msgid "Sign in"
 msgstr "登录"
 
-#: .\course\auth.py:310 .\course\auth.py:667
+#: .\course\auth.py:308 .\course\auth.py:662
 msgid "Sign-in not allowed in this facility."
 msgstr "不允许在当前设置内登录."
 
-#: .\course\auth.py:312 .\course\auth.py:668
+#: .\course\auth.py:310 .\course\auth.py:663
 msgid "user not allowed to sign in in facility"
 msgstr "用户不允许在该设施内登录"
 
-#: .\course\auth.py:335
+#: .\course\auth.py:333
 msgid "Username"
 msgstr "用户名"
 
-#: .\course\auth.py:339
+#: .\course\auth.py:337
 msgid "Enter a valid username."
 msgstr ""
 
-#: .\course\auth.py:340
+#: .\course\auth.py:338
 msgid "This value may contain only letters, numbers and @/./+/-/_ characters."
 msgstr ""
 
-#: .\course\auth.py:356 .\course\auth.py:439
+#: .\course\auth.py:354 .\course\auth.py:436
 msgid "Send email"
 msgstr "发送邮件"
 
-#: .\course\auth.py:363 .\course\auth.py:445
+#: .\course\auth.py:360 .\course\auth.py:442
 msgid "password-based sign-in is not being used"
 msgstr "用户名密码模式未启用"
 
-#: .\course\auth.py:371
+#: .\course\auth.py:368
 msgid "A user with that username already exists."
 msgstr ""
 
-#: .\course\auth.py:376
+#: .\course\auth.py:373
 #, python-format
 msgid ""
 "That email address is already in use. Would you like to <a href='%s'>reset "
 "your password</a> instead?"
 msgstr "该电子邮件已经注册, 您是否需要 <a href='%s'>重置密码</a> ?"
 
-#: .\course\auth.py:411 .\course\auth.py:479 .\course\auth.py:496
-#: .\course\auth.py:570 .\course\auth.py:629
+#: .\course\auth.py:408 .\course\auth.py:476 .\course\auth.py:493
+#: .\course\auth.py:566 .\course\auth.py:624
 #: .\course\templates\course\analytics-flow.html:5
 #: .\course\templates\course\analytics-flows.html:5
 #: .\course\templates\course\analytics-page.html:5
@@ -238,180 +238,180 @@ msgstr "该电子邮件已经注册, 您是否需要 <a href='%s'>重置密码</
 #: .\course\templates\course\home.html:30
 #: .\course\templates\course\sandbox-page.html:17
 #: .\course\templates\course\sign-in-email.txt:2
-#: .\relate\templates\admin\base_site.html:5 .\relate\templates\base.html:15
-#: .\relate\templates\base.html.py:60 .\relate\templates\maintenance.html:6
+#: .\relate\templates\admin\base_site.html:5 .\relate\templates\base.html:12
+#: .\relate\templates\base.html.py:57 .\relate\templates\maintenance.html:6
 msgid "RELATE"
 msgstr "RELATE"
 
-#: .\course\auth.py:412
+#: .\course\auth.py:409
 msgid "Verify your email"
 msgstr "验证您的电子邮件"
 
-#: .\course\auth.py:418 .\course\auth.py:486 .\course\auth.py:635
+#: .\course\auth.py:415 .\course\auth.py:483 .\course\auth.py:630
 msgid "Email sent. Please check your email and click the link."
 msgstr "Email已发送, 请进入邮箱并点击相关的链接. "
 
-#: .\course\auth.py:427
+#: .\course\auth.py:424
 msgid "Sign up"
 msgstr "注册"
 
-#: .\course\auth.py:433 .\course\auth.py:580 .\course\models.py:362
+#: .\course\auth.py:430 .\course\auth.py:576 .\course\models.py:379
 msgid "Email"
 msgstr "Email"
 
-#: .\course\auth.py:459
+#: .\course\auth.py:456
 msgid ""
 "That email address doesn't have an associated user account. Are you sure "
 "you've registered?"
 msgstr ""
 
-#: .\course\auth.py:480
+#: .\course\auth.py:477
 msgid "Password reset"
 msgstr "密码重置"
 
-#: .\course\auth.py:495 .\course\auth.py:569
+#: .\course\auth.py:492 .\course\auth.py:565
 #, python-format
 msgid "Password reset on %(site_name)s"
 msgstr ""
 
-#: .\course\auth.py:503
+#: .\course\auth.py:500
 msgid "Password"
 msgstr "密码"
 
-#: .\course\auth.py:505
+#: .\course\auth.py:502
 msgid "Password confirmation"
 msgstr ""
 
-#: .\course\auth.py:511 .\course\auth.py:699 .\course\auth.py:712
+#: .\course\auth.py:508 .\course\auth.py:694 .\course\auth.py:706
 #: .\course\templates\course\course-page.html:30
-#: .\course\templates\course\home.html:22 .\course\versioning.py:388
+#: .\course\templates\course\home.html:22 .\course\versioning.py:384
 msgid "Update"
 msgstr "更新"
 
-#: .\course\auth.py:520
+#: .\course\auth.py:516
 msgid "The two password fields didn't match."
 msgstr ""
 
-#: .\course\auth.py:525 .\course\auth.py:594 .\course\auth.py:649
+#: .\course\auth.py:521 .\course\auth.py:589 .\course\auth.py:644
 msgid "email-based sign-in is not being used"
 msgstr "基于邮件链接登录的方式未启用"
 
-#: .\course\auth.py:529 .\course\auth.py:655
+#: .\course\auth.py:525 .\course\auth.py:650
 msgid "Invalid sign-in token. Perhaps you've used an old token email?"
 msgstr "登录链接无效, 您可能使用了一个旧邮件中的链接?"
 
-#: .\course\auth.py:531 .\course\auth.py:539 .\course\auth.py:544
-#: .\course\auth.py:657 .\course\auth.py:662
+#: .\course\auth.py:527 .\course\auth.py:535 .\course\auth.py:540
+#: .\course\auth.py:652 .\course\auth.py:657
 msgid "invalid sign-in token"
 msgstr "登录链接无效"
 
-#: .\course\auth.py:543 .\course\auth.py:661
+#: .\course\auth.py:539 .\course\auth.py:656
 msgid "Account disabled."
 msgstr "帐户已禁用. "
 
-#: .\course\auth.py:554 .\course\auth.py:674
+#: .\course\auth.py:550 .\course\auth.py:669
 msgid ""
 "Successfully signed in. Please complete your registration information below."
 msgstr "成功登录, 请在下面完善您的注册信息. "
 
-#: .\course\auth.py:561 .\course\auth.py:681
+#: .\course\auth.py:557 .\course\auth.py:676
 msgid "Successfully signed in."
 msgstr "成功登录. "
 
-#: .\course\auth.py:588
+#: .\course\auth.py:584
 msgid "Send sign-in email"
 msgstr "发送登录邮件"
 
-#: .\course\auth.py:629
+#: .\course\auth.py:624
 #, python-format
 msgid "Your %(RELATE)s sign-in link"
 msgstr "您的%(RELATE)s登录链接"
 
-#: .\course\auth.py:733 .\course\auth.py:743
+#: .\course\auth.py:726 .\course\auth.py:736
 msgid "Profile data saved."
 msgstr "用户信息已更新. "
 
 #. Translators: format of event kind in Event model
-#: .\course\calendar.py:48 .\course\calendar.py:190 .\course\models.py:246
+#: .\course\calendar.py:50 .\course\calendar.py:192 .\course\models.py:254
 msgid "Should be lower_case_with_underscores, no spaces allowed."
 msgstr "只允许小写字母和下划线, 不允许有空格. "
 
-#: .\course\calendar.py:50 .\course\calendar.py:192
+#: .\course\calendar.py:52 .\course\calendar.py:194
 msgctxt "Kind of event"
 msgid "Kind of event"
 msgstr "event的类型(kind)"
 
-#: .\course\calendar.py:54
+#: .\course\calendar.py:56
 msgctxt "Starting time of event"
 msgid "Starting time"
 msgstr "开始时间"
 
-#: .\course\calendar.py:56
+#: .\course\calendar.py:58
 msgid "Duration in minutes"
 msgstr "时长(分钟)"
 
-#: .\course\calendar.py:59
+#: .\course\calendar.py:61
 msgid "Weekly"
 msgstr "以星期为单位"
 
-#: .\course\calendar.py:61
+#: .\course\calendar.py:63
 msgctxt "Interval of recurring events"
 msgid "Interval"
 msgstr "时间间隔"
 
-#: .\course\calendar.py:64 .\course\calendar.py:195
+#: .\course\calendar.py:66 .\course\calendar.py:197
 msgctxt "Starting ordinal of recurring events"
 msgid "Starting ordinal"
 msgstr "开始的序号"
 
-#: .\course\calendar.py:66
+#: .\course\calendar.py:68
 msgctxt "Count of recurring events"
 msgid "Count"
 msgstr "次数"
 
-#: .\course\calendar.py:72
+#: .\course\calendar.py:74
 msgid "Create"
 msgstr "创建"
 
-#: .\course\calendar.py:100
+#: .\course\calendar.py:102
 #, python-format
 msgid "'%(event_kind)s %(event_ordinal)d' already exists"
 msgstr "%(event_kind)s %(event_ordinal)d' 已经存在"
 
-#: .\course\calendar.py:115
+#: .\course\calendar.py:117
 msgctxt "Unkown time interval"
 msgid "unknown interval"
 msgstr "未知的时间间隔"
 
-#: .\course\calendar.py:128 .\course\calendar.py:211
+#: .\course\calendar.py:130 .\course\calendar.py:213
 msgid "only instructors and TAs may do that"
 msgstr "只有任课老师(instructor)和助教(TA)可以执行该操作"
 
-#: .\course\calendar.py:158 .\course\calendar.py:170
+#: .\course\calendar.py:160 .\course\calendar.py:172
 msgid "No events created."
 msgstr "未创建event. "
 
-#: .\course\calendar.py:176
+#: .\course\calendar.py:178
 msgid "Events created."
 msgstr "Event创建成功. "
 
-#: .\course\calendar.py:184 .\course\templates\course\course-base.html:105
+#: .\course\calendar.py:186 .\course\templates\course\course-base.html:105
 msgid "Create recurring events"
 msgstr "创建重复进行的event"
 
-#: .\course\calendar.py:201
+#: .\course\calendar.py:203
 msgid "Renumber"
 msgstr "重新编号"
 
-#: .\course\calendar.py:243
+#: .\course\calendar.py:245
 msgid "Events renumbered."
 msgstr "Event重新编号完成. "
 
-#: .\course\calendar.py:246
+#: .\course\calendar.py:248
 msgid "No events found."
 msgstr "未找到Event. "
 
-#: .\course\calendar.py:253 .\course\templates\course\course-base.html:106
+#: .\course\calendar.py:255 .\course\templates\course\course-base.html:106
 msgid "Renumber events"
 msgstr "重新编号"
 
@@ -524,7 +524,7 @@ msgctxt "Flow permission"
 msgid "Set the session to 'roll over' expiration mode"
 msgstr "将这个session设为“展期”的过期模式"
 
-#: .\course\constants.py:231
+#: .\course\constants.py:220
 msgctxt "Flow permission"
 msgid "See session time"
 msgstr "查看session时间"
@@ -609,17 +609,17 @@ msgctxt "Grade state change"
 msgid "Exempt"
 msgstr "剔除"
 
-#: .\course\constants.py:336
+#: .\course\constants.py:325
 msgctxt "Exam ticket state"
 msgid "Valid"
 msgstr "已通过有效性验证"
 
-#: .\course\constants.py:338
+#: .\course\constants.py:327
 msgctxt "Exam ticket state"
 msgid "Used"
 msgstr "已使用"
 
-#: .\course\constants.py:340
+#: .\course\constants.py:329
 msgctxt "Exam ticket state"
 msgid "Revoked"
 msgstr "已撤回"
@@ -708,7 +708,7 @@ msgstr "批准加入"
 msgid "Deny enrollment"
 msgstr "拒绝加入"
 
-#: .\course\enrollment.py:226 .\course\models.py:367
+#: .\course\enrollment.py:226 .\course\models.py:384
 #: .\course\templates\course\gradebook-participant-list.html:27
 msgid "Role"
 msgstr "在课程中的角色"
@@ -725,25 +725,25 @@ msgstr "Email"
 msgid "Preapprove"
 msgstr "预先批准"
 
-#: .\course\enrollment.py:244
+#: .\course\enrollment.py:243
 msgid "only instructors may do that"
 msgstr "只有任课老师才有执行该操作的权限"
 
-#: .\course\enrollment.py:282
+#: .\course\enrollment.py:281
 #, python-format
 msgid "%(n_created)d preapprovals created, %(n_exist)d already existed."
 msgstr "新加入了%(n_created)d个预批准, 有%(n_exist)d个是之前已经批准的. "
 
-#: .\course\enrollment.py:293
+#: .\course\enrollment.py:292
 msgid "Create Participation Preapprovals"
 msgstr "用户加入课程预批准"
 
-#: .\course\exam.py:88 .\course\views.py:499
+#: .\course\exam.py:88 .\course\views.py:498
 msgid "Select participant for whom exception is to be granted."
 msgstr "选择需要给予破例的用户. "
 
-#: .\course\exam.py:97 .\course\exam.py:180 .\course\models.py:1329
-#: .\course\models.py:1342
+#: .\course\exam.py:97 .\course\exam.py:179 .\course\models.py:1380
+#: .\course\models.py:1396
 msgid "Exam"
 msgstr "测验"
 
@@ -755,80 +755,81 @@ msgstr "撤回之前发给这个用户的测验ticket"
 msgid "Issue ticket"
 msgstr "发布ticket"
 
-#: .\course\exam.py:127
+#: .\course\exam.py:126
 msgid "User is not enrolled in course."
 msgstr "用户未参与本课程. "
 
-#: .\course\exam.py:148
+#: .\course\exam.py:147
 #, python-format
 msgid ""
 "Ticket issued for <b>%(participation)s</b>. The ticket code is <b>%"
 "(ticket_code)s</b>."
-msgstr "发给用户<b>%(participation)s</b>的ticket. 该ticket的代码是"
-"<b>%(ticket_code)s</b>."
+msgstr ""
+"发给用户<b>%(participation)s</b>的ticket. 该ticket的代码是<b>%(ticket_code)"
+"s</b>."
 
-#: .\course\exam.py:160
+#: .\course\exam.py:159
 msgid "Issue Exam Ticket"
 msgstr "发布测验ticket"
 
-#: .\course\exam.py:183
+#: .\course\exam.py:182
 msgid "List"
 msgstr "列表"
 
-#: .\course\exam.py:184
+#: .\course\exam.py:183
 msgid "Cards"
 msgstr ""
 
-#: .\course\exam.py:186
+#: .\course\exam.py:185
 msgid "Ticket Format"
 msgstr "ticket格式"
 
-#: .\course\exam.py:189
+#: .\course\exam.py:188
 msgid "Revoke prior exam tickets"
 msgstr "撤回之前的测验ticket"
 
-#: .\course\exam.py:196
+#: .\course\exam.py:195
 msgid "Issue tickets"
 msgstr "发布ticket"
 
-#: .\course\exam.py:207
+#: .\course\exam.py:205
 msgid "must be instructor or TA to batch-issue tickets"
 msgstr "只有任课老师(instructor)和助理(TA)可以批量发布ticket"
 
-#: .\course\exam.py:247
+#: .\course\exam.py:245
 #, python-format
 msgid "%d tickets issued."
 msgstr "%d个ticket已发布. "
 
-#: .\course\exam.py:257
+#: .\course\exam.py:255
 msgid "Batch-Issue Exam Tickets"
 msgstr "批量发布测验ticket"
 
-#: .\course\exam.py:298
+#: .\course\exam.py:296
 msgid "User name"
 msgstr "用户名"
 
-#: .\course\exam.py:301
+#: .\course\exam.py:299
 msgid "This is typically your full email address."
 msgstr "通常是你的完整电子邮件. "
 
-#: .\course\exam.py:302
+#: .\course\exam.py:300
 msgid "Code"
 msgstr "代码"
 
-#: .\course\exam.py:309
+#: .\course\exam.py:307
 msgid "Check in"
 msgstr "登入"
 
-#: .\course\exam.py:328
+#: .\course\exam.py:325
 msgid "Invalid check-in data."
 msgstr "无效的登入数据."
 
-#: .\course\exam.py:353
+#: .\course\exam.py:350
 msgid "Check in for Exam"
 msgstr "登入测验"
 
-#: .\course\exam.py:440
+#: .\course\exam.py:437
 msgid "Error while processing exam lockdown: ticket not found."
 msgstr "处理测验锁定时出错:未找到ticket. "
 
@@ -836,7 +837,7 @@ msgstr "处理测验锁定时出错:未找到ticket. "
 msgid "cannot grade ungraded answer"
 msgstr "无法为未评分的回答进行评分"
 
-#: .\course\flow.py:467 .\course\flow.py:1451
+#: .\course\flow.py:467 .\course\flow.py:1447
 msgid "Can't end a session that's already ended"
 msgstr "无法结束已经结束的session"
 
@@ -900,64 +901,64 @@ msgstr "无法识别的POST操作"
 msgid "may not view other people's sessions"
 msgstr "不允许查看其他人的session"
 
-#: .\course\flow.py:951
+#: .\course\flow.py:947
 msgid "Save answer"
 msgstr "保存回答"
 
-#: .\course\flow.py:958
+#: .\course\flow.py:954
 msgid "Submit answer for grading"
 msgstr "提交用于评分的回答"
 
-#: .\course\flow.py:962
+#: .\course\flow.py:958
 msgid "Submit final answer"
 msgstr "提交最终回答"
 
-#: .\course\flow.py:971
+#: .\course\flow.py:967
 msgid "Save answer and move on"
 msgstr "保存回答并继续"
 
-#: .\course\flow.py:979
+#: .\course\flow.py:975
 msgid "Save answer and finish"
 msgstr "保存回答并结束"
 
-#: .\course\flow.py:992
+#: .\course\flow.py:988
 msgid "could not find which button was pressed"
 msgstr "无法找到哪一个按钮被按下"
 
-#: .\course\flow.py:1016
+#: .\course\flow.py:1012
 msgid ""
 "No in-progress session record found for this flow. Redirected to flow start "
 "page."
 msgstr "本flow没有找到正在进行中的session, 跳转到flow的起始页面. "
 
-#: .\course\flow.py:1057
+#: .\course\flow.py:1053
 msgid "not allowed to view flow"
 msgstr "不允许查看该flow"
 
-#: .\course\flow.py:1069
+#: .\course\flow.py:1065
 msgid "Answer submission not allowed."
 msgstr "不允许提交回答. "
 
-#: .\course\flow.py:1078
+#: .\course\flow.py:1074
 msgid "Already have final answer."
 msgstr "已经有最终的回答. "
 
-#: .\course\flow.py:1100
+#: .\course\flow.py:1096
 msgid "Answer saved."
 msgstr "回答保存成功. "
 
-#: .\course\flow.py:1186
+#: .\course\flow.py:1182
 msgid "Failed to submit answer."
 msgstr "回答提交失败."
 
-#: .\course\flow.py:1260
+#: .\course\flow.py:1256
 msgid ""
 "Changes to this session are being prevented because this session yields a "
 "permanent grade, but you have not completed your enrollment process in this "
 "course."
 msgstr ""
 
-#: .\course\flow.py:1276
+#: .\course\flow.py:1272
 msgid ""
 "<p><b>WARNING!</b> What you enter on this page will not be associated with "
 "your user account, likely because you have not completed your enrollment in "
@@ -971,31 +972,31 @@ msgid ""
 "work.</b>"
 msgstr ""
 
-#: .\course\flow.py:1362
+#: .\course\flow.py:1358
 msgid "only POST allowed"
 msgstr "只允许POST操作"
 
-#: .\course\flow.py:1368
+#: .\course\flow.py:1364
 msgid "may only change your own flow sessions"
 msgstr "只允许更改您自己的flow session"
 
-#: .\course\flow.py:1371
+#: .\course\flow.py:1367
 msgid "may only change in-progress flow sessions"
 msgstr "只能更改正在进行中的session"
 
-#: .\course\flow.py:1376
+#: .\course\flow.py:1372
 msgid "invalid expiration mode"
 msgstr "无效的过期模式"
 
-#: .\course\flow.py:1447
+#: .\course\flow.py:1443
 msgid "odd POST parameters"
 msgstr "怪异的POST参数设置"
 
-#: .\course\flow.py:1455
+#: .\course\flow.py:1451
 msgid "not permitted to end session"
 msgstr "不允许结束session"
 
-#: .\course\flow.py:1523
+#: .\course\flow.py:1519
 msgid ""
 "If non-empty, limit the regrading to sessions started under this access "
 "rules tag."
@@ -1003,40 +1004,40 @@ msgstr ""
 "如果access rules的设置不为空, 则对该规则下开始的session进行重新评分受到该规则"
 "的限制. "
 
-#: .\course\flow.py:1525 .\course\models.py:439
+#: .\course\flow.py:1521 .\course\models.py:459
 msgid "Access rules tag"
 msgstr "访问规则tag"
 
-#: .\course\flow.py:1529
+#: .\course\flow.py:1525
 msgid "Regrade in-progress and not-in-progress sessions"
 msgstr "为进行中的和不在进行中的session重新评分"
 
-#: .\course\flow.py:1531
+#: .\course\flow.py:1527
 msgid "Regrade in-progress sessions only"
 msgstr "仅为进行中的session重新评分"
 
-#: .\course\flow.py:1533
+#: .\course\flow.py:1529
 msgid "Regrade not-in-progress sessions only"
 msgstr "仅为非进行中的session重新评分"
 
-#: .\course\flow.py:1535
+#: .\course\flow.py:1531
 msgid "Regraded session in progress"
 msgstr "为正在进行的session重新评分"
 
-#: .\course\flow.py:1538 .\course\templates\course\gradebook-single.html:257
+#: .\course\flow.py:1534 .\course\templates\course\gradebook-single.html:257
 msgid "Regrade"
 msgstr "重新评分"
 
-#: .\course\flow.py:1556
+#: .\course\flow.py:1552
 msgid "must be instructor to regrade flows"
 msgstr "只有任课老师(instructor)才能为flow重新评分"
 
-#: .\course\flow.py:1586
+#: .\course\flow.py:1582
 #, python-format
 msgid "%d sessions regraded."
 msgstr "%d个session已重新评分. "
 
-#: .\course\flow.py:1594
+#: .\course\flow.py:1590
 msgid ""
 "This regrading process is only intended for flows that donot show up in the "
 "grade book. If you would like to regradefor-credit flows, use the "
@@ -1045,103 +1046,103 @@ msgstr ""
 "这个重新评分的过程旨在针对不在“成绩册”中显示的的flow. 如果您想对计入成绩的"
 "flow重新评分, 请使用“成绩册”中的对应功能. "
 
-#: .\course\flow.py:1599
+#: .\course\flow.py:1595
 msgid "Regrade not-for-credit Flow Sessions"
 msgstr "为不计入成绩的flow session重新评分"
 
-#: .\course\grades.py:60
+#: .\course\grades.py:61
 msgid "must be enrolled to view grades"
 msgstr "必须加入课程才能查看成绩"
 
-#: .\course\grades.py:73 .\course\grades.py:802
+#: .\course\grades.py:74 .\course\grades.py:812
 msgid "may not view other people's grades"
 msgstr "不允许查看其他人的成绩"
 
-#: .\course\grades.py:151 .\course\grades.py:174 .\course\grades.py:271
-#: .\course\grades.py:468 .\course\grading.py:61
+#: .\course\grades.py:152 .\course\grades.py:175 .\course\grades.py:272
+#: .\course\grades.py:475 .\course\grading.py:61
 msgid "must be instructor or TA to view grades"
 msgstr "只有任课老师(instructor)或助教(TA)可以查看成绩"
 
-#: .\course\grades.py:293
+#: .\course\grades.py:296
 msgid "must be instructor or TA to export grades"
 msgstr "只有任课老师(instructor)或助教(TA)可以导出成绩"
 
-#: .\course\grades.py:342
+#: .\course\grades.py:350
 msgid "Session tag"
 msgstr ""
 
-#: .\course\grades.py:346
+#: .\course\grades.py:354
 msgid ""
 "Only act on in-progress sessions that are past their access rule's due date "
 "(applies to 'expire')"
 msgstr "只能对进行中且已经超过了截止日期的session执行该操作(针对'过期'选项)"
 
 #. Translators: see help text above.
-#: .\course\grades.py:349
+#: .\course\grades.py:357
 msgid "Past due only"
 msgstr "仅针对已过期的session"
 
-#: .\course\grades.py:352
+#: .\course\grades.py:360
 msgid "Impose deadline (Expire sessions)"
 msgstr "实施截止(使session过期)"
 
-#: .\course\grades.py:357
+#: .\course\grades.py:364
 msgid "Regrade ended sessions"
 msgstr "为已经结束的session重新评分"
 
-#: .\course\grades.py:359
+#: .\course\grades.py:366
 msgid "Recalculate grades of ended sessions"
 msgstr "重新计算已结束session的评分"
 
-#: .\course\grades.py:473
+#: .\course\grades.py:480
 msgid "opportunity from wrong course"
 msgstr "机会与课程不符"
 
-#: .\course\grades.py:499 .\course\views.py:380 .\course\views.py:407
-#: .\course\views.py:455
+#: .\course\grades.py:506 .\course\views.py:379 .\course\views.py:406
+#: .\course\views.py:454
 msgid "invalid operation"
 msgstr "无效操作"
 
-#: .\course\grades.py:515
+#: .\course\grades.py:522
 #, python-format
 msgid "%d session(s) expired."
 msgstr "%d个session已经过期. "
 
-#: .\course\grades.py:524
+#: .\course\grades.py:531
 #, python-format
 msgid "%d session(s) ended."
 msgstr "%d个session已结束. "
 
-#: .\course\grades.py:532
+#: .\course\grades.py:539
 #, python-format
 msgid "%d session(s) regraded."
 msgstr "%d个session已重新评分. "
 
-#: .\course\grades.py:540
+#: .\course\grades.py:547
 #, python-format
 msgid "Grade recalculated for %d session(s)."
 msgstr "%d个session已重新计算评分. "
 
-#: .\course\grades.py:549 .\course\grades.py:869 .\course\grades.py:1176
-#: .\course\versioning.py:454
+#: .\course\grades.py:556 .\course\grades.py:879 .\course\grades.py:1183
+#: .\course\versioning.py:450
 msgctxt "Starting of Error message"
 msgid "Error"
 msgstr "错误"
 
-#: .\course\grades.py:660 .\course\views.py:757
+#: .\course\grades.py:670 .\course\views.py:752
 msgid "Set access rules tag"
 msgstr "设置访问规则tag"
 
-#: .\course\grades.py:664 .\course\models.py:821 .\course\models.py:869
-#: .\course\models.py:1037 .\course\views.py:801
+#: .\course\grades.py:674 .\course\models.py:853 .\course\models.py:907
+#: .\course\models.py:1082 .\course\views.py:796
 msgid "Comment"
 msgstr "评论"
 
-#: .\course\grades.py:668 .\course\templates\course\gradebook-single.html:271
+#: .\course\grades.py:678 .\course\templates\course\gradebook-single.html:271
 msgid "Reopen"
 msgstr "重新打开"
 
-#: .\course\grades.py:705
+#: .\course\grades.py:715
 #, python-format
 msgid ""
 "Session reopened at %(now)s by %(user)s, previous completion time was '%"
@@ -1150,142 +1151,142 @@ msgstr ""
 "由%(user)s在%(now)s重新打开了本Session, 上一次结束的时间为%(completion_time)"
 "s: %(comment)s. "
 
-#: .\course\grades.py:729
+#: .\course\grades.py:739
 msgid "Reopen session"
 msgstr "重新打开session"
 
-#: .\course\grades.py:786
+#: .\course\grades.py:796
 msgid "participation does not match course"
 msgstr "参与和课程不符"
 
-#: .\course\grades.py:795
+#: .\course\grades.py:805
 msgid "This grade is not shown in the grade book."
 msgstr "该评分不会显示在成绩册中. "
 
-#: .\course\grades.py:798
+#: .\course\grades.py:808
 msgid "This grade is not shown in the student grade book."
 msgstr "该评分不会显示在学生的成绩册中. "
 
-#: .\course\grades.py:805
+#: .\course\grades.py:815
 msgid "grade has not been released"
 msgstr "评分还未发布"
 
-#: .\course\grades.py:825
+#: .\course\grades.py:835
 msgid "unknown action"
 msgstr "未知的操作"
 
-#: .\course\grades.py:841
+#: .\course\grades.py:851
 msgid "Session expired."
 msgstr "该session已经过期. "
 
-#: .\course\grades.py:848
+#: .\course\grades.py:858
 msgid "Session ended."
 msgstr "该session已结束. "
 
-#: .\course\grades.py:854
+#: .\course\grades.py:864
 msgid "Session regraded."
 msgstr "该session已重新评分. "
 
-#: .\course\grades.py:860
+#: .\course\grades.py:870
 msgid "Session grade recalculated."
 msgstr "该session评分已重新计算. "
 
-#: .\course\grades.py:863
+#: .\course\grades.py:873
 msgid "invalid session operation"
 msgstr "无效的session操作"
 
-#: .\course\grades.py:959
+#: .\course\grades.py:969
 #, python-format
 msgid ""
 "Click to <a href='%s' target='_blank'>create</a> a new grading opportunity. "
 "Reload this form when done."
 msgstr "点击 <a href='%s' target='_blank'>创建</a> 一个新的得分机会. "
 
-#: .\course\grades.py:963
+#: .\course\grades.py:973
 msgctxt "Field name in Import grades form"
 msgid "Grading opportunity"
 msgstr "得分机会"
 
-#: .\course\grades.py:968 .\course\models.py:1028
+#: .\course\grades.py:978 .\course\models.py:1073
 msgid "Attempt ID"
 msgstr ""
 
-#: .\course\grades.py:970
+#: .\course\grades.py:980
 msgid "File"
 msgstr "文件"
 
-#: .\course\grades.py:974
+#: .\course\grades.py:984
 msgid "CSV with Header"
 msgstr "带有表头的CSV文件"
 
-#: .\course\grades.py:977
+#: .\course\grades.py:987
 msgid "Format"
 msgstr "格式"
 
 #. Translators: the following strings are for the format
 #. informatioin for a CSV file to be imported.
-#: .\course\grades.py:982
+#: .\course\grades.py:992
 msgid ""
 "1-based column index for the Email or NetID used to locate student record"
 msgstr "学生电子邮件或用户ID所在列,从1起"
 
-#: .\course\grades.py:985
+#: .\course\grades.py:995
 msgid "User ID column"
 msgstr "用户ID列"
 
-#: .\course\grades.py:987
+#: .\course\grades.py:997
 msgid "1-based column index for the (numerical) grade"
 msgstr "学生的(数值)得分所在列,从1起"
 
-#: .\course\grades.py:989
+#: .\course\grades.py:999
 msgid "Points column"
 msgstr "分值列"
 
-#: .\course\grades.py:991
+#: .\course\grades.py:1001
 msgid "1-based column index for further (textual) feedback"
 msgstr "对学生作业的进一步(文字)反馈所在列,从1起"
 
-#: .\course\grades.py:993
+#: .\course\grades.py:1003
 msgid "Feedback column"
 msgstr "反馈所在列"
 
 #. Translators: "Max point" refers to full credit in points.
-#: .\course\grades.py:997 .\course\models.py:670 .\course\models.py:1034
+#: .\course\grades.py:1007 .\course\models.py:699 .\course\models.py:1079
 msgid "Max points"
 msgstr "满分分值"
 
-#: .\course\grades.py:1000 .\course\sandbox.py:70
+#: .\course\grades.py:1009 .\course\sandbox.py:70
 #: .\course\templates\course\grade-import-preview.html:14
-#: .\course\versioning.py:394
+#: .\course\versioning.py:390
 msgid "Preview"
 msgstr "预览"
 
-#: .\course\grades.py:1003
+#: .\course\grades.py:1010
 msgid "Import"
 msgstr "导入"
 
 #. Translators: use id_string to find user (participant).
-#: .\course\grades.py:1038
+#: .\course\grades.py:1045
 #, python-format
 msgid "no participant found for '%(id_string)s'"
 msgstr "用\"%(id_string)s\"找不到参与者"
 
-#: .\course\grades.py:1042
+#: .\course\grades.py:1049
 #, python-format
 msgid "more than one participant found for '%(id_string)s'"
 msgstr "用\"%(id_string)s\"找到超过1个参与者"
 
-#: .\course\grades.py:1184
+#: .\course\grades.py:1191
 #, python-format
 msgid "%(total)d grades found, %(unchaged)d unchanged."
 msgstr "找到%(total)d个评分, %(unchaged)d个未更改. "
 
-#: .\course\grades.py:1198
+#: .\course\grades.py:1205
 #, python-format
 msgid "%d grades imported."
 msgstr "%d个评分导入成功. "
 
-#: .\course\grades.py:1211
+#: .\course\grades.py:1218
 msgid "Import Grade Data"
 msgstr "导入成绩数据"
 
@@ -1317,47 +1318,47 @@ msgctxt "Send instant messages"
 msgid "Send"
 msgstr "发送"
 
-#: .\course\im.py:142
+#: .\course\im.py:141
 msgid "unable to connect"
 msgstr "无法连接"
 
-#: .\course\im.py:160
+#: .\course\im.py:159
 msgid "only enrolled folks may do that"
 msgstr "只有加入课程的用户才允许进行"
 
-#: .\course\im.py:167
+#: .\course\im.py:166
 msgid "Instant messaging is not enabled for this course."
 msgstr "本课程未设置即时通信功能. "
 
-#: .\course\im.py:173
+#: .\course\im.py:172
 msgid "Recipient is <span class='label label-success'>Online</span>."
 msgstr "接收者为<span class='label label-success'>在线状态</span>. "
 
-#: .\course\im.py:176
+#: .\course\im.py:175
 msgid "Recipient is <span class='label label-danger'>Offline</span>."
 msgstr "接收者为<span class='label label-danger'>离线状态</span>. "
 
-#: .\course\im.py:190
+#: .\course\im.py:189
 msgid "no recipient XMPP ID"
 msgstr "无接收者XMPP ID"
 
-#: .\course\im.py:193
+#: .\course\im.py:192
 msgid "no XMPP password"
 msgstr "无XMPP密码"
 
-#: .\course\im.py:205
+#: .\course\im.py:204
 msgid "An error occurred while sending the message. Sorry."
 msgstr "对不起, 发送信息时出现了错误. "
 
-#: .\course\im.py:209
+#: .\course\im.py:208
 msgid "Message sent."
 msgstr "信息已发送. "
 
-#: .\course\im.py:218 .\course\templates\course\course-base.html:35
+#: .\course\im.py:217 .\course\templates\course\course-base.html:35
 msgid "Send instant message"
 msgstr "发送即时信息"
 
-#: .\course\models.py:73 .\course\models.py:315
+#: .\course\models.py:75 .\course\models.py:329
 #: .\course\templates\course\gradebook-by-opp.html:97
 #: .\course\templates\course\gradebook-participant-list.html:24
 #: .\course\templates\course\gradebook-participant.html:31
@@ -1365,47 +1366,47 @@ msgstr "发送即时信息"
 msgid "User ID"
 msgstr "用户ID"
 
-#: .\course\models.py:76 .\course\models.py:99
+#: .\course\models.py:78 .\course\models.py:101
 msgid "User status"
 msgstr "用户状态"
 
-#: .\course\models.py:78
+#: .\course\models.py:80
 msgid "The sign in token sent out in email."
 msgstr "用户登录网站的token(用邮件发送)."
 
 #. Translators: the sign in token of the user.
-#: .\course\models.py:81
+#: .\course\models.py:83
 msgid "Sign in key"
 msgstr "登录key"
 
-#: .\course\models.py:83
+#: .\course\models.py:85
 msgid "The time stamp of the sign in token."
 msgstr "用户登录网站token的时间戳."
 
 #. Translators: the time when the token is sent out.
-#: .\course\models.py:85
+#: .\course\models.py:87
 msgid "Key time"
 msgstr "登录key的时间"
 
-#: .\course\models.py:89
+#: .\course\models.py:91
 msgid "Default"
 msgstr "默认"
 
 #. Translators: the text editor used by participants
-#: .\course\models.py:96
+#: .\course\models.py:98
 msgid "Editor mode"
 msgstr "编辑器模式"
 
-#: .\course\models.py:100
+#: .\course\models.py:102
 msgid "User statuses"
 msgstr "用户状态"
 
-#: .\course\models.py:104
+#: .\course\models.py:106
 #, python-format
 msgid "User status for %(user)s"
 msgstr "%(user)s的用户状态"
 
-#: .\course\models.py:113
+#: .\course\models.py:118
 msgid ""
 "A course identifier. Alphanumeric with dashes, no spaces. This is visible in "
 "URLs and determines the location on your file system where the course's git "
@@ -1414,43 +1415,43 @@ msgstr ""
 "课程的ID, 只允许字母、数字、减号, 不能有空格. 它将显示在您的链接中, 并确定该"
 "课程的git仓库放在您的系统中的哪个文件夹下. "
 
-#: .\course\models.py:116
+#: .\course\models.py:121
 msgid "Course identifier"
 msgstr "课程ID"
 
-#: .\course\models.py:122
+#: .\course\models.py:127
 msgid "Identifier may only contain letters, numbers, and hypens ('-')."
 msgstr "Identifier只能包含英文字母, 数字, 和中划线(即减号\"-\"). "
 
-#: .\course\models.py:129
+#: .\course\models.py:134
 msgid "Is the course only accessible to course staff?"
 msgstr "本课程是否只有管理人员才能访问?"
 
-#: .\course\models.py:130
+#: .\course\models.py:135
 msgid "Only visible to course staff"
 msgstr "本课程是否只对课程管理人员显示?"
 
-#: .\course\models.py:133
+#: .\course\models.py:138
 msgid "Should the course be listed on the main page?"
 msgstr "该课程是否放在主页上?"
 
-#: .\course\models.py:134
+#: .\course\models.py:139
 msgid "Listed on main page"
 msgstr "在主页上显示"
 
-#: .\course\models.py:137
+#: .\course\models.py:142
 msgid "Accepts enrollment"
 msgstr "允许申请加入课程"
 
-#: .\course\models.py:140
+#: .\course\models.py:145
 msgid "Whether the course content has passed validation."
 msgstr "课程内容是否已通过有效性验证. "
 
-#: .\course\models.py:141
+#: .\course\models.py:146
 msgid "Valid"
 msgstr "通过有效性验证"
 
-#: .\course\models.py:144
+#: .\course\models.py:149
 msgid ""
 "A Git URL from which to pull course updates. If you're just starting out, "
 "enter <tt>git://github.com/inducer/relate-sample</tt> to get some sample "
@@ -1459,11 +1460,11 @@ msgstr ""
 "一个git网址, 课程的内容更新将从它pull取得. 如果您刚刚开始使用, 可输入"
 "<tt>git://github.com/inducer/relate-sample</tt>来取得一些示范内容. "
 
-#: .\course\models.py:148
+#: .\course\models.py:153
 msgid "git source"
 msgstr "Git源地址"
 
-#: .\course\models.py:150
+#: .\course\models.py:155
 msgid ""
 "An SSH private key to use for Git authentication. Not needed for the sample "
 "URL above.You may use <a href='/generate-ssh-key'>this tool</a> to generate "
@@ -1473,78 +1474,78 @@ msgstr ""
 "课程不需设置. 你可以使用<a href='/generate-ssh-key'>这个工具</a>来生成一对密"
 "钥. "
 
-#: .\course\models.py:154
+#: .\course\models.py:159
 msgid "SSH private key"
 msgstr "SSH私有密钥"
 
-#: .\course\models.py:157
+#: .\course\models.py:162
 msgid ""
 "Subdirectory in git repository to use as course root directory. Should not "
 "include trailing slash."
 msgstr "一个在git仓库目录下的目录,作为课程的根目录. 不要包含斜杠."
 
-#: .\course\models.py:160
+#: .\course\models.py:165
 msgid "Course root directory"
 msgstr "课程根目录"
 
-#: .\course\models.py:164
+#: .\course\models.py:169
 msgid ""
 "Name of a YAML file in the git repository that contains the root course "
 "descriptor."
-msgstr "git仓库中包含了课程内容描述的YAML文件的文件名, 通常为course.xml. "
+msgstr "git仓库中包含了课程内容描述的YAML文件的文件名, 默认为course.yml. "
 
-#: .\course\models.py:166
+#: .\course\models.py:171
 msgid "Course file"
 msgstr "课程主页文件"
 
-#: .\course\models.py:169
+#: .\course\models.py:174
 msgid ""
 "Name of a YAML file in the git repository that contains calendar information."
-msgstr "git仓库中包含了课程教学日历信息的YAML文件的文件名, 通常为event.xml. "
+msgstr "git仓库中包含了课程教学日历信息的YAML文件的文件名, 默认为events.yml. "
 
-#: .\course\models.py:171
+#: .\course\models.py:176 .\course\validation.py:886
 msgid "Events file"
-msgstr "event(事件)文件"
+msgstr "events(事件)文件"
 
-#: .\course\models.py:175
+#: .\course\models.py:180
 msgid "If set, each enrolling student must be individually approved."
 msgstr "如果选择该项, 每个加入课程的请求必须单独批准. "
 
-#: .\course\models.py:177
+#: .\course\models.py:182
 msgid "Enrollment approval required"
 msgstr "申请加入课程必须得到批准"
 
-#: .\course\models.py:180
+#: .\course\models.py:185
 msgid ""
 "Enrollee's email addresses must end in the specified suffix, such as "
 "'@illinois.edu'."
 msgstr "申请加入课程的电子邮件必须使用特定的后缀, 比如\"@qq.com\". "
 
-#: .\course\models.py:182
+#: .\course\models.py:187
 msgid "Enrollment required email suffix"
 msgstr "申请加入课程的电子邮件地址必须有的后缀"
 
 #. Translators: replace "RELATE" with the brand name of your
 #. website if necessary.
-#: .\course\models.py:187
+#: .\course\models.py:192
 msgid ""
 "This email address will be used in the 'From' line of automated emails sent "
 "by RELATE."
 msgstr "这个电子邮件地址用于RELATE自动发送电子邮件时的发件人. "
 
-#: .\course\models.py:189
+#: .\course\models.py:194
 msgid "From email"
 msgstr "发送邮件的邮箱"
 
-#: .\course\models.py:192
+#: .\course\models.py:197
 msgid "This email address will receive notifications about the course."
 msgstr "这个电子邮件地址用于接收关于本课程的事务通知. "
 
-#: .\course\models.py:194
+#: .\course\models.py:199
 msgid "Notify email"
 msgstr "接收通知的邮箱"
 
-#: .\course\models.py:199
+#: .\course\models.py:204
 msgid ""
 "(Required only if the instant message feature is desired.) The Jabber/XMPP "
 "ID (JID) the course will use to sign in to an XMPP server."
@@ -1552,106 +1553,106 @@ msgstr ""
 "本课程将使用的Jabber/XMPP ID (JID), 用于登录某个XMPP服务器(仅在需要使用即时通"
 "信功能时才需填写). "
 
-#: .\course\models.py:202
+#: .\course\models.py:207
 msgid "Course xmpp ID"
 msgstr "课程的xmpp ID"
 
-#: .\course\models.py:204
+#: .\course\models.py:209
 msgid ""
 "(Required only if the instant message feature is desired.) The password to "
 "go with the JID above."
 msgstr "以上设置的JID的密码(仅在需要使用即时通信功能时才需填写). "
 
-#: .\course\models.py:206
+#: .\course\models.py:211
 msgid "Course xmpp password"
 msgstr "课程的XMPP密码"
 
-#: .\course\models.py:209
+#: .\course\models.py:214
 msgid ""
 "(Required only if the instant message feature is desired.) The JID to which "
 "instant messages will be sent."
 msgstr "接收即时信息的JID(仅在需要使用即时通信功能时才需填写). "
 
-#: .\course\models.py:211
+#: .\course\models.py:216
 msgid "Recipient xmpp ID"
 msgstr "接收者的xmpp ID"
 
-#: .\course\models.py:217 .\course\models.py:425
+#: .\course\models.py:222 .\course\models.py:445
 msgid "Active git commit SHA"
 msgstr "已启用的git commit SHA"
 
-#: .\course\models.py:224
+#: .\course\models.py:229
 msgid "Courses"
 msgstr "课程"
 
-#: .\course\models.py:248
+#: .\course\models.py:256
 msgid "Kind of event"
 msgstr "event的类型(kind)"
 
 #. Translators: ordinal of event of the same kind
-#: .\course\models.py:251
+#: .\course\models.py:259
 msgid "Ordinal of event"
 msgstr "event的序号(ordinal)"
 
-#: .\course\models.py:253 .\course\models.py:395 .\course\models.py:429
+#: .\course\models.py:261 .\course\models.py:415 .\course\models.py:449
 #: .\course\templates\course\flow-start.html:23
 msgid "Start time"
 msgstr "开始时间"
 
-#: .\course\models.py:255 .\course\models.py:397
+#: .\course\models.py:263 .\course\models.py:417
 msgid "End time"
 msgstr "结束时间"
 
 #. Translators: for when the due time is "All day", how the webpage
 #. of a event is displayed.
-#: .\course\models.py:259
+#: .\course\models.py:267
 msgid ""
 "Only affects the rendering in the class calendar, in that a start time is "
 "not shown"
 msgstr "只会影响课程日历页面的渲染, 其效果为开始时间(start time)不显示. "
 
-#: .\course\models.py:261
+#: .\course\models.py:269
 msgid "All day"
 msgstr "全天"
 
-#: .\course\models.py:264
+#: .\course\models.py:272
 msgid "Shown in calendar"
 msgstr "在日历中显示"
 
-#: .\course\models.py:267
+#: .\course\models.py:275
 msgid "Event"
 msgstr "事件(event)"
 
-#: .\course\models.py:268
+#: .\course\models.py:276
 msgid "Events"
 msgstr "事件(event)"
 
 #. Translators: name format of ParticipationTag
-#: .\course\models.py:288
+#: .\course\models.py:299
 msgid "Format is lower-case-with-hyphens. Do not use spaces."
 msgstr "格式:只允许小写字母与减号, 不允许有空格."
 
-#: .\course\models.py:290
+#: .\course\models.py:301
 msgid "Name of participation tag"
 msgstr "课程参与tag的名称"
 
-#: .\course\models.py:301
+#: .\course\models.py:312
 msgid "Name contains invalid characters."
 msgstr "名称包含无效字符. "
 
-#: .\course\models.py:307
+#: .\course\models.py:321
 msgid "Participation tag"
 msgstr "课程参与标签"
 
-#: .\course\models.py:308
+#: .\course\models.py:322
 msgid "Participation tags"
 msgstr "课程参与标签"
 
-#: .\course\models.py:320
+#: .\course\models.py:334
 msgid "Enroll time"
 msgstr "加入课程时间"
 
-#: .\course\models.py:323
+#: .\course\models.py:337
 msgid ""
 "Instructors may update course content. Teaching assistants may access and "
 "change grade data. Observers may access analytics. Each role includes "
@@ -1661,149 +1662,149 @@ msgstr ""
 "(observer)可以访问评分分析内容. 以上三者, 排在前面的角色拥有排在后面的角色的"
 "权限. "
 
-#: .\course\models.py:327
+#: .\course\models.py:341
 msgid "Participation role"
 msgstr "参与该课程的角色"
 
-#: .\course\models.py:330
+#: .\course\models.py:344
 msgid "Participation status"
 msgstr "课程参与状态"
 
-#: .\course\models.py:377
+#: .\course\models.py:349
 msgid "Multiplier for time available on time-limited flows"
 msgstr "对于有时限的flow,其可用时间的乘数."
 
-#: .\course\models.py:337
+#: .\course\models.py:351
 msgid "Time factor"
 msgstr "时间乘数"
 
-#: .\course\models.py:341
+#: .\course\models.py:355
 msgid "Preview git commit SHA"
 msgstr "预览的git commit SHA"
 
-#: .\course\models.py:344
+#: .\course\models.py:358
 msgid "Tags"
 msgstr "标签"
 
 #. Translators: displayed format of Participation: some user in some
 #. course as some role
-#: .\course\models.py:349
+#: .\course\models.py:363
 #, python-format
 msgid "%(user)s in %(course)s as %(role)s"
 msgstr "%(user)s在课程%(course)s中(作为%(role)s)"
 
-#: .\course\models.py:354 .\course\models.py:416 .\course\models.py:789
-#: .\course\models.py:859 .\course\models.py:1015 .\course\models.py:1285
-#: .\course\models.py:1345 .\course\templates\course\course-base.html:116
+#: .\course\models.py:371 .\course\models.py:436 .\course\models.py:821
+#: .\course\models.py:897 .\course\models.py:1060 .\course\models.py:1333
+#: .\course\models.py:1399 .\course\templates\course\course-base.html:116
 msgid "Participation"
 msgstr "课程参与"
 
-#: .\course\models.py:355
+#: .\course\models.py:372
 msgid "Participations"
 msgstr "课程参与"
 
-#: .\course\models.py:370 .\course\models.py:807 .\course\models.py:864
-#: .\course\models.py:1043 .\course\models.py:1348
+#: .\course\models.py:387 .\course\models.py:839 .\course\models.py:902
+#: .\course\models.py:1088 .\course\models.py:1402
 msgid "Creator"
 msgstr "创建者"
 
-#: .\course\models.py:372 .\course\models.py:809 .\course\models.py:866
-#: .\course\models.py:977 .\course\models.py:1350
+#: .\course\models.py:389 .\course\models.py:841 .\course\models.py:904
+#: .\course\models.py:1018 .\course\models.py:1404
 msgid "Creation time"
 msgstr "创建时间"
 
 #. Translators: somebody's email in some course in Participation
 #. Preapproval
-#: .\course\models.py:377
+#: .\course\models.py:394
 #, python-format
 msgid "%(email)s in %(course)s"
 msgstr "%(email)s在课程%(course)s中"
 
-#: .\course\models.py:381
+#: .\course\models.py:401
 msgid "Participation preapproval"
 msgstr "用户加入课程预批准"
 
-#: .\course\models.py:382
+#: .\course\models.py:402
 msgid "Participation preapprovals"
 msgstr "用户加入课程预批准"
 
-#: .\course\models.py:399
+#: .\course\models.py:419
 msgid "Cancelled"
 msgstr "已取消的"
 
-#: .\course\models.py:402
+#: .\course\models.py:422
 msgid "Instant flow request"
 msgstr "即时flow"
 
-#: .\course\models.py:403 .\course\templates\course\course-base.html:120
+#: .\course\models.py:423 .\course\templates\course\course-base.html:120
 msgid "Instant flow requests"
 msgstr "即时flow"
 
-#: .\course\models.py:431
+#: .\course\models.py:451
 msgid "Completition time"
 msgstr "完成时间"
 
-#: .\course\models.py:433
+#: .\course\models.py:453
 msgid "Page count"
 msgstr "page数"
 
-#: .\course\models.py:436
+#: .\course\models.py:456
 msgid "In progress"
 msgstr "进行中的"
 
-#: .\course\models.py:443 .\course\templates\course\gradebook-single.html:168
+#: .\course\models.py:463 .\course\templates\course\gradebook-single.html:168
 msgid "Expiration mode"
 msgstr "过期模式"
 
-#: .\course\models.py:452 .\course\models.py:1032
+#: .\course\models.py:472 .\course\models.py:1077
 #: .\course\templates\course\gradebook-single.html:227
 msgid "Points"
 msgstr "分值"
 
-#: .\course\models.py:455
+#: .\course\models.py:475
 msgid "Max point"
 msgstr "满分"
 
-#: .\course\models.py:457
+#: .\course\models.py:477
 msgid "Result comment"
 msgstr "结果评论"
 
-#: .\course\models.py:460 .\course\models.py:520 .\course\models.py:564
-#: .\course\models.py:1049 .\course\templates\course\grade-flow-page.html:58
+#: .\course\models.py:480 .\course\models.py:543 .\course\models.py:590
+#: .\course\models.py:1094 .\course\templates\course\grade-flow-page.html:58
 msgid "Flow session"
 msgstr ""
 
-#: .\course\models.py:461 .\course\templates\course\gradebook-single.html:133
+#: .\course\models.py:481 .\course\templates\course\gradebook-single.html:133
 msgid "Flow sessions"
 msgstr ""
 
-#: .\course\models.py:466
+#: .\course\models.py:486
 #, python-format
 msgid "anonymous session %(session_id)d on '%(flow_id)s'"
 msgstr "flow \"%(flow_id)s\"中匿名的session %(session_id)d "
 
-#: .\course\models.py:470
+#: .\course\models.py:490
 #, python-format
 msgid "%(user)s's session %(session_id)d on '%(flow_id)s'"
 msgstr "%(user)s在flow \"%(flow_id)s\"的session %(session_id)d"
 
-#: .\course\models.py:522
+#: .\course\models.py:545
 msgid "Ordinal"
 msgstr "序号"
 
-#: .\course\models.py:525
+#: .\course\models.py:548
 msgid "Group ID"
 msgstr ""
 
-#: .\course\models.py:532
+#: .\course\models.py:555
 msgid "Data"
 msgstr "数据"
 
-#: .\course\models.py:535 .\course\models.py:536
+#: .\course\models.py:558 .\course\models.py:559
 msgid "Flow page data"
 msgstr "flow page的数据"
 
-#: .\course\models.py:540
+#: .\course\models.py:563
 #, python-format
 msgid ""
 "Data for page '%(group_id)s/%(page_id)s' (ordinal %(ordinal)s) in %"
@@ -1811,19 +1812,19 @@ msgid ""
 msgstr ""
 "%(flow_session)s中page %(group_id)s/%(page_id)s(序号为%(ordinal)s)的数据"
 
-#: .\course\models.py:567 .\course\models.py:720
+#: .\course\models.py:593 .\course\models.py:752
 msgid "Page data"
 msgstr "page数据"
 
-#: .\course\models.py:569
+#: .\course\models.py:595
 msgid "Visit time"
 msgstr "访问时间"
 
-#: .\course\models.py:571
+#: .\course\models.py:597
 msgid "Remote address"
 msgstr "来访的ip地址"
 
-#: .\course\models.py:574
+#: .\course\models.py:600
 msgid ""
 "Synthetic flow page visits are generated for unvisited pages once a flow is "
 "finished. This is needed since grade information is attached to a visit, and "
@@ -1832,277 +1833,277 @@ msgstr ""
 "如果一个flow结束,则对未访问的page生成\"合成\"的flow page访问。这是因为评分信"
 "息是附在访问中的,它需要有一个去处。"
 
-#: .\course\models.py:578
+#: .\course\models.py:604
 msgid "Is synthetic"
 msgstr "是否合成"
 
 #. Translators: "Answer" is a Noun.
-#: .\course\models.py:584 .\course\page\code.py:59 .\course\page\text.py:98
+#: .\course\models.py:610 .\course\page\code.py:60 .\course\page\text.py:98
 msgid "Answer"
 msgstr "回答"
 
 #. Translators: determine whether the answer is a final,
 #. submitted answer fit for grading.
-#: .\course\models.py:597
+#: .\course\models.py:623
 msgid "Is submitted answer"
 msgstr "是否为用于评分的回答"
 
 #. Translators: flow page visit
-#: .\course\models.py:602
+#: .\course\models.py:628
 #, python-format
 msgid "'%(group_id)s/%(page_id)s' in '%(session)s' on %(time)s"
 msgstr "在%(time)s时, \"%(session)s'中的'%(group_id)s/%(page_id)s\""
 
 #. Translators: flow page visit: if an answer is
 #. provided by user then append the string.
-#: .\course\models.py:612
+#: .\course\models.py:638
 msgid " (with answer)"
 msgstr "(和回答)"
 
-#: .\course\models.py:617
+#: .\course\models.py:646
 msgid "Flow page visit"
 msgstr "flow page访问"
 
-#: .\course\models.py:618
+#: .\course\models.py:647
 msgid "Flow page visits"
 msgstr "flow page访问"
 
-#: .\course\models.py:645
+#: .\course\models.py:674
 msgid "Visit"
 msgstr "访问"
 
-#: .\course\models.py:649 .\course\templates\course\gradebook-single.html:228
+#: .\course\models.py:678 .\course\templates\course\gradebook-single.html:228
 msgid "Grader"
 msgstr "评分者"
 
-#: .\course\models.py:651 .\course\models.py:1045
+#: .\course\models.py:680 .\course\models.py:1090
 msgid "Grade time"
 msgstr "评分时间"
 
-#: .\course\models.py:655
+#: .\course\models.py:684
 msgid "Graded at git commit SHA"
 msgstr "评分,于git commit SHA"
 
-#: .\course\models.py:660
+#: .\course\models.py:689
 msgid "Grade data"
 msgstr "评分数据"
 
 #. Translators: max point in grade
-#: .\course\models.py:668
+#: .\course\models.py:697
 msgid "Point value of this question when receiving full credit."
 msgstr "该问题取得满分时取得的分值. "
 
 #. Translators: correctness in grade
-#: .\course\models.py:673
+#: .\course\models.py:702
 msgid ""
 "Real number between zero and one (inclusively) indicating the degree of "
 "correctness of the answer."
 msgstr "属于范围[0,1]的数值, 用于表示回答的正确性. "
 
-#: .\course\models.py:675
+#: .\course\models.py:704
 msgid "Correctness"
 msgstr "正确性"
 
 #. Translators: "Feedback" stands for the feedback of answers.
-#: .\course\models.py:686
+#: .\course\models.py:715
 #: .\course\templates\course\grade-import-preview.html:20
 msgid "Feedback"
 msgstr "反馈"
 
-#: .\course\models.py:701
+#: .\course\models.py:730
 msgid "Flow page visit grade"
 msgstr "flow page 访问的得分"
 
-#: .\course\models.py:702
+#: .\course\models.py:731
 msgid "Flow page visit grades"
 msgstr "flow page 访问的得分"
 
 #. Translators: return the information of the grade of a user
 #. by percentage.
-#: .\course\models.py:712
+#: .\course\models.py:741
 #, python-format
 msgid "grade of %(visit)s: %(percentage)s"
 msgstr "%(visit)s的得分(百分比): %(percentage)s"
 
-#: .\course\models.py:722
+#: .\course\models.py:754
 #: .\course\templates\course\grade-import-preview.html:19
 #: .\course\templates\course\gradebook-participant.html:51
 #: .\course\templates\course\gradebook-single.html:74
 msgid "Grade"
 msgstr "得分"
 
-#: .\course\models.py:727
+#: .\course\models.py:759
 msgid "Bulk feedback"
 msgstr "批量反馈"
 
-#: .\course\models.py:763
+#: .\course\models.py:795
 msgid "stipulations must be a dictionary"
 msgstr "规定必须为一个字典型数据,即:(项目, 项目的值)"
 
-#: .\course\models.py:768
+#: .\course\models.py:800
 msgid "unrecognized keys in stipulations"
 msgstr "无法识别的规定"
 
-#: .\course\models.py:774
+#: .\course\models.py:806
 msgid "credit_percent must be a float"
 msgstr "credit_percent必须是一个浮点数"
 
-#: .\course\models.py:780
+#: .\course\models.py:812
 msgid "'allowed_session_count' must be a non-negative integer"
 msgstr "allowed_session_count必须是一个非负的整数"
 
-#: .\course\models.py:793 .\course\models.py:861
+#: .\course\models.py:825 .\course\models.py:899
 msgid "Expiration"
 msgstr "过期"
 
 #. Translators: help text for stipulations in FlowAccessException
 #. (deprecated)
-#: .\course\models.py:798
+#: .\course\models.py:830
 msgid ""
 "A dictionary of the same things that can be added to a flow access rule, "
 "such as allowed_session_count or credit_percent. If not specified here, "
 "values will default to the stipulations in the course content."
 msgstr ""
 
-#: .\course\models.py:804
+#: .\course\models.py:836
 msgid "Stipulations"
 msgstr "条款"
 
 #. Translators: deprecated
-#: .\course\models.py:814
+#: .\course\models.py:846
 msgid ""
 "Check if a flow started under this exception rule set should stay under this "
 "rule set until it is expired."
 msgstr ""
 
 #. Translators: deprecated
-#: .\course\models.py:818
+#: .\course\models.py:850
 msgid "Is sticky"
 msgstr ""
 
 #. Translators: flow access exception in admin (deprecated)
-#: .\course\models.py:826
+#: .\course\models.py:858
 #, python-format
 msgid "Access exception for '%(user)s' to '%(flow_id)s' in '%(course)s'"
 msgstr "对用户\"%(user)s'破例访问课程'%(course)s'中的'%(flow_id)s\". "
 
-#: .\course\models.py:840
+#: .\course\models.py:875
 msgid "Exception"
 msgstr "破例处理"
 
-#: .\course\models.py:843
+#: .\course\models.py:878
 msgid "Permission"
 msgstr "权限"
 
 #. Translators: FlowAccessExceptionEntry (deprecated)
-#: .\course\models.py:847
+#: .\course\models.py:882
 msgid "Flow access exception entries"
 msgstr "破例访问flow的条目"
 
-#: .\course\models.py:873
+#: .\course\models.py:911
 msgid "Kind"
 msgstr "类型"
 
-#: .\course\models.py:875
+#: .\course\models.py:913
 msgid "Rule"
 msgstr "规则"
 
-#: .\course\models.py:878
+#: .\course\models.py:916
 msgctxt "Is the flow rule exception activated?"
 msgid "Active"
 msgstr "生效"
 
 #. Translators: For FlowRuleException
-#: .\course\models.py:883
+#: .\course\models.py:921
 #, python-format
 msgid "%(kind)s exception for '%(user)s' to '%(flow_id)s'in '%(course)s'"
 msgstr "在课程%(course)s的%(flow_id)s中, 给予%(user)s破例的类型%(kind)s"
 
-#: .\course\models.py:896
+#: .\course\models.py:937
 msgid "grading rules may not expire"
 msgstr "评分规则不会过期"
 
-#: .\course\models.py:935
+#: .\course\models.py:976
 msgid "invalid rule kind: "
 msgstr "无效的规则类型:"
 
-#: .\course\models.py:939
+#: .\course\models.py:980
 msgid "invalid existing_session_rules: "
 msgstr "无效的existing_session_rules:"
 
-#: .\course\models.py:942
+#: .\course\models.py:983
 msgid "Flow rule exception"
 msgstr "flow rule破例"
 
-#: .\course\models.py:943
+#: .\course\models.py:984
 msgid "Flow rule exceptions"
 msgstr "flow rule破例"
 
 #. Translators: format of identifier for GradingOpportunity
-#: .\course\models.py:956
+#: .\course\models.py:997
 msgid "A symbolic name for this grade. lower_case_with_underscores, no spaces."
 msgstr "这个评分的字符化名称, 只允许小写字母和下划线, 不允许有空格. "
 
-#: .\course\models.py:958
+#: .\course\models.py:999
 msgid "Grading opportunity ID"
 msgstr "得分机会ID"
 
 #. Translators: name for GradingOpportunity
-#: .\course\models.py:961
+#: .\course\models.py:1002
 msgid "A human-readable identifier for the grade."
 msgstr "一个易于理解的标识, 用于评分. "
 
-#: .\course\models.py:962
+#: .\course\models.py:1003
 msgid "Grading opportunity name"
 msgstr "得分机会的名称"
 
-#: .\course\models.py:964
+#: .\course\models.py:1005
 msgid "Flow identifier that this grading opportunity is linked to, if any"
 msgstr "这个评分机会所属的Flow ID, 如果有评分机会的话"
 
 #. Translators: strategy on how the grading of mutiple sessioins
 #. are aggregated.
-#: .\course\models.py:972 .\course\templates\course\gradebook-by-opp.html:36
+#: .\course\models.py:1013 .\course\templates\course\gradebook-by-opp.html:36
 #: .\course\templates\course\gradebook-opp-list.html:27
 #: .\course\templates\course\gradebook-single.html:121
 msgid "Aggregation strategy"
 msgstr "多session评分累积策略"
 
-#: .\course\models.py:975 .\course\models.py:1040
-#: .\course\templates\course\gradebook-opp-list.html:28 .\course\views.py:790
+#: .\course\models.py:1016 .\course\models.py:1085
+#: .\course\templates\course\gradebook-opp-list.html:28 .\course\views.py:785
 msgid "Due time"
 msgstr "截止时间"
 
-#: .\course\models.py:980
+#: .\course\models.py:1021
 msgid "Shown in grade book"
 msgstr "在成绩册中显示"
 
-#: .\course\models.py:982
+#: .\course\models.py:1023
 msgid "Shown in student grade book"
 msgstr "在在学生的成绩册中显示"
 
-#: .\course\models.py:985 .\course\models.py:1012
+#: .\course\models.py:1026 .\course\models.py:1057
 msgid "Grading opportunity"
 msgstr "得分机会"
 
-#: .\course\models.py:986
+#: .\course\models.py:1027
 msgid "Grading opportunities"
 msgstr "得分机会"
 
 #. Translators: For GradingOpportunity
-#: .\course\models.py:993
+#: .\course\models.py:1034
 #, python-format
 msgid "%(opportunity_name)s (%(opportunity_id)s) in %(course)s"
 msgstr "课程%(course)s中的评分机会%(opportunity_name)s (%(opportunity_id)s) "
 
 #. Translators: something like 'status'.
-#: .\course\models.py:1020 .\course\templates\course\flow-start.html:24
+#: .\course\models.py:1065 .\course\templates\course\flow-start.html:24
 #: .\course\templates\course\gradebook-single.html:141
 msgid "State"
 msgstr "状态"
 
 #. Translators: help text of "attempt_id" in GradeChange class
-#: .\course\models.py:1025
+#: .\course\models.py:1070
 msgid ""
 "Grade changes are grouped by their 'attempt ID' where later grades with the "
 "same attempt ID supersede earlier ones."
@@ -2110,185 +2111,186 @@ msgstr ""
 "评分的变化是根据它们的\"attempt ID'进行分组, 在相同的'attempt ID\"下, 后面的"
 "评分将覆盖前面的评分. "
 
-#: .\course\models.py:1052
+#: .\course\models.py:1097
 msgid "Grade change"
 msgstr "评分变更"
 
-#: .\course\models.py:1053
+#: .\course\models.py:1098
 msgid "Grade changes"
 msgstr "评分变更"
 
 #. Translators: information for GradeChange
-#: .\course\models.py:1058
+#: .\course\models.py:1103
 #, python-format
 msgid "%(participation)s %(state)s on %(opportunityname)s"
 msgstr "%(opportunityname)s中, %(participation)s %(state)s"
 
-#: .\course\models.py:1067
+#: .\course\models.py:1115
 msgid "Participation and opportunity must live in the same course"
 msgstr "参与(Participation)和评分机会(opportunity)必须属于同一门课程"
 
-#: .\course\models.py:1119
+#: .\course\models.py:1167
 msgid "cannot accept grade once opportunity has been marked 'unavailable'"
 msgstr "一旦评分机会被标记为\"无效(unavailable)\", 将无法进行评分"
 
-#: .\course\models.py:1123
+#: .\course\models.py:1171
 msgid "cannot accept grade once opportunity has been marked 'exempt'"
 msgstr "一旦评分机会被标记为\"剔除(exempt)\", 将无法进行评分"
 
-#: .\course\models.py:1166
+#: .\course\models.py:1214
 #, python-format
 msgid "invalid grade change state '%s'"
 msgstr "无效的评分改变状态 \"%s\""
 
-#: .\course\models.py:1208
+#: .\course\models.py:1256
 #, python-format
 msgid "invalid grade aggregation strategy '%s'"
 msgstr "无效的多session评分累积策略 \"%s\""
 
 #. Translators: display the name of a flow
-#: .\course\models.py:1258
+#: .\course\models.py:1306
 #, python-format
 msgid "Flow: %(flow_desc_title)s"
 msgstr ""
 
-#: .\course\models.py:1287
+#: .\course\models.py:1335
 msgid "Text"
 msgstr "文字"
 
-#: .\course\models.py:1289 .\course\templates\course\gradebook-single.html:71
+#: .\course\models.py:1337 .\course\templates\course\gradebook-single.html:71
 #: .\course\views.py:263
 msgid "Time"
 msgstr "时间"
 
-#: .\course\models.py:1292
+#: .\course\models.py:1340
 msgid "Instant message"
 msgstr "即时信息"
 
-#: .\course\models.py:1293
+#: .\course\models.py:1341
 msgid "Instant messages"
 msgstr "即时信息"
 
-#: .\course\models.py:1308
+#: .\course\models.py:1359
 msgid "Description"
 msgstr "描述"
 
-#: .\course\models.py:1313
+#: .\course\models.py:1364
 msgid "Currently active"
 msgstr "当前生效"
 
-#: .\course\models.py:1316
+#: .\course\models.py:1367
 msgid "No exams before"
 msgstr "之前未有测验"
 
-#: .\course\models.py:1319
+#: .\course\models.py:1370
 msgid "No exams after"
 msgstr "之后未有测验"
 
-#: .\course\models.py:1323
+#: .\course\models.py:1374
 msgid "Lock down sessions"
 msgstr "锁定session"
 
-#: .\course\models.py:1324
+#: .\course\models.py:1375
 msgid ""
 "Only allow access to exam content (and no other content in this RELATE "
 "instance) in sessions logged in through this exam"
-msgstr "只允许经由此本测验登入的session来访问测验的内容,同时不允许访问本"
-"RELATE网站的其它内容"
+msgstr ""
+"只允许经由此本测验登入的session来访问测验的内容,同时不允许访问本RELATE网站的"
+"其它内容"
 
-#: .\course\models.py:1330 .\course\templates\course\course-base.html:74
-#: .\relate\templates\base.html:87
+#: .\course\models.py:1381 .\course\templates\course\course-base.html:74
+#: .\relate\templates\base.html:84
 msgid "Exams"
 msgstr "测验"
 
-#: .\course\models.py:1334
+#: .\course\models.py:1385
 #, python-format
 msgid "Exam  %(description)s in %(course)s"
 msgstr "课程%(course)s中的测验: %(description)s"
 
-#: .\course\models.py:1352
+#: .\course\models.py:1406
 msgid "Usage time"
 msgstr "使用的时间"
 
-#: .\course\models.py:1357
+#: .\course\models.py:1411
 msgid "Exam ticket state"
 msgstr "测验ticket的状态"
 
-#: .\course\models.py:1362
+#: .\course\models.py:1416
 msgid "Exam ticket"
 msgstr "测验ticket"
 
-#: .\course\models.py:1363
+#: .\course\models.py:1417
 msgid "Exam tickets"
 msgstr "测验ticket"
 
-#: .\course\models.py:1366
+#: .\course\models.py:1420
 msgid "Can issue exam tickets to student"
 msgstr "可以向学生发布测验ticket"
 
-#: .\course\models.py:1370
+#: .\course\models.py:1424
 #, python-format
 msgid "Exam  ticket for %(participation)s in %(exam)s"
 msgstr "%(participation)s在%(exam)s中的测验ticket."
 
-#: .\course\models.py:1380
+#: .\course\models.py:1437
 msgid "Participation and exam must live in the same course"
 msgstr "参与者和测验必须属于同一门课程"
 
-#: .\course\page\base.py:103
+#: .\course\page\base.py:104
 msgid "Your answer is not correct."
 msgstr "您的回答不正确. "
 
-#: .\course\page\base.py:105
+#: .\course\page\base.py:106
 msgid "Your answer is correct."
 msgstr "您的回答是正确的. "
 
-#: .\course\page\base.py:109
+#: .\course\page\base.py:110
 msgid "Your answer is mostly correct."
 msgstr "您的回答基本正确. "
 
-#: .\course\page\base.py:113
+#: .\course\page\base.py:114
 msgid "No information on correctness of answer."
 msgstr "未知回答正确与否. "
 
-#: .\course\page\base.py:117
+#: .\course\page\base.py:118
 msgid "Your answer is somewhat correct."
 msgstr "您的回答在一定程度上正确. "
 
-#: .\course\page\base.py:146
+#: .\course\page\base.py:147
 msgid "Invalid correctness value"
 msgstr "无效的正确性数值"
 
-#: .\course\page\base.py:535
+#: .\course\page\base.py:536
 #, python-format
 msgid ""
 "PageBaseWithTitle subclass '%s' does not implement markdown_body_for_title()"
 msgstr "PageBaseWithTitle的子类\"%s\"未使用markdown_body_for_title()方法"
 
-#: .\course\page\base.py:545
+#: .\course\page\base.py:546
 msgid "no title found in body or title attribute"
 msgstr "没有在body中找到title,也没有title属性"
 
-#: .\course\page\base.py:586
+#: .\course\page\base.py:587
 msgid "Grade assigned, in percent"
 msgstr "给予的评分(百分比)"
 
-#: .\course\page\base.py:591
+#: .\course\page\base.py:592
 msgid "Grade percent"
 msgstr "得分的百分比"
 
-#: .\course\page\base.py:597
+#: .\course\page\base.py:598
 #, python-format
 msgid ""
 "Grade assigned, as points out of %.1f. Fill out either this or 'grade "
 "percent'."
 msgstr "给予的评分, %.1f分中取得的分值. 填入此项或者\"得分的百分比\". "
 
-#: .\course\page\base.py:604
+#: .\course\page\base.py:605
 msgid "Grade points"
 msgstr "得分的分值"
 
-#: .\course\page\base.py:610
+#: .\course\page\base.py:611
 msgid ""
 "Feedback to be shown to student, using <a href='http://documen.tician.de/"
 "relate/content.html#relate-markup'>RELATE-flavored Markdown</a>"
@@ -2296,83 +2298,83 @@ msgstr ""
 "将反馈给学生的信息, 建议使用<a href='http://documen.tician.de/relate/content."
 "html#relate-markup'>RELATE方式的Markdown模式</a>. "
 
-#: .\course\page\base.py:614
+#: .\course\page\base.py:615
 msgid "Feedback text"
 msgstr "反馈文字"
 
-#: .\course\page\base.py:617
+#: .\course\page\base.py:618
 msgid ""
 "Checking this box and submitting the form will notify the participant with a "
 "generic message containing the feedback text"
 msgstr "勾选此项并提交这个表单, 将会向参与者发送一个包含了反馈信息的消息. "
 
-#: .\course\page\base.py:620
+#: .\course\page\base.py:621
 msgid "Notify"
 msgstr "发送通知"
 
-#: .\course\page\base.py:623
+#: .\course\page\base.py:624
 msgid "Whether the grade and feedback are to be shown to student"
 msgstr "是否允许学生看到分数和反馈"
 
-#: .\course\page\base.py:625
+#: .\course\page\base.py:626
 msgid "Released"
 msgstr "已发布"
 
-#: .\course\page\base.py:628
+#: .\course\page\base.py:629
 msgid "Internal notes, not shown to student"
 msgstr "内部注释, 学生不可见"
 
-#: .\course\page\base.py:630
+#: .\course\page\base.py:631
 msgid "Notes"
 msgstr "注释"
 
-#: .\course\page\base.py:643 .\course\page\base.py:657
+#: .\course\page\base.py:644 .\course\page\base.py:658
 msgid "Grade (percent) and Grade (points) disagree"
 msgstr "百分比评分与分值评分不一致"
 
-#: .\course\page\base.py:733
+#: .\course\page\base.py:734
 msgid "New notification"
 msgstr "一条新的通知"
 
-#: .\course\page\base.py:763 .\course\page\choice.py:223
-#: .\course\page\choice.py:333 .\course\page\code.py:530
-#: .\course\page\code.py:834 .\course\page\inline.py:822
-#: .\course\page\text.py:897
+#: .\course\page\base.py:764 .\course\page\choice.py:224
+#: .\course\page\choice.py:334 .\course\page\code.py:530
+#: .\course\page\code.py:834 .\course\page\inline.py:820
+#: .\course\page\text.py:898
 msgid "No answer provided."
 msgstr "未回答. "
 
-#: .\course\page\base.py:785
+#: .\course\page\base.py:786
 msgid "The following feedback was provided"
 msgstr "有以下的反馈信息"
 
 #. Translators: "choice" in Choice Answer Form in a single-choice question.
-#: .\course\page\choice.py:46
+#: .\course\page\choice.py:47
 msgid "Choice"
 msgstr "选项"
 
 #. Translators: "Choice" in Choice Answer Form in a multiple
 #. choice question in which multiple answers can be chosen.
-#: .\course\page\choice.py:57
+#: .\course\page\choice.py:58
 msgid "Choices"
 msgstr "多项选择"
 
-#: .\course\page\choice.py:125 .\course\page\choice.py:445
-#: .\course\page\inline.py:427
+#: .\course\page\choice.py:126 .\course\page\choice.py:446
+#: .\course\page\inline.py:425
 #, python-format
 msgid "choice %(idx)d: unable to convert to string"
 msgstr "选项%(idx)d: 无法转换为字符串"
 
-#: .\course\page\choice.py:140
+#: .\course\page\choice.py:141
 #, python-format
 msgid "one or more correct answer(s) expected, %(n_correct)d found"
 msgstr "需要至少1个参考答案,找到%(n_correct)d个"
 
-#: .\course\page\choice.py:237 .\course\page\inline.py:794
-#: .\course\page\text.py:918
+#: .\course\page\choice.py:238 .\course\page\inline.py:792
+#: .\course\page\text.py:919
 msgid "A correct answer is"
 msgstr "参考答案"
 
-#: .\course\page\choice.py:377
+#: .\course\page\choice.py:378
 msgid "The correct answer is"
 msgstr "正确答案"
 
@@ -2440,21 +2442,21 @@ msgstr "以下的代码是一个有效的回答"
 msgid "human_feedback_value greater than overall value of question"
 msgstr "人工评分(human_feedback_value)大于这个问题的总分值"
 
-#: .\course\page\inline.py:134
+#: .\course\page\inline.py:132
 #, python-format
 msgid "unknown embeded question type '%(type)s'"
 msgstr "未知的嵌入型问题类型\"%(type)s\""
 
-#: .\course\page\inline.py:148
+#: .\course\page\inline.py:146
 msgid "must be struct"
 msgstr "必须是一个struct型的数据"
 
-#: .\course\page\inline.py:239
+#: .\course\page\inline.py:237
 #, python-format
 msgid "unrecogonized width attribute string: '%(width_attr)s'"
 msgstr "无法识别的宽度字符串: '%(width_attr)s'"
 
-#: .\course\page\inline.py:250
+#: .\course\page\inline.py:248
 #, python-format
 msgid ""
 "unsupported length unit '%(length_unit)s', expected length unit can be %"
@@ -2463,60 +2465,60 @@ msgstr ""
 "不支持的长度单位'%(length_unit)s', 可使用的长度单位包括%(allowed_length_unit)"
 "s"
 
-#: .\course\page\inline.py:293 .\course\page\text.py:867
+#: .\course\page\inline.py:291 .\course\page\text.py:868
 msgid "at least one answer must be provided"
 msgstr "至少要提供一个回答"
 
 #. Translators: refers to optional
 #. correct answer for checking
 #. correctness sumbitted by students.
-#: .\course\page\inline.py:316
+#: .\course\page\inline.py:314
 msgid "answer"
 msgstr "回答"
 
-#: .\course\page\inline.py:326 .\course\page\text.py:882
+#: .\course\page\inline.py:324 .\course\page\text.py:883
 msgid "no matcher is able to provide a plain-text correct answer"
 msgstr "现有的匹配类无法提供一个普通文本型的标准答案"
 
-#: .\course\page\inline.py:444
+#: .\course\page\inline.py:442
 #, python-format
 msgid ""
 "one or more correct answer(s) expected  for question '%(question_name)s', %"
 "(n_correct)d found"
 msgstr "问题'%(question_name)s'至少要有1个答案,找到%(n_correct)d个"
 
-#: .\course\page\inline.py:622
+#: .\course\page\inline.py:620
 #, python-format
 msgid "invalid answers name %s. "
 msgstr "无效的答案名称%s. "
 
-#: .\course\page\inline.py:623 .\course\page\inline.py:641
+#: .\course\page\inline.py:621 .\course\page\inline.py:639
 msgid ""
 "A valid name should start with letters. Alphanumeric with underscores. Do "
 "not use spaces."
 msgstr "一个有效的名称应以字母开头,允许包含数字和下划线, 不允许有空格. "
 
-#: .\course\page\inline.py:640
+#: .\course\page\inline.py:638
 #, python-format
 msgid "invalid embeded question name %s. "
 msgstr "无效的嵌入型问题名称%s. "
 
-#: .\course\page\inline.py:658
+#: .\course\page\inline.py:656
 #, python-format
 msgid "embeded question name %s not unique."
 msgstr "嵌入问题的名称%s不是唯一的."
 
-#: .\course\page\inline.py:669
+#: .\course\page\inline.py:667
 #, python-format
 msgid "correct answer(s) not provided for question %s."
 msgstr "未为问题%s提供正确答案. "
 
-#: .\course\page\inline.py:677
+#: .\course\page\inline.py:675
 #, python-format
 msgid "redundant answers %s provided for non-existing question(s)."
 msgstr "为不存在的问题提供了多余的答案%s. "
 
-#: .\course\page\inline.py:710
+#: .\course\page\inline.py:708
 #, python-format
 msgid "have unpaired '%s'."
 msgstr "有未配对的\"%s\"."
@@ -2530,7 +2532,7 @@ msgstr "page必须是\"%s\"类型"
 msgid "unknown validator type"
 msgstr "未知的验证器类型"
 
-#: .\course\page\text.py:186 .\course\page\text.py:586
+#: .\course\page\text.py:186 .\course\page\text.py:587
 msgid "must be struct or string"
 msgstr "必须是一个struct或string型的数据"
 
@@ -2539,16 +2541,16 @@ msgstr "必须是一个struct或string型的数据"
 msgid "regex '%(pattern)s' did not compile"
 msgstr "正则表达式(regex)\"%(pattern)s\"无法编译"
 
-#: .\course\page\text.py:340
+#: .\course\page\text.py:341
 msgid "unable to check symbolic expression"
 msgstr "无法检查symbolic表达式"
 
-#: .\course\page\text.py:444 .\course\page\text.py:455
-#: .\course\page\text.py:465
+#: .\course\page\text.py:445 .\course\page\text.py:456
+#: .\course\page\text.py:466
 msgid "does not provide a valid float literal"
 msgstr "提供了一个无效的float字符串"
 
-#: .\course\page\text.py:475
+#: .\course\page\text.py:476
 msgid ""
 "Float match should have either rtol or atol--otherwise it will match any "
 "number"
@@ -2558,29 +2560,29 @@ msgstr ""
 #. Translators: a "matcher" is used to determine
 #. if the answer to text question (blank filling
 #. question) is correct.
-#: .\course\page\text.py:533
+#: .\course\page\text.py:534
 #, python-format
 msgid "%(matcherclassname)s only accepts '%(matchertype)s' patterns"
 msgstr "%(matcherclassname)s 只接受 \"%(matchertype)s\" 模式"
 
-#: .\course\page\text.py:545
+#: .\course\page\text.py:546
 #, python-format
 msgid "unknown match type '%(matchertype)s'"
 msgstr "未知的匹配(match)类型\"%(matchertype)s\""
 
-#: .\course\page\text.py:564
+#: .\course\page\text.py:565
 msgid "does not specify match type"
 msgstr "无法确定匹配(match)类型"
 
-#: .\course\page\text.py:572
+#: .\course\page\text.py:573
 msgid "uses deprecated 'matcher:answer' style"
 msgstr "使用了已淘汰了的(deprecated) \"matcher:answer\" 类型"
 
-#: .\course\page\text.py:593
+#: .\course\page\text.py:594
 msgid "matcher must supply 'type'"
 msgstr "matcher必须提供\"type\""
 
-#: .\course\page\text.py:644
+#: .\course\page\text.py:645
 msgid "unrecognized widget type"
 msgstr "无法识别的构件(widget)类型"
 
@@ -3436,7 +3438,7 @@ msgstr ", 评分者为%(grader_name)s"
 msgid "at %(grade_time)s"
 msgstr ", 评分时间为%(grade_time)s"
 
-#: .\course\templates\course\grade-flow-page.html:131 .\course\views.py:596
+#: .\course\templates\course\grade-flow-page.html:131 .\course\views.py:592
 msgid "Session"
 msgstr ""
 
@@ -3740,7 +3742,7 @@ msgstr "本(%(RELATE)s)网站还没有挂载课程. "
 msgid "<a href=\"%(relate-sign_in_by_user_pw)s\">Sign in</a> to get started."
 msgstr "<a href=\"%(relate-sign_in_by_user_pw)s\">登录</a> 以开始使用. "
 
-#: .\course\templates\course\home.html:41 .\course\versioning.py:248
+#: .\course\templates\course\home.html:41 .\course\versioning.py:251
 msgid "Set up new course"
 msgstr "设置新课程"
 
@@ -4070,132 +4072,146 @@ msgstr "%s: 找不到page"
 msgid "group id '%(group_id)s' not unique"
 msgstr "group id \"%(group_id)s\" 应该是唯一的"
 
-#: .\course\validation.py:900
+#: .\course\validation.py:887
+#, python-format
+msgid "Your course repository does not have an events file named '%s'."
+msgstr "您课程的仓库中并不包含一个名为'%s'的事件文件."
+
+#: .\course\validation.py:907
 msgid ""
 "Your course repository has a 'media/' directory. Linking to media files "
 "using 'media:' is discouraged. Use the 'repo:' and 'repocur:' linkng schemes "
 "instead."
-msgstr "你课程的仓库中有一个'media/'目录. 不建议使用'media:'来链接到媒体文件. "
-"建议改为使用'repo:'和'repocur:'来链接到你的方案(schemes)."
+msgstr ""
+"你课程的仓库中有一个'media/'目录. 不建议使用'media:'来链接到媒体文件. 建议改"
+"为使用'repo:'和'repocur:'来链接到你的方案(schemes)."
 
-#: .\course\validation.py:922
+#: .\course\validation.py:929
 msgid ""
 "invalid flow name. Flow names may only contain (roman) letters, numbers, "
 "dashes and underscores."
 msgstr "无效的flow名称. flow的名称只能有英文字母、数字、减号和下划线. "
 
-#: .\course\validation.py:1046
+#: .\course\validation.py:952
+msgid "flow uses more than one grade_identifier"
+msgstr "本flow中使用了多于1个grade_identifier"
+
+#: .\course\validation.py:959
+msgid "flow uses the same grade_identifier as another flow"
+msgstr "本flow使用了与另一个flow相同的grade_identifier"
+
+#: .\course\validation.py:1057
 msgid "WARNINGS: "
 msgstr "警告:"
 
-#: .\course\versioning.py:133
+#: .\course\versioning.py:137
 msgid "Validate and create"
 msgstr "验证并创建课程"
 
-#: .\course\versioning.py:140
+#: .\course\versioning.py:143
 msgid "only staff may create courses"
 msgstr "只有课程管理人员(staff)及以上才能创建课程"
 
-#: .\course\versioning.py:197
+#: .\course\versioning.py:200
 msgid "Course content validated, creation succeeded."
 msgstr "课程内容有效性验证完成, 创建成功. "
 
-#: .\course\versioning.py:223
+#: .\course\versioning.py:226
 #, python-format
 msgid "Failed to delete unused repository directory '%s'."
 msgstr "无法删除未使用的代码仓库目录\"%s\"."
 
-#: .\course\versioning.py:235
+#: .\course\versioning.py:238
 msgid "Course creation failed"
 msgstr "课程创建失败"
 
-#: .\course\versioning.py:284
+#: .\course\versioning.py:287
 msgid "no git source URL specified"
 msgstr "未设定git源的URL"
 
-#: .\course\versioning.py:296
+#: .\course\versioning.py:299
 msgid "fetch would discard commits, refusing"
 msgstr "fetch将会放弃修改, 拒绝fetch"
 
-#: .\course\versioning.py:300
+#: .\course\versioning.py:303
 msgid "Fetch successful."
 msgstr "fetch成功. "
 
-#: .\course\versioning.py:309
+#: .\course\versioning.py:312
 msgid "Preview ended."
 msgstr "预览已结束. "
 
-#: .\course\versioning.py:324
+#: .\course\versioning.py:327
 #, python-format
 msgid "Course content did not validate successfully. (%s) Update not applied."
 msgstr "课程内容有效性验证不成功, (%s) 未应用更新. "
 
-#: .\course\versioning.py:331
+#: .\course\versioning.py:334
 msgid "Course content validated successfully."
 msgstr "课程内容有效性验证成功. "
 
-#: .\course\versioning.py:335
+#: .\course\versioning.py:338
 msgid "Course content validated OK, with warnings: "
 msgstr "课程内容有效性验证成功, 但有警告信息:"
 
-#: .\course\versioning.py:346
+#: .\course\versioning.py:349
 msgid "Preview activated."
 msgstr "预览状态已激活. "
 
-#: .\course\versioning.py:357
+#: .\course\versioning.py:360
 msgid "Update applied. "
 msgstr "更新已应用. "
 
-#: .\course\versioning.py:360 .\course\versioning.py:439 .\course\views.py:686
+#: .\course\versioning.py:363 .\course\versioning.py:435 .\course\views.py:681
 msgid "invalid command"
 msgstr "无效的命令"
 
-#: .\course\versioning.py:367
+#: .\course\versioning.py:370
 msgctxt "new git SHA for revision of course contents"
 msgid "New git SHA"
 msgstr "新的git SHA"
 
-#: .\course\versioning.py:369
+#: .\course\versioning.py:372
 msgid "Prevent updating to a git revision prior to the current one"
 msgstr "防止更新到当前git修订版本之前的版本."
 
-#: .\course\versioning.py:387
+#: .\course\versioning.py:383
 msgid "Fetch and update"
 msgstr "fetch并更新"
 
-#: .\course\versioning.py:391
+#: .\course\versioning.py:387
 msgid "End preview"
 msgstr "结束预览"
 
-#: .\course\versioning.py:393
+#: .\course\versioning.py:389
 msgid "Fetch and preview"
 msgstr "fetch并预览"
 
-#: .\course\versioning.py:396
+#: .\course\versioning.py:392
 msgid "Fetch"
 msgstr ""
 
-#: .\course\versioning.py:407
+#: .\course\versioning.py:403
 msgid "must be instructor or TA to update course"
 msgstr "只有任课老师(instructor)和助理(TA)可以更新课程"
 
-#: .\course\versioning.py:474
+#: .\course\versioning.py:475
 msgid "Current git HEAD"
 msgstr "当前的git HEAD"
 
-#: .\course\versioning.py:481
+#: .\course\versioning.py:483
 msgid "Public active git SHA"
 msgstr "公开运行的git SHA"
 
-#: .\course\versioning.py:494 .\course\versioning.py:506
+#: .\course\versioning.py:496 .\course\versioning.py:508
 msgid "Current preview git SHA"
 msgstr "当前预览的git SHA"
 
-#: .\course\versioning.py:508
+#: .\course\versioning.py:510
 msgid "None"
 msgstr "无"
 
-#: .\course\versioning.py:516
+#: .\course\versioning.py:518
 msgid "Update Course Revision"
 msgstr "更新对课程内容的修订"
 
@@ -4227,7 +4243,7 @@ msgstr "恢复正常"
 msgid "only staff may set fake time"
 msgstr "只有课程管理人员(staff)及以上可以设置虚拟时间"
 
-#: .\course\views.py:325 .\relate\templates\base.html:81
+#: .\course\views.py:325 .\relate\templates\base.html:78
 msgid "Set fake time"
 msgstr "设置虚拟时间"
 
@@ -4241,84 +4257,84 @@ msgctxt "Add an instant flow"
 msgid "Add"
 msgstr "添加"
 
-#: .\course\views.py:360
+#: .\course\views.py:359
 msgctxt "Cancel all instant flow(s)"
 msgid "Cancel all"
 msgstr "全部取消"
 
-#: .\course\views.py:367
+#: .\course\views.py:366
 msgid "must be instructor to manage instant flow requests"
 msgstr "只有任课老师(instructor)才能管理即时flow"
 
-#: .\course\views.py:414
+#: .\course\views.py:413
 msgid "Manage Instant Flow Requests"
 msgstr "管理即时Flow"
 
-#: .\course\views.py:436
+#: .\course\views.py:435
 msgctxt "Start an activity"
 msgid "Go"
 msgstr "前往"
 
-#: .\course\views.py:446
+#: .\course\views.py:445
 msgid "must be instructor or TA to test flows"
 msgstr "只有任课老师(instructor)和助理(TA)可以测试flow"
 
-#: .\course\views.py:467
+#: .\course\views.py:466
 msgid "Test Flow"
 msgstr "测试flow"
 
-#: .\course\views.py:512 .\course\views.py:603
+#: .\course\views.py:511 .\course\views.py:599
 msgctxt "Next step"
 msgid "Next"
 msgstr "下一步"
 
-#: .\course\views.py:523 .\course\views.py:614 .\course\views.py:828
+#: .\course\views.py:521 .\course\views.py:609 .\course\views.py:822
 msgid "must be instructor or TA to grant exceptions"
 msgstr "只有任课老师(instructor)和助理(TA)可以进行破例评分"
 
-#: .\course\views.py:543 .\course\views.py:723 .\course\views.py:995
+#: .\course\views.py:541 .\course\views.py:718 .\course\views.py:989
 msgid "Grant Exception"
 msgstr "给予破例"
 
 #. Translators: %s is the string of the start time of a session.
-#: .\course\views.py:550
+#: .\course\views.py:548
 #, python-format
 msgid "started at %s"
 msgstr "开始于%s"
 
-#: .\course\views.py:567
+#: .\course\views.py:565
 msgid ""
 "If you click 'Create session', this tag will be applied to the new session."
 msgstr "如果您点击\"创建session\", 这个tag将会应用到新的session. "
 
-#: .\course\views.py:569
+#: .\course\views.py:567
 msgid "Access rules tag for new session"
 msgstr "新session的访问规则tag"
 
-#: .\course\views.py:575
+#: .\course\views.py:573
 msgid "Create session (override rules)"
 msgstr "创建session(覆盖rules)"
 
-#: .\course\views.py:581
+#: .\course\views.py:578
 msgid "Create session"
 msgstr "创建session"
 
-#: .\course\views.py:593
+#: .\course\views.py:589
 msgid ""
 "The rules that currently apply to selected session will provide the default "
 "values for the rules on the next page."
 msgstr "选定session所采用的rule将为作为下一个page所采用rule的默认值. "
 
-#: .\course\views.py:623
+#: .\course\views.py:618
 #, python-format
 msgid "Granting exception to '%(participation)s' for '%(flow_id)s'."
 msgstr "对%(participation)s的%(flow_id)s给予破例."
 
-#: .\course\views.py:644 .\course\views.py:648
+#: .\course\views.py:639 .\course\views.py:643
 msgid "NONE"
 msgstr "无"
 
-#: .\course\views.py:658
+#: .\course\views.py:653
 msgid ""
 "Creating a new session is (technically) not allowed by course rules. "
 "Clicking 'Create Session' anyway will override this rule."
@@ -4326,12 +4342,12 @@ msgstr ""
 "根据课程的设定, (从技术上)不允许创建一个新的session. 点击\"创建session\"将覆"
 "盖掉这个规则. "
 
-#: .\course\views.py:733
+#: .\course\views.py:728
 msgctxt "Time when access expires"
 msgid "Access expires"
 msgstr "访问到期时间"
 
-#: .\course\views.py:734
+#: .\course\views.py:729
 msgid ""
 "At the specified time, the special access granted below will expire and "
 "revert to being the same as for the rest of the class. This field may be "
@@ -4344,19 +4360,19 @@ msgstr ""
 "date\"和'credit percent\"也不会过期, 并且始终保持有效, 除非被其它的破例措施覆"
 "盖. "
 
-#: .\course\views.py:759
+#: .\course\views.py:754
 msgid "Exception only applies to sessions with the above tag"
 msgstr "只有有以上tag的session才能采取破例措施. "
 
-#: .\course\views.py:778
+#: .\course\views.py:773
 msgid "If set, the 'Due' field will be disregarded."
 msgstr "如果选定, 则“截止时间”的设定将不被考虑. "
 
-#: .\course\views.py:781
+#: .\course\views.py:776
 msgid "Due same as access expiration"
 msgstr "访问到期,则截止"
 
-#: .\course\views.py:786
+#: .\course\views.py:781
 msgid ""
 "The due time shown to the student. Also, the time after which any session "
 "under these rules is subject to expiration."
@@ -4365,46 +4381,46 @@ msgstr ""
 "date shown to the student. Also, the time after which any session under "
 "these rules is subject to expiration. "
 
-#: .\course\views.py:794
+#: .\course\views.py:789
 msgid "Credit percent"
 msgstr "得分百分比"
 
-#: .\course\views.py:807
+#: .\course\views.py:802
 msgid "Save"
 msgstr "保存"
 
-#: .\course\views.py:817
+#: .\course\views.py:811
 msgid ""
 "Must specify access expiration if 'due same as access expiration' is set."
 msgstr ""
 "如果设定了与访问同时截止(due same as access expiration), 则必须确定访问截止时"
 "间(access expiration). "
 
-#: .\course\views.py:889 .\course\views.py:956
+#: .\course\views.py:883 .\course\views.py:950
 msgid "newly created exception"
 msgstr "新创建的破例"
 
-#: .\course\views.py:918
+#: .\course\views.py:912
 msgid "Granted excecption"
 msgstr "已给予破例"
 
-#: .\course\views.py:920
+#: .\course\views.py:914
 msgid "credit"
 msgstr "应得分"
 
-#: .\course\views.py:972
+#: .\course\views.py:966
 #, python-format
 msgid "Exception granted to '%(participation)s' for '%(flow_id)s'."
 msgstr "已对%(participation)s的%(flow_id)s给予破例. "
 
-#: .\course\views.py:998
+#: .\course\views.py:992
 #, python-format
 msgid ""
 "Granting exception to '%(participation)s' for '%(flow_id)s' (session %"
 "(session)s)."
 msgstr "对%(participation)s的%(flow_id)s(%(session)s的session)给予破例."
 
-#: .\course\views.py:1015
+#: .\course\views.py:1009
 msgid "only staff may use this tool"
 msgstr "只有课程管理人员可以使用这个工具"
 
@@ -4491,32 +4507,32 @@ msgid ""
 "(fake_time)s."
 msgstr "您现在正在预览这个网站在时间为%(fake_time)s时的样子. "
 
-#: .\relate\templates\base.html:70
+#: .\relate\templates\base.html:67
 msgid "Staff"
 msgstr "高级管理"
 
-#: .\relate\templates\base.html:73
+#: .\relate\templates\base.html:70
 msgid "Admin site"
 msgstr "管理网站"
 
-#: .\relate\templates\base.html:75
+#: .\relate\templates\base.html:72
 msgid "Test/Troubleshoot"
 msgstr "测试/发现问题"
 
-#: .\relate\templates\base.html:88
+#: .\relate\templates\base.html:85
 msgid "Issue exam tickets"
 msgstr "发布测验ticket"
 
-#: .\relate\templates\base.html:89
+#: .\relate\templates\base.html:86
 msgid "Exam check-in"
 msgstr "登入测验"
 
-#: .\relate\templates\base.html:99
+#: .\relate\templates\base.html:96
 #, python-format
 msgid "Signed in as %(username)s"
 msgstr "登录用户: %(username)s"
 
-#: .\relate\templates\base.html:106
+#: .\relate\templates\base.html:103
 msgid "(impersonated)"
 msgstr "(正在模拟用户)"