diff --git a/.gitignore b/.gitignore
index b3fa1ad84666b0e6ee760ea3b6714aaef35fb864..7c06b552c21bfe4ba4049dc1e40da652f1545e90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,5 @@ docs/_build/
 .coverage
 .mypy_cache/
 htmlcov/
+
+poetry.lock
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 27a9c8b5f89ac3378dd9586118fe073a21deb1d3..f8bcd06c637e4de890c6a8b96312a05f102ca0f8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,6 +1,8 @@
 include:
     - project: "AlekSIS/official/AlekSIS"
       file: /ci/general.yml
+    - project: "AlekSIS/official/AlekSIS"
+      file: /ci/prepare/lock.yml
     - project: "AlekSIS/official/AlekSIS"
       file: /ci/test/test.yml
     - project: "AlekSIS/official/AlekSIS"
@@ -11,3 +13,5 @@ include:
       file: /ci/build/dist.yml
     - project: "AlekSIS/official/AlekSIS"
       file: /ci/publish/pypi.yml
+    - project: "AlekSIS/official/AlekSIS"
+      file: /ci/docker/image.yml
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 788236f8c809dd050602e19d78d75e236cd45bb6..d05154a9ed55034bbef054f4463e67be35c65c27 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -9,11 +9,61 @@ and this project adheres to `Semantic Versioning`_.
 Unreleased
 ----------
 
+Added
+~~~~~
+
+* Integrate seating plans in lesson overview
+* Add option to set LessonDocumentation data for all lessons in one week at once.
+* Excuse types can now be marked as `Count as absent`, which they are per default. If not, they aren't counted in the overviews.
+* Add Ukrainian locale (contributed by Sergiy Gorichenko from Fre(i)e Software GmbH).
+
+Fixed
+~~~~~
+
+* The week overview page was not refreshed when a new week was selected in the dropdown.
+
+`2.0.1`_ - 2022-02-12
+---------------------
+
+Fixed
+~~~~~
+
+* Status icon in single-lesson view showed 'Missing data' although the data were complete.
+* The personal note tab of a lesson was not well usable on mobile devices.
+
+`2.0`_ - 2022-02-06
+------------------
+
+Changed
+~~~~~~~
+
+* Use start date of current SchoolTerm as default value for PersonalNote filter in overview.
+
+Fixed
+~~~~~
+
+* Events without groups caused an error when not accessed through the week view.
+
+`2.0rc7`_ - 2021-12-25
+---------------------
+
+Changed
+~~~~~~~
+
+* Optimize view for one register object ("lesson view") for mobile and tablet devices.
+* Optimize view for lessons of a week ("week view") for mobile and tablet devices.
+* German translations were updated.
+* Link to personal notes in the personal overview.
+
 Fixed
 ~~~~~
 
 * Translate table columns and filter button on person overview page.
 * Show correct status icon for events.
+* Subjects in full register printout were struck through although they
+hadn't changed.
+* Table with all register objects didn't work with extra lessons.
+* Add missing definitions of some permissions so they can be assigned.
 
 `2.0rc6`_ - 2021-08-25
 ----------------------
@@ -200,3 +250,6 @@ Fixed
 .. _2.0rc4: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc4
 .. _2.0rc5: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc5
 .. _2.0rc6: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc6
+.. _2.0rc7: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0rc7
+.. _2.0: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0
+.. _2.0.1: https://edugit.org/AlekSIS/Official/AlekSIS-App-Alsijil/-/tags/2.0.1
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d8fce524ded7036baf499e7ac83ff4b8fbe24556
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,2 @@
+ARG APPS="AlekSIS-App-Alsijil"
+FROM registry.edugit.org/aleksis/official/aleksis-core:master
diff --git a/README.rst b/README.rst
index 46a0bb8b6be07cc3e36c553b3c11211635892aa1..e0063aa4f1170759ab0377f9f51f0ea47a25796a 100644
--- a/README.rst
+++ b/README.rst
@@ -4,7 +4,7 @@ AlekSIS (School Information System) — App كتاب السجل (class regis
 AlekSIS
 -------
 
-This is an application for use with the `AlekSIS`_ platform.
+This is an application for use with the `AlekSIS®`_ platform.
 
 Features
 --------
@@ -22,6 +22,9 @@ This AlekSIS app currently provides the following features for managing digital
  * Show all owned groups of the current person
  * Show all students of the current person
  * Show filterable (week) overview for lesson documentations and personal/group notes
+ * Manage absence of persons
+ * Show overview of all students with statistics
+ 
 
 Licence
 -------
@@ -44,5 +47,13 @@ full licence text or on the `European Union Public Licence`_ website
 https://joinup.ec.europa.eu/collection/eupl/guidelines-users-and-developers
 (including all other official language versions).
 
-.. _AlekSIS: https://edugit.org/AlekSIS/Official/AlekSIS
+Trademark
+---------
+
+AlekSIS® is a registered trademark of the AlekSIS open source project, represented
+by Teckids e.V. Please refer to the `trademark policy`_ for hints on using the trademark
+AlekSIS®.
+
+.. _AlekSIS®: https://edugit.org/AlekSIS/Official/AlekSIS
 .. _European Union Public Licence: https://eupl.eu/
+.. _trademark policy: https://aleksis.org/pages/about
diff --git a/aleksis/apps/alsijil/filters.py b/aleksis/apps/alsijil/filters.py
index 4033e36e5500e3c440b73950fb96741761c46acf..c924aec0d78b5c28032407f805000d5481def23e 100644
--- a/aleksis/apps/alsijil/filters.py
+++ b/aleksis/apps/alsijil/filters.py
@@ -3,6 +3,8 @@ from django.utils.translation import gettext as _
 from django_filters import CharFilter, DateFilter, FilterSet
 from material import Layout, Row
 
+from aleksis.core.models import SchoolTerm
+
 from .models import PersonalNote
 
 
@@ -11,8 +13,20 @@ class PersonalNoteFilter(FilterSet):
     day_end = DateFilter(lookup_expr="lte", label=_("Before"))
     subject = CharFilter(lookup_expr="icontains", label=_("Subject"))
 
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
+    def __init__(self, data=None, *args, **kwargs):
+        if data is not None:
+            data = data.copy()
+
+            current_school_term = SchoolTerm.current
+            if not data.get("day_start") and current_school_term:
+                data["day_start"] = current_school_term.date_start
+
+            for name, f in self.base_filters.items():
+                initial = f.extra.get("initial")
+                if not data.get(name) and initial:
+                    data[name] = initial
+
+        super().__init__(data, *args, **kwargs)
         self.form.fields["late__lt"].label = _("Tardiness is lower than")
         self.form.fields["late__gt"].label = _("Tardiness is bigger than")
         self.form.layout = Layout(
diff --git a/aleksis/apps/alsijil/forms.py b/aleksis/apps/alsijil/forms.py
index 042b253363a2fa34ab203833e775c4175ebaf162..6f4e65b2022192c3cf5c0a7c4b44cc3e1731919e 100644
--- a/aleksis/apps/alsijil/forms.py
+++ b/aleksis/apps/alsijil/forms.py
@@ -13,7 +13,7 @@ from guardian.shortcuts import get_objects_for_user
 from material import Fieldset, Layout, Row
 
 from aleksis.apps.chronos.managers import TimetableType
-from aleksis.apps.chronos.models import Subject, TimePeriod
+from aleksis.apps.chronos.models import LessonPeriod, Subject, TimePeriod
 from aleksis.core.forms import ActionForm, ListActionForm
 from aleksis.core.models import Group, Person, SchoolTerm
 from aleksis.core.util.core_helpers import get_site_preferences
@@ -45,6 +45,30 @@ class LessonDocumentationForm(forms.ModelForm):
         super().__init__(*args, **kwargs)
 
         self.fields["homework"].label = _("Homework for the next lesson")
+        if (
+            self.instance.lesson_period
+            and get_site_preferences()["alsijil__allow_carry_over_same_week"]
+        ):
+            self.fields["carry_over_week"] = forms.BooleanField(
+                label=_("Carry over data to all other lessons with the same subject in this week"),
+                initial=True,
+                required=False,
+            )
+
+    def save(self, **kwargs):
+        lesson_documentation = super(LessonDocumentationForm, self).save(commit=True)
+        if (
+            self.cleaned_data["carry_over_week"]
+            and (
+                lesson_documentation.topic
+                or lesson_documentation.homework
+                or lesson_documentation.group_note
+            )
+            and lesson_documentation.lesson_period
+        ):
+            lesson_documentation.carry_over_data(
+                LessonPeriod.objects.filter(lesson=lesson_documentation.lesson_period.lesson)
+            )
 
 
 class PersonalNoteForm(forms.ModelForm):
@@ -69,10 +93,16 @@ class SelectForm(forms.Form):
     layout = Layout(Row("group", "teacher"))
 
     group = forms.ModelChoiceField(
-        queryset=None, label=_("Group"), required=False, widget=Select2Widget,
+        queryset=None,
+        label=_("Group"),
+        required=False,
+        widget=Select2Widget,
     )
     teacher = forms.ModelChoiceField(
-        queryset=None, label=_("Teacher"), required=False, widget=Select2Widget,
+        queryset=None,
+        label=_("Teacher"),
+        required=False,
+        widget=Select2Widget,
     )
 
     def clean(self) -> dict:
@@ -174,11 +204,11 @@ class ExtraMarkForm(forms.ModelForm):
 
 
 class ExcuseTypeForm(forms.ModelForm):
-    layout = Layout("short_name", "name")
+    layout = Layout("short_name", "name", "count_as_absent")
 
     class Meta:
         model = ExcuseType
-        fields = ["short_name", "name"]
+        fields = ["short_name", "name", "count_as_absent"]
 
 
 class PersonOverviewForm(ActionForm):
@@ -211,7 +241,10 @@ class AssignGroupRoleForm(forms.ModelForm):
         widget=ModelSelect2MultipleWidget(
             model=Group,
             search_fields=["name__icontains", "short_name__icontains"],
-            attrs={"data-minimum-input-length": 0, "class": "browser-default",},
+            attrs={
+                "data-minimum-input-length": 0,
+                "class": "browser-default",
+            },
         ),
     )
     person = forms.ModelChoiceField(
diff --git a/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po
index 30d41d21868fde3e5aed4655a80ea1b228e4570a..6789a3abca86d188ee71a30e14d1d17db1e851ef 100644
--- a/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po
+++ b/aleksis/apps/alsijil/locale/ar/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-28 17:33+0200\n"
+"POT-Creation-Date: 2021-12-24 13:24+0100\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"
@@ -110,10 +110,10 @@ msgstr ""
 msgid "Before"
 msgstr ""
 
-#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:293
+#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:302
 #: aleksis/apps/alsijil/tables.py:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:106
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:202
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:227
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:169
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:200
 msgid "Subject"
@@ -131,99 +131,100 @@ msgstr ""
 msgid "Homework for the next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:72 aleksis/apps/alsijil/forms.py:208
-#: aleksis/apps/alsijil/forms.py:292
+#: aleksis/apps/alsijil/forms.py:73 aleksis/apps/alsijil/forms.py:214
+#: aleksis/apps/alsijil/forms.py:301
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:199
 msgid "Group"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:75
+#: aleksis/apps/alsijil/forms.py:79
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:170
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:201
 msgid "Teacher"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:90
+#: aleksis/apps/alsijil/forms.py:96
 msgid "You can't select a group and a teacher both."
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:144 aleksis/apps/alsijil/forms.py:294
-#: aleksis/apps/alsijil/models.py:446
+#: aleksis/apps/alsijil/forms.py:150 aleksis/apps/alsijil/forms.py:303
+#: aleksis/apps/alsijil/models.py:471
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64
 msgid "Start date"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:145 aleksis/apps/alsijil/forms.py:295
-#: aleksis/apps/alsijil/models.py:450
+#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/forms.py:304
+#: aleksis/apps/alsijil/models.py:475
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65
 msgid "End date"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:146
+#: aleksis/apps/alsijil/forms.py:152
 msgid "Start period"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:147
+#: aleksis/apps/alsijil/forms.py:153
 msgid "End period"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:148
+#: aleksis/apps/alsijil/forms.py:154 aleksis/apps/alsijil/tables.py:108
+#: aleksis/apps/alsijil/tables.py:129
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:263
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:339
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:397
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:75
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:312
 msgid "Absent"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:149 aleksis/apps/alsijil/tables.py:137
+#: aleksis/apps/alsijil/forms.py:155 aleksis/apps/alsijil/tables.py:137
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:265
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:134
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:72
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:84
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:275
 msgid "Excused"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/models.py:62
-#: aleksis/apps/alsijil/models.py:232
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:266
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:307
+#: aleksis/apps/alsijil/forms.py:157 aleksis/apps/alsijil/models.py:62
+#: aleksis/apps/alsijil/models.py:236
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:31
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:72
 msgid "Excuse type"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:156
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:268
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:328
+#: aleksis/apps/alsijil/forms.py:162
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:93
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:314
 msgid "Remarks"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:218
+#: aleksis/apps/alsijil/forms.py:227
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:9
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:262
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27
 msgid "Person"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:290
+#: aleksis/apps/alsijil/forms.py:299
 msgid "School term"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:291
+#: aleksis/apps/alsijil/forms.py:300
 msgid "Has lesson documentation"
 msgstr ""
 
-#: aleksis/apps/alsijil/managers.py:81 aleksis/apps/alsijil/tables.py:121
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:57
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:151
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:214
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:268
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:16
+#: aleksis/apps/alsijil/managers.py:88 aleksis/apps/alsijil/tables.py:121
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:176
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:240
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:316
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:50
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:21
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:335
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:415
-#: aleksis/apps/alsijil/util/alsijil_helpers.py:314
+#: aleksis/apps/alsijil/util/alsijil_helpers.py:315
 msgid "Event"
 msgstr ""
 
@@ -275,12 +276,12 @@ msgstr ""
 msgid "Excuse types"
 msgstr ""
 
-#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:237
-#: aleksis/apps/alsijil/models.py:401
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:267
+#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:241
+#: aleksis/apps/alsijil/models.py:423 aleksis/apps/alsijil/tables.py:111
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9
 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:41
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:17
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:293
 msgid "Extra marks"
@@ -290,164 +291,178 @@ msgstr ""
 msgid "Manage group roles"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:180
+#: aleksis/apps/alsijil/model_extensions.py:191
 msgid "Can view week overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:183
+#: aleksis/apps/alsijil/model_extensions.py:195
 msgid "Can view lesson overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:185
+#: aleksis/apps/alsijil/model_extensions.py:197
 msgid "Can view all personal notes of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:186
+#: aleksis/apps/alsijil/model_extensions.py:198
 msgid "Can edit all personal notes of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:188
+#: aleksis/apps/alsijil/model_extensions.py:200
 msgid "Can view all lesson documentation of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:191
+#: aleksis/apps/alsijil/model_extensions.py:203
 msgid "Can edit all lesson documentation of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:193
+#: aleksis/apps/alsijil/model_extensions.py:205
 msgid "Can view full register of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:195
+#: aleksis/apps/alsijil/model_extensions.py:207
 msgid "Can register an absence for all members of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:197
+#: aleksis/apps/alsijil/model_extensions.py:209
+msgid "Can assign a group role for this group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:210
 msgid "Can register an absence for a person"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:388
+#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:410
 msgid "Short name"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:389
-#: aleksis/apps/alsijil/models.py:413
+#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:411
+#: aleksis/apps/alsijil/models.py:435
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:22
 msgid "Name"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:303
+#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:315
 msgid "Year"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:271
+#: aleksis/apps/alsijil/models.py:275
 msgid "Personal note"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:272
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:115
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:253
+#: aleksis/apps/alsijil/models.py:276
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:47
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:71
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:317
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:375
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:18
 msgid "Personal notes"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:315
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:150
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:108
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:237
+#: aleksis/apps/alsijil/models.py:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:263
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:342
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:26
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:381
 msgid "Lesson topic"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:316
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:158
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:109
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:243
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:289
+#: aleksis/apps/alsijil/models.py:328
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:133
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:269
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:347
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:34
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:382
 msgid "Homework"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:317
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:166
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:110
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:249
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:295
+#: aleksis/apps/alsijil/models.py:329
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:134
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:275
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:351
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:42
 msgid "Group note"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:363
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:111
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:141
+#: aleksis/apps/alsijil/models.py:376
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:17
 msgid "Lesson documentation"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:364
+#: aleksis/apps/alsijil/models.py:377
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:43
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:68
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:21
 msgid "Lesson documentations"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:400
+#: aleksis/apps/alsijil/models.py:422
 msgid "Extra mark"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:414
+#: aleksis/apps/alsijil/models.py:436
 msgid "Icon"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:415
+#: aleksis/apps/alsijil/models.py:437
 msgid "Colour"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:421 aleksis/apps/alsijil/models.py:435
+#: aleksis/apps/alsijil/models.py:443 aleksis/apps/alsijil/models.py:458
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62
 msgid "Group role"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:422
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:128
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:75
+#: aleksis/apps/alsijil/models.py:444
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:34
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9
 msgid "Group roles"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:441
+#: aleksis/apps/alsijil/models.py:448
+msgid "Can assign group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:464
 msgid "Assigned person"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:444 aleksis/apps/alsijil/tables.py:98
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:104
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:220
+#: aleksis/apps/alsijil/models.py:469 aleksis/apps/alsijil/tables.py:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:128
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:246
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:326
 msgid "Groups"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:451
+#: aleksis/apps/alsijil/models.py:476
 msgid "Can be left empty if end date is not clear yet"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:466
+#: aleksis/apps/alsijil/models.py:491
 msgid "Group role assignment"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:467
+#: aleksis/apps/alsijil/models.py:492
 msgid "Group role assignments"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:474
+#: aleksis/apps/alsijil/models.py:499
+msgid "Can view lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:500
 msgid "Can view week overview"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:475
+#: aleksis/apps/alsijil/models.py:501
+msgid "Can view full register"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:502
 msgid "Can register absence"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:476
+#: aleksis/apps/alsijil/models.py:503
 msgid "Can list all personal note filters"
 msgstr ""
 
@@ -531,16 +546,28 @@ msgid "Date"
 msgstr ""
 
 #: aleksis/apps/alsijil/tables.py:95
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:102
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:17
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126
 msgid "Period"
 msgstr ""
 
 #: aleksis/apps/alsijil/tables.py:103
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:231
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:131
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:257
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:336
 msgid "Teachers"
 msgstr ""
 
+#: aleksis/apps/alsijil/tables.py:109
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
+msgid "Tardiness"
+msgstr ""
+
 #: aleksis/apps/alsijil/tables.py:110
 msgid "Excuse"
 msgstr ""
@@ -553,7 +580,7 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:5
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:6
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:30
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:385
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:113
 msgid "Register absence"
 msgstr ""
@@ -604,13 +631,15 @@ msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:35
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:76
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:40
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:51
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:78
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90
 msgid "Students list"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:39
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:60
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:69
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:27
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:43
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:16
@@ -630,8 +659,8 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:50
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:20
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:42
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:44
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:58
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:97
 msgid "Generate printout"
 msgstr ""
 
@@ -648,107 +677,39 @@ msgstr ""
 msgid "Lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:21
-msgid "Back to week view"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:24
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:27
+msgid "Persons"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30
-msgid "My previous lesson"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:34
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:82
+msgid "Previous"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:39
-msgid "My next lesson"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:42
+msgid "More"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:51
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:187
-#, python-format
-msgid "%(period)s. period"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:75
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:81
+msgid "My previous lesson"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:86
-#, python-format
-msgid ""
-"\n"
-"            Previous %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:96
-#, python-format
-msgid ""
-"\n"
-"            Next %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:122
-msgid "Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:132
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:380
-msgid "Change history"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:186
-msgid "Overview: Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:193
-msgid "Lesson topic of previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:200
-msgid "Homework for this lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:207
-msgid "Group notes for previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:214
-msgid "Absent persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:221
-msgid "Late persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:264
-#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
-#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
-msgid "Tardiness"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:293
-msgid "Tardiness (in m)"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:399
-#, python-format
-msgid ""
-"\n"
-"              Previous %(subject)s lesson\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:92
+msgid "My next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:409
-#, python-format
-msgid ""
-"\n"
-"              Next %(subject)s lesson\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:93
+msgid "Next"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:425
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:143
 msgid ""
 "\n"
-"                This lesson overlaps with holidays and can't be edited.\n"
-"              "
+"                  This lesson overlaps with holidays and can't be edited.\n"
+"                "
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:10
@@ -793,6 +754,10 @@ msgstr ""
 msgid "Filter"
 msgstr ""
 
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:91
+msgid "Filter results"
+msgstr ""
+
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:119
 msgid "Statistics on absences, tardiness and remarks"
 msgstr ""
@@ -824,35 +789,47 @@ msgstr ""
 msgid "Students list: %(group)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:23
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:54
 msgid "Select"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:31
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:62
+msgid "Toggle filters"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:69
 #, python-format
 msgid ""
 "CW %(week)s:\n"
 "      %(instance)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:340
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:293
+msgid "Unfold"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:360
+msgid "Visit lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:398
 msgid "unexcused"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:343
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:401
 msgid "Summed up tardiness"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:346
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:404
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:92
 msgid "Count of tardiness"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:377
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:436
 msgid "No lessons available"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:380
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:439
 msgid ""
 "\n"
 "            There are no lessons for the selected group or teacher in this week.\n"
@@ -994,26 +971,95 @@ msgstr ""
 msgid "Excused absences"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:28
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:42
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:7
+#, python-format
+msgid "%(period)s. period"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:31
+#, python-format
+msgid ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  period\n"
+"          "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:8
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:135
+msgid "Save"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:19
+#, python-format
+msgid ""
+"\n"
+"        Previous %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:30
+#, python-format
+msgid ""
+"\n"
+"        Next %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html:13
+msgid "Change history"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:58
+msgid "Tardiness (in m)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:6
+msgid "Overview: Previous lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:13
+msgid "Lesson topic of previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:20
+msgid "Homework for this lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:27
+msgid "Group notes for previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:34
+msgid "Absent persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:41
+msgid "Late persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:6
 msgid "Data complete"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:12
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:25
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:17
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:30
 msgid "Missing data"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:14
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:27
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:19
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:32
 msgid "Pending"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:23
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:426
 msgid "Lesson cancelled"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:34
 msgid "Substitution"
 msgstr ""
 
@@ -1217,78 +1263,78 @@ msgstr ""
 msgid "Notes"
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:114
+#: aleksis/apps/alsijil/views.py:117
 msgid "You either selected an invalid lesson or there is currently no lesson in progress."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:147
+#: aleksis/apps/alsijil/views.py:150
 msgid "You are not allowed to create a lesson documentation for a lesson in the future."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:241
+#: aleksis/apps/alsijil/views.py:246
 msgid "The lesson documentation has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:275
+#: aleksis/apps/alsijil/views.py:280
 msgid "The personal notes have been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1031
+#: aleksis/apps/alsijil/views.py:1049
 msgid "The absence has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1052
+#: aleksis/apps/alsijil/views.py:1070
 msgid "The personal note has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1074
+#: aleksis/apps/alsijil/views.py:1092
 msgid "The extra mark has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1086
+#: aleksis/apps/alsijil/views.py:1104
 msgid "The extra mark has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1097
+#: aleksis/apps/alsijil/views.py:1115
 msgid "The extra mark has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1118
+#: aleksis/apps/alsijil/views.py:1136
 msgid "The excuse type has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1130
+#: aleksis/apps/alsijil/views.py:1148
 msgid "The excuse type has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1141
+#: aleksis/apps/alsijil/views.py:1159
 msgid "The excuse type has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1162
+#: aleksis/apps/alsijil/views.py:1180
 msgid "The group role has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1174
+#: aleksis/apps/alsijil/views.py:1192
 msgid "The group role has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1185
+#: aleksis/apps/alsijil/views.py:1203
 msgid "The group role has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1218 aleksis/apps/alsijil/views.py:1250
+#: aleksis/apps/alsijil/views.py:1236 aleksis/apps/alsijil/views.py:1268
 msgid "The group role has been assigned."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1269
+#: aleksis/apps/alsijil/views.py:1287
 msgid "The group role assignment has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1290
+#: aleksis/apps/alsijil/views.py:1308
 msgid "The group role assignment has been stopped."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1303
+#: aleksis/apps/alsijil/views.py:1321
 msgid "The group role assignment has been deleted."
 msgstr ""
diff --git a/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po
index 5be03766fc5fd2402de588d24f214fc62a8bde3a..584f38d48ce6d4426da31259eba0d5cf43c97ca9 100644
--- a/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po
+++ b/aleksis/apps/alsijil/locale/de_DE/LC_MESSAGES/django.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-28 17:33+0200\n"
-"PO-Revision-Date: 2021-08-28 15:59+0000\n"
+"POT-Creation-Date: 2021-12-24 13:24+0100\n"
+"PO-Revision-Date: 2021-12-25 20:03+0000\n"
 "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n"
 "Language-Team: German <https://translate.edugit.org/projects/aleksis/"
 "aleksis-app-alsijil/de/>\n"
@@ -17,7 +17,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4\n"
+"X-Generator: Weblate 4.8\n"
 
 #: aleksis/apps/alsijil/actions.py:18
 msgid "Mark as excused"
@@ -111,10 +111,10 @@ msgstr "Nach"
 msgid "Before"
 msgstr "Bevor"
 
-#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:293
+#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:302
 #: aleksis/apps/alsijil/tables.py:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:106
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:202
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:227
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:169
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:200
 msgid "Subject"
@@ -132,99 +132,100 @@ msgstr "Verspätung ist größer als"
 msgid "Homework for the next lesson"
 msgstr "Hausaufgabe zur nächsten Stunde"
 
-#: aleksis/apps/alsijil/forms.py:72 aleksis/apps/alsijil/forms.py:208
-#: aleksis/apps/alsijil/forms.py:292
+#: aleksis/apps/alsijil/forms.py:73 aleksis/apps/alsijil/forms.py:214
+#: aleksis/apps/alsijil/forms.py:301
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:199
 msgid "Group"
 msgstr "Gruppe"
 
-#: aleksis/apps/alsijil/forms.py:75
+#: aleksis/apps/alsijil/forms.py:79
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:170
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:201
 msgid "Teacher"
 msgstr "Lehrkraft"
 
-#: aleksis/apps/alsijil/forms.py:90
+#: aleksis/apps/alsijil/forms.py:96
 msgid "You can't select a group and a teacher both."
 msgstr "Es kann nur entweder eine Gruppe oder eine Lehrkraft ausgewählt werden."
 
-#: aleksis/apps/alsijil/forms.py:144 aleksis/apps/alsijil/forms.py:294
-#: aleksis/apps/alsijil/models.py:446
+#: aleksis/apps/alsijil/forms.py:150 aleksis/apps/alsijil/forms.py:303
+#: aleksis/apps/alsijil/models.py:471
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64
 msgid "Start date"
 msgstr "Startdatum"
 
-#: aleksis/apps/alsijil/forms.py:145 aleksis/apps/alsijil/forms.py:295
-#: aleksis/apps/alsijil/models.py:450
+#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/forms.py:304
+#: aleksis/apps/alsijil/models.py:475
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65
 msgid "End date"
 msgstr "Enddatum"
 
-#: aleksis/apps/alsijil/forms.py:146
+#: aleksis/apps/alsijil/forms.py:152
 msgid "Start period"
 msgstr "Startstunde"
 
-#: aleksis/apps/alsijil/forms.py:147
+#: aleksis/apps/alsijil/forms.py:153
 msgid "End period"
 msgstr "Endstunde"
 
-#: aleksis/apps/alsijil/forms.py:148
+#: aleksis/apps/alsijil/forms.py:154 aleksis/apps/alsijil/tables.py:108
+#: aleksis/apps/alsijil/tables.py:129
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:263
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:339
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:397
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:75
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:312
 msgid "Absent"
 msgstr "Abwesend"
 
-#: aleksis/apps/alsijil/forms.py:149 aleksis/apps/alsijil/tables.py:137
+#: aleksis/apps/alsijil/forms.py:155 aleksis/apps/alsijil/tables.py:137
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:265
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:134
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:72
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:84
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:275
 msgid "Excused"
 msgstr "Entschuldigt"
 
-#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/models.py:62
-#: aleksis/apps/alsijil/models.py:232
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:266
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:307
+#: aleksis/apps/alsijil/forms.py:157 aleksis/apps/alsijil/models.py:62
+#: aleksis/apps/alsijil/models.py:236
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:31
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:72
 msgid "Excuse type"
 msgstr "Entschuldigungsart"
 
-#: aleksis/apps/alsijil/forms.py:156
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:268
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:328
+#: aleksis/apps/alsijil/forms.py:162
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:93
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:314
 msgid "Remarks"
 msgstr "Bemerkungen"
 
-#: aleksis/apps/alsijil/forms.py:218
+#: aleksis/apps/alsijil/forms.py:227
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:9
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:262
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27
 msgid "Person"
 msgstr "Person"
 
-#: aleksis/apps/alsijil/forms.py:290
+#: aleksis/apps/alsijil/forms.py:299
 msgid "School term"
 msgstr "Schuljahr"
 
-#: aleksis/apps/alsijil/forms.py:291
+#: aleksis/apps/alsijil/forms.py:300
 msgid "Has lesson documentation"
 msgstr "Hat eine Stunden-Dokumentation"
 
-#: aleksis/apps/alsijil/managers.py:81 aleksis/apps/alsijil/tables.py:121
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:57
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:151
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:214
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:268
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:16
+#: aleksis/apps/alsijil/managers.py:88 aleksis/apps/alsijil/tables.py:121
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:176
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:240
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:316
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:50
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:21
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:335
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:415
-#: aleksis/apps/alsijil/util/alsijil_helpers.py:314
+#: aleksis/apps/alsijil/util/alsijil_helpers.py:315
 msgid "Event"
 msgstr "Veranstaltung"
 
@@ -276,12 +277,12 @@ msgstr "Alle Stunden"
 msgid "Excuse types"
 msgstr "Entschuldigungsarten"
 
-#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:237
-#: aleksis/apps/alsijil/models.py:401
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:267
+#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:241
+#: aleksis/apps/alsijil/models.py:423 aleksis/apps/alsijil/tables.py:111
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9
 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:41
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:17
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:293
 msgid "Extra marks"
@@ -291,164 +292,178 @@ msgstr "Zusätzliche Markierungen"
 msgid "Manage group roles"
 msgstr "Gruppenrollen verwalten"
 
-#: aleksis/apps/alsijil/model_extensions.py:180
+#: aleksis/apps/alsijil/model_extensions.py:191
 msgid "Can view week overview of group class register"
 msgstr "Kann Wochenübersicht des Gruppenklassenbuches sehen"
 
-#: aleksis/apps/alsijil/model_extensions.py:183
+#: aleksis/apps/alsijil/model_extensions.py:195
 msgid "Can view lesson overview of group class register"
 msgstr "Kann Stundenübersicht des Gruppenklassenbuches sehen"
 
-#: aleksis/apps/alsijil/model_extensions.py:185
+#: aleksis/apps/alsijil/model_extensions.py:197
 msgid "Can view all personal notes of a group"
 msgstr "Kann alle persönlichen Notizen einer Gruppe sehen"
 
-#: aleksis/apps/alsijil/model_extensions.py:186
+#: aleksis/apps/alsijil/model_extensions.py:198
 msgid "Can edit all personal notes of a group"
 msgstr "Kann alle persönlichen Notizen einer Gruppe bearbeiten"
 
-#: aleksis/apps/alsijil/model_extensions.py:188
+#: aleksis/apps/alsijil/model_extensions.py:200
 msgid "Can view all lesson documentation of a group"
 msgstr "Kann alle Unterrichtsdokumentationen für eine Gruppe sehen"
 
-#: aleksis/apps/alsijil/model_extensions.py:191
+#: aleksis/apps/alsijil/model_extensions.py:203
 msgid "Can edit all lesson documentation of a group"
 msgstr "Kann alle Unterrichtsdokumentationen für eine Gruppe bearbeiten"
 
-#: aleksis/apps/alsijil/model_extensions.py:193
+#: aleksis/apps/alsijil/model_extensions.py:205
 msgid "Can view full register of a group"
 msgstr "Kann komplettes Klassenbuch einer Gruppe sehen"
 
-#: aleksis/apps/alsijil/model_extensions.py:195
+#: aleksis/apps/alsijil/model_extensions.py:207
 msgid "Can register an absence for all members of a group"
 msgstr "Kann eine Absenz für alle Mitglieder eine Gruppe registrieren"
 
-#: aleksis/apps/alsijil/model_extensions.py:197
+#: aleksis/apps/alsijil/model_extensions.py:209
+msgid "Can assign a group role for this group"
+msgstr "Kann eine Gruppenrolle für diese Gruppe zuweisen"
+
+#: aleksis/apps/alsijil/model_extensions.py:210
 msgid "Can register an absence for a person"
 msgstr "Kann eine Absenz für eine Person registrieren"
 
-#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:388
+#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:410
 msgid "Short name"
 msgstr "Kurzname"
 
-#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:389
-#: aleksis/apps/alsijil/models.py:413
+#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:411
+#: aleksis/apps/alsijil/models.py:435
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:22
 msgid "Name"
 msgstr "Name"
 
-#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:303
+#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:315
 msgid "Year"
 msgstr "Jahr"
 
-#: aleksis/apps/alsijil/models.py:271
+#: aleksis/apps/alsijil/models.py:275
 msgid "Personal note"
 msgstr "Persönliche Notiz"
 
-#: aleksis/apps/alsijil/models.py:272
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:115
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:253
+#: aleksis/apps/alsijil/models.py:276
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:47
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:71
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:317
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:375
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:18
 msgid "Personal notes"
 msgstr "Persönliche Notizen"
 
-#: aleksis/apps/alsijil/models.py:315
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:150
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:108
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:237
+#: aleksis/apps/alsijil/models.py:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:263
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:342
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:26
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:381
 msgid "Lesson topic"
 msgstr "Stundenthema"
 
-#: aleksis/apps/alsijil/models.py:316
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:158
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:109
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:243
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:289
+#: aleksis/apps/alsijil/models.py:328
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:133
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:269
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:347
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:34
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:382
 msgid "Homework"
 msgstr "Hausaufgaben"
 
-#: aleksis/apps/alsijil/models.py:317
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:166
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:110
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:249
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:295
+#: aleksis/apps/alsijil/models.py:329
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:134
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:275
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:351
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:42
 msgid "Group note"
 msgstr "Gruppennotiz"
 
-#: aleksis/apps/alsijil/models.py:363
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:111
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:141
+#: aleksis/apps/alsijil/models.py:376
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:17
 msgid "Lesson documentation"
 msgstr "Stunden-Dokumentation"
 
-#: aleksis/apps/alsijil/models.py:364
+#: aleksis/apps/alsijil/models.py:377
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:43
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:68
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:21
 msgid "Lesson documentations"
 msgstr "Stunden-Dokumentationen"
 
-#: aleksis/apps/alsijil/models.py:400
+#: aleksis/apps/alsijil/models.py:422
 msgid "Extra mark"
 msgstr "Zusätzliche Markierung"
 
-#: aleksis/apps/alsijil/models.py:414
+#: aleksis/apps/alsijil/models.py:436
 msgid "Icon"
 msgstr "Symbol"
 
-#: aleksis/apps/alsijil/models.py:415
+#: aleksis/apps/alsijil/models.py:437
 msgid "Colour"
 msgstr "Farbe"
 
-#: aleksis/apps/alsijil/models.py:421 aleksis/apps/alsijil/models.py:435
+#: aleksis/apps/alsijil/models.py:443 aleksis/apps/alsijil/models.py:458
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62
 msgid "Group role"
 msgstr "Gruppenrolle"
 
-#: aleksis/apps/alsijil/models.py:422
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:128
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:75
+#: aleksis/apps/alsijil/models.py:444
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:34
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9
 msgid "Group roles"
 msgstr "Gruppenrollen"
 
-#: aleksis/apps/alsijil/models.py:441
+#: aleksis/apps/alsijil/models.py:448
+msgid "Can assign group role"
+msgstr "Kann Gruppenrolle zuweisen"
+
+#: aleksis/apps/alsijil/models.py:464
 msgid "Assigned person"
 msgstr "Zugewiesene Person"
 
-#: aleksis/apps/alsijil/models.py:444 aleksis/apps/alsijil/tables.py:98
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:104
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:220
+#: aleksis/apps/alsijil/models.py:469 aleksis/apps/alsijil/tables.py:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:128
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:246
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:326
 msgid "Groups"
 msgstr "Gruppen"
 
-#: aleksis/apps/alsijil/models.py:451
+#: aleksis/apps/alsijil/models.py:476
 msgid "Can be left empty if end date is not clear yet"
 msgstr "Kann frei gelassen werden, wenn das Enddatum noch nicht feststeht"
 
-#: aleksis/apps/alsijil/models.py:466
+#: aleksis/apps/alsijil/models.py:491
 msgid "Group role assignment"
 msgstr "Zuweisung von Gruppenrollen"
 
-#: aleksis/apps/alsijil/models.py:467
+#: aleksis/apps/alsijil/models.py:492
 msgid "Group role assignments"
 msgstr "Zuweisungen von Gruppenrollen"
 
-#: aleksis/apps/alsijil/models.py:474
+#: aleksis/apps/alsijil/models.py:499
+msgid "Can view lesson overview"
+msgstr "Kann die Stundenübersicht sehen"
+
+#: aleksis/apps/alsijil/models.py:500
 msgid "Can view week overview"
 msgstr "Kann die Wochenübersicht sehen"
 
-#: aleksis/apps/alsijil/models.py:475
+#: aleksis/apps/alsijil/models.py:501
+msgid "Can view full register"
+msgstr "Kann komplettes Klassenbuch sehen"
+
+#: aleksis/apps/alsijil/models.py:502
 msgid "Can register absence"
 msgstr "Kann eine Absenz registrieren"
 
-#: aleksis/apps/alsijil/models.py:476
+#: aleksis/apps/alsijil/models.py:503
 msgid "Can list all personal note filters"
 msgstr "Kann alle Filter für persönliche Notizen anzeigen"
 
@@ -532,16 +547,28 @@ msgid "Date"
 msgstr "Datum"
 
 #: aleksis/apps/alsijil/tables.py:95
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:102
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:17
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126
 msgid "Period"
 msgstr "Stunde"
 
 #: aleksis/apps/alsijil/tables.py:103
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:231
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:131
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:257
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:336
 msgid "Teachers"
 msgstr "Lehrkräfte"
 
+#: aleksis/apps/alsijil/tables.py:109
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
+msgid "Tardiness"
+msgstr "Verspätung"
+
 #: aleksis/apps/alsijil/tables.py:110
 msgid "Excuse"
 msgstr "Entschuldigen"
@@ -554,7 +581,7 @@ msgstr "{value}' verspätet"
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:5
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:6
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:30
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:385
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:113
 msgid "Register absence"
 msgstr "Abwesenheit eintragen"
@@ -615,13 +642,15 @@ msgstr "Schülerinnen und Schüler"
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:35
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:76
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:40
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:51
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:78
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90
 msgid "Students list"
 msgstr "Liste der Schülerinnen und Schüler"
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:39
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:60
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:69
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:27
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:43
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:16
@@ -641,8 +670,8 @@ msgstr "Rollen"
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:50
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:20
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:42
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:44
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:58
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:97
 msgid "Generate printout"
 msgstr "Ausdruck generieren"
 
@@ -659,123 +688,44 @@ msgstr "Schülerinnen und Schüler"
 msgid "Lesson"
 msgstr "Unterrichtsstunde"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:21
-msgid "Back to week view"
-msgstr "Zurück zur Wochenübersicht"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:24
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:27
+msgid "Persons"
+msgstr "Personen"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:34
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:82
+msgid "Previous"
+msgstr "Vorherige"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:42
+msgid "More"
+msgstr "Mehr"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:75
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:81
 msgid "My previous lesson"
 msgstr "Meine vorherige Stunde"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:39
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:86
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:92
 msgid "My next lesson"
 msgstr "Meine nächste Stunde"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:51
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:187
-#, python-format
-msgid "%(period)s. period"
-msgstr "%(period)s. Stunde"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:86
-#, python-format
-msgid ""
-"\n"
-"            Previous %(subject)s lesson\n"
-"          "
-msgstr ""
-"\n"
-"            Vorherige %(subject)s-Stunde\n"
-"          "
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:96
-#, python-format
-msgid ""
-"\n"
-"            Next %(subject)s lesson\n"
-"          "
-msgstr ""
-"\n"
-"            Nächste %(subject)s-Stunde\n"
-"          "
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:122
-msgid "Previous lesson"
-msgstr "Vorherige Unterrichtsstunde"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:132
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:380
-msgid "Change history"
-msgstr "Veränderungen"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:186
-msgid "Overview: Previous lesson"
-msgstr "Übersicht: Vorherige Stunde"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:193
-msgid "Lesson topic of previous lesson:"
-msgstr "Stundenthema der vorherigen Stunde:"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:200
-msgid "Homework for this lesson:"
-msgstr "Hausaufgaben zu dieser Stunde:"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:207
-msgid "Group notes for previous lesson:"
-msgstr "Gruppennotizen für die vorherige Stunde:"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:214
-msgid "Absent persons:"
-msgstr "Abwesende Personen:"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:221
-msgid "Late persons:"
-msgstr "Verspätete Personen:"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:264
-#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
-#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
-msgid "Tardiness"
-msgstr "Verspätung"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:293
-msgid "Tardiness (in m)"
-msgstr "Verspätung (in m)"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:399
-#, python-format
-msgid ""
-"\n"
-"              Previous %(subject)s lesson\n"
-"            "
-msgstr ""
-"\n"
-"              Vorherige %(subject)s Stunde\n"
-"            "
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:409
-#, python-format
-msgid ""
-"\n"
-"              Next %(subject)s lesson\n"
-"            "
-msgstr ""
-"\n"
-"              Nächste %(subject)s Stunde\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:93
+msgid "Next"
+msgstr "Nächste"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:425
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:143
 msgid ""
 "\n"
-"                This lesson overlaps with holidays and can't be edited.\n"
-"              "
+"                  This lesson overlaps with holidays and can't be edited.\n"
+"                "
 msgstr ""
 "\n"
-"                Diese Stunde ist in den Ferien und kann somit nicht bearbeitet werden.\n"
-"              "
+"                  Diese Stunde ist in den Ferien und kann somit nicht "
+"bearbeitet werden.\n"
+"                "
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:10
 msgid "Class register: person"
@@ -822,6 +772,10 @@ msgstr "Schließen"
 msgid "Filter"
 msgstr "Filtern"
 
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:91
+msgid "Filter results"
+msgstr "Ergebnisse filtern"
+
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:119
 msgid "Statistics on absences, tardiness and remarks"
 msgstr "Statistiken zu Fehlzeiten, Verspätungen und Bemerkungen"
@@ -853,11 +807,15 @@ msgstr "Unentschuldigt"
 msgid "Students list: %(group)s"
 msgstr "Liste der Schülerinnen und Schüler: %(group)s"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:23
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:54
 msgid "Select"
 msgstr "Auswählen"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:31
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:62
+msgid "Toggle filters"
+msgstr "Filter umschalten"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:69
 #, python-format
 msgid ""
 "CW %(week)s:\n"
@@ -866,24 +824,32 @@ msgstr ""
 "KW %(week)s: \n"
 "%(instance)s"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:340
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:293
+msgid "Unfold"
+msgstr "Ausklappen"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:360
+msgid "Visit lesson overview"
+msgstr "Stundenübersicht besuchen"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:398
 msgid "unexcused"
 msgstr "unentschuldigt"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:343
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:401
 msgid "Summed up tardiness"
 msgstr "Summierte Verspätung"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:346
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:404
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:92
 msgid "Count of tardiness"
 msgstr "Anzahl der Verspätungen"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:377
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:436
 msgid "No lessons available"
 msgstr "Keine Stunden verfügbar"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:380
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:439
 msgid ""
 "\n"
 "            There are no lessons for the selected group or teacher in this week.\n"
@@ -913,11 +879,8 @@ msgid ""
 "  "
 msgstr ""
 "\n"
-"    Diese Funktion sollte nur benutzt werden, um Alternativen zur normalen "
-"Entschuldigung, welche von sich aus extra gezählt wird, zu definieren.\n"
-"Benutzen Sie diese Funktion nicht, um eine Entschuldigungsart für normale "
-"Entschuldigungen zu erstellen oder wenn Sie nicht zwischen verschiedenen "
-"Entschuldigungsarten unterscheiden möchten.\n"
+"    Diese Funktion sollte nur benutzt werden, um Alternativen zur normalen Entschuldigung, welche von sich aus extra gezählt wird, zu definieren.\n"
+"Benutzen Sie diese Funktion nicht, um eine Entschuldigungsart für normale Entschuldigungen zu erstellen oder wenn Sie nicht zwischen verschiedenen Entschuldigungsarten unterscheiden möchten.\n"
 "  "
 
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6
@@ -996,8 +959,7 @@ msgid ""
 "  "
 msgstr ""
 "\n"
-"    Sie können zusätzliche Aktionen für jede Gruppenrollenzuweisung "
-"aufrufen, \n"
+"    Sie können zusätzliche Aktionen für jede Gruppenrollenzuweisung aufrufen, \n"
 "wenn Sie auf den Namen der entsprechenden Person klicken.\n"
 "  "
 
@@ -1040,26 +1002,104 @@ msgstr "Unentschuldigte Fehlzeiten"
 msgid "Excused absences"
 msgstr "Entschuldigte Fehlzeiten"
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:28
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:42
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:7
+#, python-format
+msgid "%(period)s. period"
+msgstr "%(period)s. Stunde"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:31
+#, python-format
+msgid ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  period\n"
+"          "
+msgstr ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  Stunde\n"
+"          "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:8
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:135
+msgid "Save"
+msgstr "Speichern"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:19
+#, python-format
+msgid ""
+"\n"
+"        Previous %(subject)s lesson\n"
+"      "
+msgstr ""
+"\n"
+"        Vorherige %(subject)s Stunde\n"
+"      "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:30
+#, python-format
+msgid ""
+"\n"
+"        Next %(subject)s lesson\n"
+"      "
+msgstr ""
+"\n"
+"        Nächste %(subject)s Stunde\n"
+"      "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html:13
+msgid "Change history"
+msgstr "Veränderungen"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:58
+msgid "Tardiness (in m)"
+msgstr "Verspätung (in m)"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:6
+msgid "Overview: Previous lesson"
+msgstr "Übersicht: Vorherige Stunde"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:13
+msgid "Lesson topic of previous lesson:"
+msgstr "Stundenthema der vorherigen Stunde:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:20
+msgid "Homework for this lesson:"
+msgstr "Hausaufgaben zu dieser Stunde:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:27
+msgid "Group notes for previous lesson:"
+msgstr "Gruppennotizen für die vorherige Stunde:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:34
+msgid "Absent persons:"
+msgstr "Abwesende Personen:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:41
+msgid "Late persons:"
+msgstr "Verspätete Personen:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:6
 msgid "Data complete"
 msgstr "Daten vollständig"
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:12
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:25
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:17
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:30
 msgid "Missing data"
 msgstr "Fehlende Daten"
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:14
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:27
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:19
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:32
 msgid "Pending"
 msgstr "Findet gerade statt"
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:23
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:426
 msgid "Lesson cancelled"
 msgstr "Stunde ist ausgefallen"
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:34
 msgid "Substitution"
 msgstr "Vertretung"
 
@@ -1277,84 +1317,117 @@ msgstr "KW"
 msgid "Notes"
 msgstr "Notizen"
 
-#: aleksis/apps/alsijil/views.py:114
+#: aleksis/apps/alsijil/views.py:117
 msgid "You either selected an invalid lesson or there is currently no lesson in progress."
 msgstr ""
 "Sie haben eine ungültige Stunde ausgewählt oder es\n"
 "      läuft momentan keine Stunde."
 
-#: aleksis/apps/alsijil/views.py:147
+#: aleksis/apps/alsijil/views.py:150
 msgid "You are not allowed to create a lesson documentation for a lesson in the future."
 msgstr "Ihnen ist es nicht erlaubt, eine Eintragung für eine Unterrichtsstunde in der Zukunft vorzunehmen."
 
-#: aleksis/apps/alsijil/views.py:241
+#: aleksis/apps/alsijil/views.py:246
 msgid "The lesson documentation has been saved."
 msgstr "Die Stunden-Dokumentation wurde gespeichert."
 
-#: aleksis/apps/alsijil/views.py:275
+#: aleksis/apps/alsijil/views.py:280
 msgid "The personal notes have been saved."
 msgstr "Die persönlichen Notizen wurden gespeichert."
 
-#: aleksis/apps/alsijil/views.py:1031
+#: aleksis/apps/alsijil/views.py:1049
 msgid "The absence has been saved."
 msgstr "Die Abwesenheit wurde gespeichert."
 
-#: aleksis/apps/alsijil/views.py:1052
+#: aleksis/apps/alsijil/views.py:1070
 msgid "The personal note has been deleted."
 msgstr "Die persönliche Notiz wurde gelöscht."
 
-#: aleksis/apps/alsijil/views.py:1074
+#: aleksis/apps/alsijil/views.py:1092
 msgid "The extra mark has been created."
 msgstr "Die zusätzliche Markierung wurde erstellt."
 
-#: aleksis/apps/alsijil/views.py:1086
+#: aleksis/apps/alsijil/views.py:1104
 msgid "The extra mark has been saved."
 msgstr "Die zusätzliche Markierung wurde gespeichert."
 
-#: aleksis/apps/alsijil/views.py:1097
+#: aleksis/apps/alsijil/views.py:1115
 msgid "The extra mark has been deleted."
 msgstr "Die zusätzliche Markierung wurde gelöscht."
 
-#: aleksis/apps/alsijil/views.py:1118
+#: aleksis/apps/alsijil/views.py:1136
 msgid "The excuse type has been created."
 msgstr "Die Entschuldigungsart wurde erstellt."
 
-#: aleksis/apps/alsijil/views.py:1130
+#: aleksis/apps/alsijil/views.py:1148
 msgid "The excuse type has been saved."
 msgstr "Die Entschuldigunsart wurde gespeichert."
 
-#: aleksis/apps/alsijil/views.py:1141
+#: aleksis/apps/alsijil/views.py:1159
 msgid "The excuse type has been deleted."
 msgstr "Die Entschuldigungsart wurde gelöscht."
 
-#: aleksis/apps/alsijil/views.py:1162
+#: aleksis/apps/alsijil/views.py:1180
 msgid "The group role has been created."
 msgstr "Die Gruppenrolle wurde erstellt."
 
-#: aleksis/apps/alsijil/views.py:1174
+#: aleksis/apps/alsijil/views.py:1192
 msgid "The group role has been saved."
 msgstr "Die Gruppenrolle wurde gespeichert."
 
-#: aleksis/apps/alsijil/views.py:1185
+#: aleksis/apps/alsijil/views.py:1203
 msgid "The group role has been deleted."
 msgstr "Die Gruppenrolle wurde gelöscht."
 
-#: aleksis/apps/alsijil/views.py:1218 aleksis/apps/alsijil/views.py:1250
+#: aleksis/apps/alsijil/views.py:1236 aleksis/apps/alsijil/views.py:1268
 msgid "The group role has been assigned."
 msgstr "Die Gruppenrolle wurde zugewiesen."
 
-#: aleksis/apps/alsijil/views.py:1269
+#: aleksis/apps/alsijil/views.py:1287
 msgid "The group role assignment has been saved."
 msgstr "Die Gruppenrollenzuweisung wurde gespeichert."
 
-#: aleksis/apps/alsijil/views.py:1290
+#: aleksis/apps/alsijil/views.py:1308
 msgid "The group role assignment has been stopped."
 msgstr "Die Gruppenrollenzuweisung wurde beendet."
 
-#: aleksis/apps/alsijil/views.py:1303
+#: aleksis/apps/alsijil/views.py:1321
 msgid "The group role assignment has been deleted."
 msgstr "Die Gruppenrollenzuweisung wurde gelöscht."
 
+#~ msgid "Back to week view"
+#~ msgstr "Zurück zur Wochenübersicht"
+
+#, python-format
+#~ msgid ""
+#~ "\n"
+#~ "            Next %(subject)s lesson\n"
+#~ "          "
+#~ msgstr ""
+#~ "\n"
+#~ "            Nächste %(subject)s-Stunde\n"
+#~ "          "
+
+#, python-format
+#~ msgid ""
+#~ "\n"
+#~ "              Previous %(subject)s lesson\n"
+#~ "            "
+#~ msgstr ""
+#~ "\n"
+#~ "              Vorherige %(subject)s Stunde\n"
+#~ "            "
+
+#, python-format
+#~ msgid ""
+#~ "\n"
+#~ "              Next %(subject)s lesson\n"
+#~ "            "
+#~ msgstr ""
+#~ "\n"
+#~ "              Nächste %(subject)s Stunde\n"
+#~ "            "
+
 #~ msgid "Delete note"
 #~ msgstr "Notiz löschen"
 
@@ -1388,24 +1461,6 @@ msgstr "Die Gruppenrollenzuweisung wurde gelöscht."
 #~ msgid "Lesson documentation for week"
 #~ msgstr "Unterrichtsdokumentation für Woche"
 
-#~ msgid ""
-#~ "\n"
-#~ "          Previous %(subject)s lesson\n"
-#~ "        "
-#~ msgstr ""
-#~ "\n"
-#~ "          Vorherige %(subject)s Stunde\n"
-#~ "        "
-
-#~ msgid ""
-#~ "\n"
-#~ "          Next %(subject)s lesson\n"
-#~ "        "
-#~ msgstr ""
-#~ "\n"
-#~ "          Nächste %(subject)s Stunde\n"
-#~ "        "
-
 #~ msgid "There is no current school term."
 #~ msgstr "Es gibt aktuell kein Schuljahr."
 
@@ -1445,9 +1500,6 @@ msgstr "Die Gruppenrollenzuweisung wurde gelöscht."
 #~ msgid "No group selected"
 #~ msgstr "Keine Gruppe ausgewählt"
 
-#~ msgid "Save"
-#~ msgstr "Speichern"
-
 #, fuzzy
 #~| msgid "Current lesson"
 #~ msgid "Starting lesson"
diff --git a/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po
index abffdb41cdf1c23f9ab05a7ca1b612ef9d1a4db1..d25ac9f4f0bdc1613df656adab70a6add98209d2 100644
--- a/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po
+++ b/aleksis/apps/alsijil/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-28 17:33+0200\n"
+"POT-Creation-Date: 2021-12-24 13:24+0100\n"
 "PO-Revision-Date: 2021-06-16 11:59+0000\n"
 "Last-Translator: Jonathan Weth <teckids@jonathanweth.de>\n"
 "Language-Team: French <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/fr/>\n"
@@ -122,10 +122,10 @@ msgstr ""
 msgid "Before"
 msgstr ""
 
-#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:293
+#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:302
 #: aleksis/apps/alsijil/tables.py:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:106
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:202
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:227
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:169
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:200
 msgid "Subject"
@@ -147,107 +147,108 @@ msgstr "Retard"
 msgid "Homework for the next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:72 aleksis/apps/alsijil/forms.py:208
-#: aleksis/apps/alsijil/forms.py:292
+#: aleksis/apps/alsijil/forms.py:73 aleksis/apps/alsijil/forms.py:214
+#: aleksis/apps/alsijil/forms.py:301
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:199
 msgid "Group"
 msgstr "groupe"
 
-#: aleksis/apps/alsijil/forms.py:75
+#: aleksis/apps/alsijil/forms.py:79
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:170
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:201
 msgid "Teacher"
 msgstr "prof"
 
-#: aleksis/apps/alsijil/forms.py:90
+#: aleksis/apps/alsijil/forms.py:96
 msgid "You can't select a group and a teacher both."
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:144 aleksis/apps/alsijil/forms.py:294
-#: aleksis/apps/alsijil/models.py:446
+#: aleksis/apps/alsijil/forms.py:150 aleksis/apps/alsijil/forms.py:303
+#: aleksis/apps/alsijil/models.py:471
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64
 msgid "Start date"
 msgstr "Date de début"
 
-#: aleksis/apps/alsijil/forms.py:145 aleksis/apps/alsijil/forms.py:295
-#: aleksis/apps/alsijil/models.py:450
+#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/forms.py:304
+#: aleksis/apps/alsijil/models.py:475
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65
 msgid "End date"
 msgstr "Date de fin"
 
-#: aleksis/apps/alsijil/forms.py:146
+#: aleksis/apps/alsijil/forms.py:152
 #, fuzzy
 #| msgid "From period"
 msgid "Start period"
 msgstr "De la période"
 
-#: aleksis/apps/alsijil/forms.py:147
+#: aleksis/apps/alsijil/forms.py:153
 #, fuzzy
 #| msgid "From period"
 msgid "End period"
 msgstr "De la période"
 
-#: aleksis/apps/alsijil/forms.py:148
+#: aleksis/apps/alsijil/forms.py:154 aleksis/apps/alsijil/tables.py:108
+#: aleksis/apps/alsijil/tables.py:129
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:263
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:339
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:397
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:75
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:312
 msgid "Absent"
 msgstr "Absent(e)"
 
-#: aleksis/apps/alsijil/forms.py:149 aleksis/apps/alsijil/tables.py:137
+#: aleksis/apps/alsijil/forms.py:155 aleksis/apps/alsijil/tables.py:137
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:265
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:134
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:72
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:84
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:275
 msgid "Excused"
 msgstr "Excusé"
 
-#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/models.py:62
-#: aleksis/apps/alsijil/models.py:232
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:266
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:307
+#: aleksis/apps/alsijil/forms.py:157 aleksis/apps/alsijil/models.py:62
+#: aleksis/apps/alsijil/models.py:236
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:31
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:72
 #, fuzzy
 #| msgid "Excused"
 msgid "Excuse type"
 msgstr "Excusé"
 
-#: aleksis/apps/alsijil/forms.py:156
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:268
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:328
+#: aleksis/apps/alsijil/forms.py:162
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:93
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:314
 msgid "Remarks"
 msgstr "Remarque"
 
-#: aleksis/apps/alsijil/forms.py:218
+#: aleksis/apps/alsijil/forms.py:227
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:9
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:262
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27
 msgid "Person"
 msgstr "Personne"
 
-#: aleksis/apps/alsijil/forms.py:290
+#: aleksis/apps/alsijil/forms.py:299
 msgid "School term"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:291
+#: aleksis/apps/alsijil/forms.py:300
 #, fuzzy
 #| msgid "Lesson documentation"
 msgid "Has lesson documentation"
 msgstr "Documentation de cours"
 
-#: aleksis/apps/alsijil/managers.py:81 aleksis/apps/alsijil/tables.py:121
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:57
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:151
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:214
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:268
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:16
+#: aleksis/apps/alsijil/managers.py:88 aleksis/apps/alsijil/tables.py:121
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:176
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:240
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:316
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:50
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:21
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:335
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:415
-#: aleksis/apps/alsijil/util/alsijil_helpers.py:314
+#: aleksis/apps/alsijil/util/alsijil_helpers.py:315
 msgid "Event"
 msgstr ""
 
@@ -307,12 +308,12 @@ msgstr ""
 msgid "Excuse types"
 msgstr "Excusé"
 
-#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:237
-#: aleksis/apps/alsijil/models.py:401
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:267
+#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:241
+#: aleksis/apps/alsijil/models.py:423 aleksis/apps/alsijil/tables.py:111
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9
 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:41
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:17
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:293
 msgid "Extra marks"
@@ -322,148 +323,149 @@ msgstr ""
 msgid "Manage group roles"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:180
+#: aleksis/apps/alsijil/model_extensions.py:191
 msgid "Can view week overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:183
+#: aleksis/apps/alsijil/model_extensions.py:195
 msgid "Can view lesson overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:185
+#: aleksis/apps/alsijil/model_extensions.py:197
 #, fuzzy
 #| msgid "List of all personal note filters"
 msgid "Can view all personal notes of a group"
 msgstr "Liste de filtres de notes personnelles"
 
-#: aleksis/apps/alsijil/model_extensions.py:186
+#: aleksis/apps/alsijil/model_extensions.py:198
 #, fuzzy
 #| msgid "List of all personal note filters"
 msgid "Can edit all personal notes of a group"
 msgstr "Liste de filtres de notes personnelles"
 
-#: aleksis/apps/alsijil/model_extensions.py:188
+#: aleksis/apps/alsijil/model_extensions.py:200
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "Can view all lesson documentation of a group"
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/model_extensions.py:191
+#: aleksis/apps/alsijil/model_extensions.py:203
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "Can edit all lesson documentation of a group"
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/model_extensions.py:193
+#: aleksis/apps/alsijil/model_extensions.py:205
 msgid "Can view full register of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:195
+#: aleksis/apps/alsijil/model_extensions.py:207
 msgid "Can register an absence for all members of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:197
+#: aleksis/apps/alsijil/model_extensions.py:209
+msgid "Can assign a group role for this group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:210
 #, fuzzy
 #| msgid "Class register"
 msgid "Can register an absence for a person"
 msgstr "Registre de la classe"
 
-#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:388
+#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:410
 #, fuzzy
 #| msgid "First name"
 msgid "Short name"
 msgstr "Prénom"
 
-#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:389
-#: aleksis/apps/alsijil/models.py:413
+#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:411
+#: aleksis/apps/alsijil/models.py:435
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:22
 msgid "Name"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:303
+#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:315
 msgid "Year"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:271
+#: aleksis/apps/alsijil/models.py:275
 #, fuzzy
 #| msgid "Personal notes"
 msgid "Personal note"
 msgstr "Notes personnelles"
 
-#: aleksis/apps/alsijil/models.py:272
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:115
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:253
+#: aleksis/apps/alsijil/models.py:276
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:47
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:71
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:317
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:375
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:18
 msgid "Personal notes"
 msgstr "Notes personnelles"
 
-#: aleksis/apps/alsijil/models.py:315
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:150
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:108
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:237
+#: aleksis/apps/alsijil/models.py:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:263
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:342
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:26
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:381
 msgid "Lesson topic"
 msgstr "Sujet de cours"
 
-#: aleksis/apps/alsijil/models.py:316
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:158
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:109
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:243
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:289
+#: aleksis/apps/alsijil/models.py:328
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:133
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:269
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:347
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:34
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:382
 msgid "Homework"
 msgstr "Devoirs"
 
-#: aleksis/apps/alsijil/models.py:317
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:166
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:110
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:249
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:295
+#: aleksis/apps/alsijil/models.py:329
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:134
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:275
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:351
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:42
 #, fuzzy
 #| msgid "Group"
 msgid "Group note"
 msgstr "Groupe"
 
-#: aleksis/apps/alsijil/models.py:363
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:111
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:141
+#: aleksis/apps/alsijil/models.py:376
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:17
 msgid "Lesson documentation"
 msgstr "Documentation de cours"
 
-#: aleksis/apps/alsijil/models.py:364
+#: aleksis/apps/alsijil/models.py:377
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:43
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:68
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:21
 #, fuzzy
 #| msgid "Lesson documentation"
 msgid "Lesson documentations"
 msgstr "Documentation de cours"
 
-#: aleksis/apps/alsijil/models.py:400
+#: aleksis/apps/alsijil/models.py:422
 msgid "Extra mark"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:414
+#: aleksis/apps/alsijil/models.py:436
 msgid "Icon"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:415
+#: aleksis/apps/alsijil/models.py:437
 msgid "Colour"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:421 aleksis/apps/alsijil/models.py:435
+#: aleksis/apps/alsijil/models.py:443 aleksis/apps/alsijil/models.py:458
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62
 #, fuzzy
 #| msgid "Group"
 msgid "Group role"
 msgstr "Groupe"
 
-#: aleksis/apps/alsijil/models.py:422
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:128
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:75
+#: aleksis/apps/alsijil/models.py:444
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:34
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9
 #, fuzzy
@@ -471,43 +473,62 @@ msgstr "Groupe"
 msgid "Group roles"
 msgstr "Groupe"
 
-#: aleksis/apps/alsijil/models.py:441
+#: aleksis/apps/alsijil/models.py:448
+#, fuzzy
+#| msgid "Persons in group"
+msgid "Can assign group role"
+msgstr "Personnes en groupe"
+
+#: aleksis/apps/alsijil/models.py:464
 #, fuzzy
 #| msgid "Absences"
 msgid "Assigned person"
 msgstr "Absences"
 
-#: aleksis/apps/alsijil/models.py:444 aleksis/apps/alsijil/tables.py:98
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:104
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:220
+#: aleksis/apps/alsijil/models.py:469 aleksis/apps/alsijil/tables.py:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:128
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:246
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:326
 #, fuzzy
 #| msgid "Group"
 msgid "Groups"
 msgstr "Groupe"
 
-#: aleksis/apps/alsijil/models.py:451
+#: aleksis/apps/alsijil/models.py:476
 msgid "Can be left empty if end date is not clear yet"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:466
+#: aleksis/apps/alsijil/models.py:491
 msgid "Group role assignment"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:467
+#: aleksis/apps/alsijil/models.py:492
 msgid "Group role assignments"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:474
+#: aleksis/apps/alsijil/models.py:499
+#, fuzzy
+#| msgid "Personal overview"
+msgid "Can view lesson overview"
+msgstr "Vue d'ensemble personnelle"
+
+#: aleksis/apps/alsijil/models.py:500
 msgid "Can view week overview"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:475
+#: aleksis/apps/alsijil/models.py:501
+#, fuzzy
+#| msgid "Class register"
+msgid "Can view full register"
+msgstr "Registre de la classe"
+
+#: aleksis/apps/alsijil/models.py:502
 #, fuzzy
 #| msgid "Register absence"
 msgid "Can register absence"
 msgstr "Registre de Absence"
 
-#: aleksis/apps/alsijil/models.py:476
+#: aleksis/apps/alsijil/models.py:503
 #, fuzzy
 #| msgid "List of all personal note filters"
 msgid "Can list all personal note filters"
@@ -595,16 +616,28 @@ msgid "Date"
 msgstr "Date"
 
 #: aleksis/apps/alsijil/tables.py:95
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:102
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:17
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126
 msgid "Period"
 msgstr "Période"
 
 #: aleksis/apps/alsijil/tables.py:103
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:231
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:131
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:257
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:336
 msgid "Teachers"
 msgstr "Profs"
 
+#: aleksis/apps/alsijil/tables.py:109
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
+msgid "Tardiness"
+msgstr "Retard"
+
 #: aleksis/apps/alsijil/tables.py:110
 #, fuzzy
 #| msgid "Excused"
@@ -619,7 +652,7 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:5
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:6
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:30
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:385
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:113
 msgid "Register absence"
 msgstr "Registre de Absence"
@@ -680,13 +713,15 @@ msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:35
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:76
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:40
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:51
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:78
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90
 msgid "Students list"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:39
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:60
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:69
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:27
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:43
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:16
@@ -706,8 +741,8 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:50
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:20
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:42
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:44
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:58
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:97
 msgid "Generate printout"
 msgstr ""
 
@@ -724,116 +759,43 @@ msgstr ""
 msgid "Lesson"
 msgstr "Cours"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:21
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:24
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:27
 #, fuzzy
-#| msgid "Week view"
-msgid "Back to week view"
-msgstr "Vue de semaine"
+#| msgid "Person"
+msgid "Persons"
+msgstr "Personne"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:34
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:82
 #, fuzzy
 #| msgid "Current lesson"
-msgid "My previous lesson"
+msgid "Previous"
 msgstr "Lecon actuelle"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:39
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:42
+msgid "More"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:75
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:81
 #, fuzzy
 #| msgid "Current lesson"
-msgid "My next lesson"
+msgid "My previous lesson"
 msgstr "Lecon actuelle"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:51
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:187
-#, fuzzy, python-format
-#| msgid "From period"
-msgid "%(period)s. period"
-msgstr "De la période"
-
 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:86
-#, python-format
-msgid ""
-"\n"
-"            Previous %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:96
-#, python-format
-msgid ""
-"\n"
-"            Next %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:122
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:92
 #, fuzzy
 #| msgid "Current lesson"
-msgid "Previous lesson"
+msgid "My next lesson"
 msgstr "Lecon actuelle"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:132
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:380
-msgid "Change history"
-msgstr "Changement d' histoire"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:186
-msgid "Overview: Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:193
-msgid "Lesson topic of previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:200
-msgid "Homework for this lesson:"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:93
+msgid "Next"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:207
-msgid "Group notes for previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:214
-#, fuzzy
-#| msgid "Absences"
-msgid "Absent persons:"
-msgstr "Absences"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:221
-msgid "Late persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:264
-#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
-#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
-msgid "Tardiness"
-msgstr "Retard"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:293
-#, fuzzy
-#| msgid "Tardiness"
-msgid "Tardiness (in m)"
-msgstr "Retard"
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:399
-#, python-format
-msgid ""
-"\n"
-"              Previous %(subject)s lesson\n"
-"            "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:409
-#, python-format
-msgid ""
-"\n"
-"              Next %(subject)s lesson\n"
-"            "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:425
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:143
 #, fuzzy
 #| msgid ""
 #| "\n"
@@ -841,8 +803,8 @@ msgstr ""
 #| "          "
 msgid ""
 "\n"
-"                This lesson overlaps with holidays and can't be edited.\n"
-"              "
+"                  This lesson overlaps with holidays and can't be edited.\n"
+"                "
 msgstr ""
 "\n"
 "            Il n' y a pas des cours pour le groupe sélectionné, les profs, le salle ou le temps.\n"
@@ -896,6 +858,12 @@ msgstr ""
 msgid "Filter"
 msgstr ""
 
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:91
+#, fuzzy
+#| msgid "Relevant personal notes"
+msgid "Filter results"
+msgstr "Notes personnelles importantes"
+
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:119
 msgid "Statistics on absences, tardiness and remarks"
 msgstr ""
@@ -927,37 +895,53 @@ msgstr "injustifié(e)"
 msgid "Students list: %(group)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:23
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:54
 msgid "Select"
 msgstr "Sélectionner"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:31
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:62
+#, fuzzy
+#| msgid "Personal note filters"
+msgid "Toggle filters"
+msgstr "Filtres de notes personnelles"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:69
 #, python-format
 msgid ""
 "CW %(week)s:\n"
 "      %(instance)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:340
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:293
+msgid "Unfold"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:360
+#, fuzzy
+#| msgid "Personal overview"
+msgid "Visit lesson overview"
+msgstr "Vue d'ensemble personnelle"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:398
 msgid "unexcused"
 msgstr "Injustifié(e)"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:343
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:401
 msgid "Summed up tardiness"
 msgstr "Résumé des retards"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:346
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:404
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:92
 #, fuzzy
 #| msgid "Summed up tardiness"
 msgid "Count of tardiness"
 msgstr "Résumé des retards"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:377
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:436
 msgid "No lessons available"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:380
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:439
 #, fuzzy
 #| msgid ""
 #| "\n"
@@ -1115,26 +1099,100 @@ msgstr "injustifié(e)"
 msgid "Excused absences"
 msgstr "injustifié(e)"
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:28
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:42
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:7
+#, fuzzy, python-format
+#| msgid "From period"
+msgid "%(period)s. period"
+msgstr "De la période"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:31
+#, python-format
+msgid ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  period\n"
+"          "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:8
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:135
+msgid "Save"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:19
+#, python-format
+msgid ""
+"\n"
+"        Previous %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:30
+#, python-format
+msgid ""
+"\n"
+"        Next %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html:13
+msgid "Change history"
+msgstr "Changement d' histoire"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:58
+#, fuzzy
+#| msgid "Tardiness"
+msgid "Tardiness (in m)"
+msgstr "Retard"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:6
+msgid "Overview: Previous lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:13
+msgid "Lesson topic of previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:20
+msgid "Homework for this lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:27
+msgid "Group notes for previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:34
+#, fuzzy
+#| msgid "Absences"
+msgid "Absent persons:"
+msgstr "Absences"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:41
+msgid "Late persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:6
 msgid "Data complete"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:12
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:25
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:17
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:30
 msgid "Missing data"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:14
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:27
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:19
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:32
 msgid "Pending"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:23
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:426
 msgid "Lesson cancelled"
 msgstr "Cours annulés"
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:34
 msgid "Substitution"
 msgstr ""
 
@@ -1352,104 +1410,109 @@ msgstr "Vue de semaine"
 msgid "Notes"
 msgstr "Notes"
 
-#: aleksis/apps/alsijil/views.py:114
+#: aleksis/apps/alsijil/views.py:117
 msgid "You either selected an invalid lesson or there is currently no lesson in progress."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:147
+#: aleksis/apps/alsijil/views.py:150
 msgid "You are not allowed to create a lesson documentation for a lesson in the future."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:241
+#: aleksis/apps/alsijil/views.py:246
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The lesson documentation has been saved."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:275
+#: aleksis/apps/alsijil/views.py:280
 msgid "The personal notes have been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1031
+#: aleksis/apps/alsijil/views.py:1049
 msgid "The absence has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1052
+#: aleksis/apps/alsijil/views.py:1070
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The personal note has been deleted."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1074
+#: aleksis/apps/alsijil/views.py:1092
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The extra mark has been created."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1086
+#: aleksis/apps/alsijil/views.py:1104
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The extra mark has been saved."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1097
+#: aleksis/apps/alsijil/views.py:1115
 msgid "The extra mark has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1118
+#: aleksis/apps/alsijil/views.py:1136
 msgid "The excuse type has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1130
+#: aleksis/apps/alsijil/views.py:1148
 msgid "The excuse type has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1141
+#: aleksis/apps/alsijil/views.py:1159
 msgid "The excuse type has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1162
+#: aleksis/apps/alsijil/views.py:1180
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The group role has been created."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1174
+#: aleksis/apps/alsijil/views.py:1192
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The group role has been saved."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1185
+#: aleksis/apps/alsijil/views.py:1203
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The group role has been deleted."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1218 aleksis/apps/alsijil/views.py:1250
+#: aleksis/apps/alsijil/views.py:1236 aleksis/apps/alsijil/views.py:1268
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The group role has been assigned."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1269
+#: aleksis/apps/alsijil/views.py:1287
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The group role assignment has been saved."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1290
+#: aleksis/apps/alsijil/views.py:1308
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The group role assignment has been stopped."
 msgstr "Documentation de cours pour la semaine calendrier"
 
-#: aleksis/apps/alsijil/views.py:1303
+#: aleksis/apps/alsijil/views.py:1321
 #, fuzzy
 #| msgid "Lesson documentation for calendar week"
 msgid "The group role assignment has been deleted."
 msgstr "Documentation de cours pour la semaine calendrier"
 
+#, fuzzy
+#~| msgid "Week view"
+#~ msgid "Back to week view"
+#~ msgstr "Vue de semaine"
+
 #, fuzzy
 #~| msgid "Lesson documentation for calendar week"
 #~ msgid "Lesson documentation for week"
diff --git a/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po
index 629487406bc5de79c6e899c4080e8147f9c7a723..fc62666b0939662f7b64dd2b03f1cfa3e68dedb6 100644
--- a/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po
+++ b/aleksis/apps/alsijil/locale/la/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-28 17:33+0200\n"
+"POT-Creation-Date: 2021-12-24 13:24+0100\n"
 "PO-Revision-Date: 2020-07-26 14:08+0000\n"
 "Last-Translator: Julian <leuckerj@gmail.com>\n"
 "Language-Team: Latin <https://translate.edugit.org/projects/aleksis/aleksis-app-alsijil/la/>\n"
@@ -110,10 +110,10 @@ msgstr ""
 msgid "Before"
 msgstr ""
 
-#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:293
+#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:302
 #: aleksis/apps/alsijil/tables.py:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:106
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:202
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:227
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:169
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:200
 msgid "Subject"
@@ -131,99 +131,100 @@ msgstr ""
 msgid "Homework for the next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:72 aleksis/apps/alsijil/forms.py:208
-#: aleksis/apps/alsijil/forms.py:292
+#: aleksis/apps/alsijil/forms.py:73 aleksis/apps/alsijil/forms.py:214
+#: aleksis/apps/alsijil/forms.py:301
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:199
 msgid "Group"
 msgstr "Grex"
 
-#: aleksis/apps/alsijil/forms.py:75
+#: aleksis/apps/alsijil/forms.py:79
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:170
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:201
 msgid "Teacher"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:90
+#: aleksis/apps/alsijil/forms.py:96
 msgid "You can't select a group and a teacher both."
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:144 aleksis/apps/alsijil/forms.py:294
-#: aleksis/apps/alsijil/models.py:446
+#: aleksis/apps/alsijil/forms.py:150 aleksis/apps/alsijil/forms.py:303
+#: aleksis/apps/alsijil/models.py:471
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64
 msgid "Start date"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:145 aleksis/apps/alsijil/forms.py:295
-#: aleksis/apps/alsijil/models.py:450
+#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/forms.py:304
+#: aleksis/apps/alsijil/models.py:475
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65
 msgid "End date"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:146
+#: aleksis/apps/alsijil/forms.py:152
 msgid "Start period"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:147
+#: aleksis/apps/alsijil/forms.py:153
 msgid "End period"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:148
+#: aleksis/apps/alsijil/forms.py:154 aleksis/apps/alsijil/tables.py:108
+#: aleksis/apps/alsijil/tables.py:129
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:263
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:339
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:397
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:75
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:312
 msgid "Absent"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:149 aleksis/apps/alsijil/tables.py:137
+#: aleksis/apps/alsijil/forms.py:155 aleksis/apps/alsijil/tables.py:137
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:265
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:134
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:72
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:84
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:275
 msgid "Excused"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/models.py:62
-#: aleksis/apps/alsijil/models.py:232
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:266
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:307
+#: aleksis/apps/alsijil/forms.py:157 aleksis/apps/alsijil/models.py:62
+#: aleksis/apps/alsijil/models.py:236
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:31
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:72
 msgid "Excuse type"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:156
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:268
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:328
+#: aleksis/apps/alsijil/forms.py:162
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:93
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:314
 msgid "Remarks"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:218
+#: aleksis/apps/alsijil/forms.py:227
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:9
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:262
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27
 msgid "Person"
 msgstr "Persona"
 
-#: aleksis/apps/alsijil/forms.py:290
+#: aleksis/apps/alsijil/forms.py:299
 msgid "School term"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:291
+#: aleksis/apps/alsijil/forms.py:300
 msgid "Has lesson documentation"
 msgstr ""
 
-#: aleksis/apps/alsijil/managers.py:81 aleksis/apps/alsijil/tables.py:121
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:57
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:151
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:214
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:268
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:16
+#: aleksis/apps/alsijil/managers.py:88 aleksis/apps/alsijil/tables.py:121
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:176
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:240
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:316
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:50
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:21
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:335
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:415
-#: aleksis/apps/alsijil/util/alsijil_helpers.py:314
+#: aleksis/apps/alsijil/util/alsijil_helpers.py:315
 msgid "Event"
 msgstr ""
 
@@ -277,12 +278,12 @@ msgstr ""
 msgid "Excuse types"
 msgstr ""
 
-#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:237
-#: aleksis/apps/alsijil/models.py:401
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:267
+#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:241
+#: aleksis/apps/alsijil/models.py:423 aleksis/apps/alsijil/tables.py:111
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9
 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:41
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:17
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:293
 msgid "Extra marks"
@@ -292,136 +293,137 @@ msgstr ""
 msgid "Manage group roles"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:180
+#: aleksis/apps/alsijil/model_extensions.py:191
 msgid "Can view week overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:183
+#: aleksis/apps/alsijil/model_extensions.py:195
 msgid "Can view lesson overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:185
+#: aleksis/apps/alsijil/model_extensions.py:197
 msgid "Can view all personal notes of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:186
+#: aleksis/apps/alsijil/model_extensions.py:198
 msgid "Can edit all personal notes of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:188
+#: aleksis/apps/alsijil/model_extensions.py:200
 msgid "Can view all lesson documentation of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:191
+#: aleksis/apps/alsijil/model_extensions.py:203
 msgid "Can edit all lesson documentation of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:193
+#: aleksis/apps/alsijil/model_extensions.py:205
 msgid "Can view full register of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:195
+#: aleksis/apps/alsijil/model_extensions.py:207
 msgid "Can register an absence for all members of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:197
+#: aleksis/apps/alsijil/model_extensions.py:209
+msgid "Can assign a group role for this group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:210
 msgid "Can register an absence for a person"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:388
+#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:410
 #, fuzzy
 #| msgid "First name"
 msgid "Short name"
 msgstr "Primus nomen"
 
-#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:389
-#: aleksis/apps/alsijil/models.py:413
+#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:411
+#: aleksis/apps/alsijil/models.py:435
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:22
 msgid "Name"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:303
+#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:315
 msgid "Year"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:271
+#: aleksis/apps/alsijil/models.py:275
 #, fuzzy
 #| msgid "Person"
 msgid "Personal note"
 msgstr "Persona"
 
-#: aleksis/apps/alsijil/models.py:272
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:115
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:253
+#: aleksis/apps/alsijil/models.py:276
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:47
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:71
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:317
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:375
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:18
 msgid "Personal notes"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:315
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:150
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:108
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:237
+#: aleksis/apps/alsijil/models.py:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:263
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:342
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:26
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:381
 msgid "Lesson topic"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:316
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:158
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:109
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:243
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:289
+#: aleksis/apps/alsijil/models.py:328
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:133
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:269
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:347
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:34
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:382
 msgid "Homework"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:317
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:166
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:110
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:249
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:295
+#: aleksis/apps/alsijil/models.py:329
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:134
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:275
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:351
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:42
 #, fuzzy
 #| msgid "Group"
 msgid "Group note"
 msgstr "Grex"
 
-#: aleksis/apps/alsijil/models.py:363
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:111
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:141
+#: aleksis/apps/alsijil/models.py:376
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:17
 msgid "Lesson documentation"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:364
+#: aleksis/apps/alsijil/models.py:377
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:43
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:68
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:21
 msgid "Lesson documentations"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:400
+#: aleksis/apps/alsijil/models.py:422
 msgid "Extra mark"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:414
+#: aleksis/apps/alsijil/models.py:436
 msgid "Icon"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:415
+#: aleksis/apps/alsijil/models.py:437
 msgid "Colour"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:421 aleksis/apps/alsijil/models.py:435
+#: aleksis/apps/alsijil/models.py:443 aleksis/apps/alsijil/models.py:458
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62
 #, fuzzy
 #| msgid "Group"
 msgid "Group role"
 msgstr "Grex"
 
-#: aleksis/apps/alsijil/models.py:422
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:128
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:75
+#: aleksis/apps/alsijil/models.py:444
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:34
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9
 #, fuzzy
@@ -429,39 +431,52 @@ msgstr "Grex"
 msgid "Group roles"
 msgstr "Grex"
 
-#: aleksis/apps/alsijil/models.py:441
+#: aleksis/apps/alsijil/models.py:448
+msgid "Can assign group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:464
 msgid "Assigned person"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:444 aleksis/apps/alsijil/tables.py:98
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:104
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:220
+#: aleksis/apps/alsijil/models.py:469 aleksis/apps/alsijil/tables.py:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:128
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:246
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:326
 #, fuzzy
 #| msgid "Group"
 msgid "Groups"
 msgstr "Grex"
 
-#: aleksis/apps/alsijil/models.py:451
+#: aleksis/apps/alsijil/models.py:476
 msgid "Can be left empty if end date is not clear yet"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:466
+#: aleksis/apps/alsijil/models.py:491
 msgid "Group role assignment"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:467
+#: aleksis/apps/alsijil/models.py:492
 msgid "Group role assignments"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:474
+#: aleksis/apps/alsijil/models.py:499
+msgid "Can view lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:500
 msgid "Can view week overview"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:475
+#: aleksis/apps/alsijil/models.py:501
+msgid "Can view full register"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:502
 msgid "Can register absence"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:476
+#: aleksis/apps/alsijil/models.py:503
 msgid "Can list all personal note filters"
 msgstr ""
 
@@ -545,16 +560,28 @@ msgid "Date"
 msgstr "dies"
 
 #: aleksis/apps/alsijil/tables.py:95
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:102
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:17
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126
 msgid "Period"
 msgstr ""
 
 #: aleksis/apps/alsijil/tables.py:103
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:231
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:131
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:257
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:336
 msgid "Teachers"
 msgstr ""
 
+#: aleksis/apps/alsijil/tables.py:109
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
+msgid "Tardiness"
+msgstr ""
+
 #: aleksis/apps/alsijil/tables.py:110
 msgid "Excuse"
 msgstr ""
@@ -567,7 +594,7 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:5
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:6
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:30
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:385
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:113
 msgid "Register absence"
 msgstr ""
@@ -618,13 +645,15 @@ msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:35
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:76
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:40
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:51
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:78
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90
 msgid "Students list"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:39
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:60
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:69
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:27
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:43
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:16
@@ -644,8 +673,8 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:50
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:20
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:42
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:44
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:58
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:97
 msgid "Generate printout"
 msgstr ""
 
@@ -662,107 +691,41 @@ msgstr ""
 msgid "Lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:21
-msgid "Back to week view"
-msgstr ""
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:24
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:27
+#, fuzzy
+#| msgid "Person"
+msgid "Persons"
+msgstr "Persona"
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30
-msgid "My previous lesson"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:34
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:82
+msgid "Previous"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:39
-msgid "My next lesson"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:42
+msgid "More"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:51
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:187
-#, python-format
-msgid "%(period)s. period"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:75
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:81
+msgid "My previous lesson"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:86
-#, python-format
-msgid ""
-"\n"
-"            Previous %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:96
-#, python-format
-msgid ""
-"\n"
-"            Next %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:122
-msgid "Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:132
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:380
-msgid "Change history"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:186
-msgid "Overview: Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:193
-msgid "Lesson topic of previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:200
-msgid "Homework for this lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:207
-msgid "Group notes for previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:214
-msgid "Absent persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:221
-msgid "Late persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:264
-#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
-#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
-msgid "Tardiness"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:293
-msgid "Tardiness (in m)"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:399
-#, python-format
-msgid ""
-"\n"
-"              Previous %(subject)s lesson\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:92
+msgid "My next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:409
-#, python-format
-msgid ""
-"\n"
-"              Next %(subject)s lesson\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:93
+msgid "Next"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:425
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:143
 msgid ""
 "\n"
-"                This lesson overlaps with holidays and can't be edited.\n"
-"              "
+"                  This lesson overlaps with holidays and can't be edited.\n"
+"                "
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:10
@@ -809,6 +772,12 @@ msgstr ""
 msgid "Filter"
 msgstr ""
 
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:91
+#, fuzzy
+#| msgid "Person"
+msgid "Filter results"
+msgstr "Persona"
+
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:119
 msgid "Statistics on absences, tardiness and remarks"
 msgstr ""
@@ -840,35 +809,47 @@ msgstr ""
 msgid "Students list: %(group)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:23
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:54
 msgid "Select"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:31
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:62
+msgid "Toggle filters"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:69
 #, python-format
 msgid ""
 "CW %(week)s:\n"
 "      %(instance)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:340
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:293
+msgid "Unfold"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:360
+msgid "Visit lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:398
 msgid "unexcused"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:343
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:401
 msgid "Summed up tardiness"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:346
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:404
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:92
 msgid "Count of tardiness"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:377
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:436
 msgid "No lessons available"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:380
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:439
 msgid ""
 "\n"
 "            There are no lessons for the selected group or teacher in this week.\n"
@@ -1012,26 +993,95 @@ msgstr ""
 msgid "Excused absences"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:28
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:42
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:7
+#, python-format
+msgid "%(period)s. period"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:31
+#, python-format
+msgid ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  period\n"
+"          "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:8
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:135
+msgid "Save"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:19
+#, python-format
+msgid ""
+"\n"
+"        Previous %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:30
+#, python-format
+msgid ""
+"\n"
+"        Next %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html:13
+msgid "Change history"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:58
+msgid "Tardiness (in m)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:6
+msgid "Overview: Previous lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:13
+msgid "Lesson topic of previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:20
+msgid "Homework for this lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:27
+msgid "Group notes for previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:34
+msgid "Absent persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:41
+msgid "Late persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:6
 msgid "Data complete"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:12
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:25
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:17
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:30
 msgid "Missing data"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:14
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:27
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:19
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:32
 msgid "Pending"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:23
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:426
 msgid "Lesson cancelled"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:34
 msgid "Substitution"
 msgstr ""
 
@@ -1237,79 +1287,79 @@ msgstr ""
 msgid "Notes"
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:114
+#: aleksis/apps/alsijil/views.py:117
 msgid "You either selected an invalid lesson or there is currently no lesson in progress."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:147
+#: aleksis/apps/alsijil/views.py:150
 msgid "You are not allowed to create a lesson documentation for a lesson in the future."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:241
+#: aleksis/apps/alsijil/views.py:246
 msgid "The lesson documentation has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:275
+#: aleksis/apps/alsijil/views.py:280
 msgid "The personal notes have been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1031
+#: aleksis/apps/alsijil/views.py:1049
 msgid "The absence has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1052
+#: aleksis/apps/alsijil/views.py:1070
 msgid "The personal note has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1074
+#: aleksis/apps/alsijil/views.py:1092
 msgid "The extra mark has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1086
+#: aleksis/apps/alsijil/views.py:1104
 msgid "The extra mark has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1097
+#: aleksis/apps/alsijil/views.py:1115
 msgid "The extra mark has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1118
+#: aleksis/apps/alsijil/views.py:1136
 msgid "The excuse type has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1130
+#: aleksis/apps/alsijil/views.py:1148
 msgid "The excuse type has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1141
+#: aleksis/apps/alsijil/views.py:1159
 msgid "The excuse type has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1162
+#: aleksis/apps/alsijil/views.py:1180
 msgid "The group role has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1174
+#: aleksis/apps/alsijil/views.py:1192
 msgid "The group role has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1185
+#: aleksis/apps/alsijil/views.py:1203
 msgid "The group role has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1218 aleksis/apps/alsijil/views.py:1250
+#: aleksis/apps/alsijil/views.py:1236 aleksis/apps/alsijil/views.py:1268
 msgid "The group role has been assigned."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1269
+#: aleksis/apps/alsijil/views.py:1287
 msgid "The group role assignment has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1290
+#: aleksis/apps/alsijil/views.py:1308
 msgid "The group role assignment has been stopped."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1303
+#: aleksis/apps/alsijil/views.py:1321
 msgid "The group role assignment has been deleted."
 msgstr ""
 
diff --git a/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po
index c9fcfa46f7015bda5734a25052658daacf71e2fb..0f75a14f7e9b4a4ec0b20f5fe915794fbb6aa540 100644
--- a/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po
+++ b/aleksis/apps/alsijil/locale/nb_NO/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-28 17:33+0200\n"
+"POT-Creation-Date: 2021-12-24 13:24+0100\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"
@@ -109,10 +109,10 @@ msgstr ""
 msgid "Before"
 msgstr ""
 
-#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:293
+#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:302
 #: aleksis/apps/alsijil/tables.py:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:106
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:202
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:227
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:169
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:200
 msgid "Subject"
@@ -130,99 +130,100 @@ msgstr ""
 msgid "Homework for the next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:72 aleksis/apps/alsijil/forms.py:208
-#: aleksis/apps/alsijil/forms.py:292
+#: aleksis/apps/alsijil/forms.py:73 aleksis/apps/alsijil/forms.py:214
+#: aleksis/apps/alsijil/forms.py:301
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:199
 msgid "Group"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:75
+#: aleksis/apps/alsijil/forms.py:79
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:170
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:201
 msgid "Teacher"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:90
+#: aleksis/apps/alsijil/forms.py:96
 msgid "You can't select a group and a teacher both."
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:144 aleksis/apps/alsijil/forms.py:294
-#: aleksis/apps/alsijil/models.py:446
+#: aleksis/apps/alsijil/forms.py:150 aleksis/apps/alsijil/forms.py:303
+#: aleksis/apps/alsijil/models.py:471
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64
 msgid "Start date"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:145 aleksis/apps/alsijil/forms.py:295
-#: aleksis/apps/alsijil/models.py:450
+#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/forms.py:304
+#: aleksis/apps/alsijil/models.py:475
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65
 msgid "End date"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:146
+#: aleksis/apps/alsijil/forms.py:152
 msgid "Start period"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:147
+#: aleksis/apps/alsijil/forms.py:153
 msgid "End period"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:148
+#: aleksis/apps/alsijil/forms.py:154 aleksis/apps/alsijil/tables.py:108
+#: aleksis/apps/alsijil/tables.py:129
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:263
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:339
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:397
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:75
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:312
 msgid "Absent"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:149 aleksis/apps/alsijil/tables.py:137
+#: aleksis/apps/alsijil/forms.py:155 aleksis/apps/alsijil/tables.py:137
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:265
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:134
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:72
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:84
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:275
 msgid "Excused"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/models.py:62
-#: aleksis/apps/alsijil/models.py:232
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:266
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:307
+#: aleksis/apps/alsijil/forms.py:157 aleksis/apps/alsijil/models.py:62
+#: aleksis/apps/alsijil/models.py:236
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:31
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:72
 msgid "Excuse type"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:156
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:268
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:328
+#: aleksis/apps/alsijil/forms.py:162
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:93
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:314
 msgid "Remarks"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:218
+#: aleksis/apps/alsijil/forms.py:227
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:9
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:262
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27
 msgid "Person"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:290
+#: aleksis/apps/alsijil/forms.py:299
 msgid "School term"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:291
+#: aleksis/apps/alsijil/forms.py:300
 msgid "Has lesson documentation"
 msgstr ""
 
-#: aleksis/apps/alsijil/managers.py:81 aleksis/apps/alsijil/tables.py:121
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:57
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:151
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:214
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:268
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:16
+#: aleksis/apps/alsijil/managers.py:88 aleksis/apps/alsijil/tables.py:121
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:176
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:240
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:316
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:50
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:21
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:335
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:415
-#: aleksis/apps/alsijil/util/alsijil_helpers.py:314
+#: aleksis/apps/alsijil/util/alsijil_helpers.py:315
 msgid "Event"
 msgstr ""
 
@@ -274,12 +275,12 @@ msgstr ""
 msgid "Excuse types"
 msgstr ""
 
-#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:237
-#: aleksis/apps/alsijil/models.py:401
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:267
+#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:241
+#: aleksis/apps/alsijil/models.py:423 aleksis/apps/alsijil/tables.py:111
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9
 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:41
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:17
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:293
 msgid "Extra marks"
@@ -289,164 +290,178 @@ msgstr ""
 msgid "Manage group roles"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:180
+#: aleksis/apps/alsijil/model_extensions.py:191
 msgid "Can view week overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:183
+#: aleksis/apps/alsijil/model_extensions.py:195
 msgid "Can view lesson overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:185
+#: aleksis/apps/alsijil/model_extensions.py:197
 msgid "Can view all personal notes of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:186
+#: aleksis/apps/alsijil/model_extensions.py:198
 msgid "Can edit all personal notes of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:188
+#: aleksis/apps/alsijil/model_extensions.py:200
 msgid "Can view all lesson documentation of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:191
+#: aleksis/apps/alsijil/model_extensions.py:203
 msgid "Can edit all lesson documentation of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:193
+#: aleksis/apps/alsijil/model_extensions.py:205
 msgid "Can view full register of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:195
+#: aleksis/apps/alsijil/model_extensions.py:207
 msgid "Can register an absence for all members of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:197
+#: aleksis/apps/alsijil/model_extensions.py:209
+msgid "Can assign a group role for this group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:210
 msgid "Can register an absence for a person"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:388
+#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:410
 msgid "Short name"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:389
-#: aleksis/apps/alsijil/models.py:413
+#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:411
+#: aleksis/apps/alsijil/models.py:435
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:22
 msgid "Name"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:303
+#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:315
 msgid "Year"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:271
+#: aleksis/apps/alsijil/models.py:275
 msgid "Personal note"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:272
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:115
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:253
+#: aleksis/apps/alsijil/models.py:276
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:47
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:71
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:317
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:375
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:18
 msgid "Personal notes"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:315
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:150
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:108
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:237
+#: aleksis/apps/alsijil/models.py:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:263
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:342
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:26
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:381
 msgid "Lesson topic"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:316
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:158
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:109
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:243
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:289
+#: aleksis/apps/alsijil/models.py:328
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:133
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:269
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:347
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:34
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:382
 msgid "Homework"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:317
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:166
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:110
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:249
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:295
+#: aleksis/apps/alsijil/models.py:329
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:134
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:275
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:351
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:42
 msgid "Group note"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:363
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:111
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:141
+#: aleksis/apps/alsijil/models.py:376
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:17
 msgid "Lesson documentation"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:364
+#: aleksis/apps/alsijil/models.py:377
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:43
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:68
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:21
 msgid "Lesson documentations"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:400
+#: aleksis/apps/alsijil/models.py:422
 msgid "Extra mark"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:414
+#: aleksis/apps/alsijil/models.py:436
 msgid "Icon"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:415
+#: aleksis/apps/alsijil/models.py:437
 msgid "Colour"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:421 aleksis/apps/alsijil/models.py:435
+#: aleksis/apps/alsijil/models.py:443 aleksis/apps/alsijil/models.py:458
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62
 msgid "Group role"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:422
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:128
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:75
+#: aleksis/apps/alsijil/models.py:444
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:34
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9
 msgid "Group roles"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:441
+#: aleksis/apps/alsijil/models.py:448
+msgid "Can assign group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:464
 msgid "Assigned person"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:444 aleksis/apps/alsijil/tables.py:98
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:104
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:220
+#: aleksis/apps/alsijil/models.py:469 aleksis/apps/alsijil/tables.py:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:128
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:246
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:326
 msgid "Groups"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:451
+#: aleksis/apps/alsijil/models.py:476
 msgid "Can be left empty if end date is not clear yet"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:466
+#: aleksis/apps/alsijil/models.py:491
 msgid "Group role assignment"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:467
+#: aleksis/apps/alsijil/models.py:492
 msgid "Group role assignments"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:474
+#: aleksis/apps/alsijil/models.py:499
+msgid "Can view lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:500
 msgid "Can view week overview"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:475
+#: aleksis/apps/alsijil/models.py:501
+msgid "Can view full register"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:502
 msgid "Can register absence"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:476
+#: aleksis/apps/alsijil/models.py:503
 msgid "Can list all personal note filters"
 msgstr ""
 
@@ -530,16 +545,28 @@ msgid "Date"
 msgstr ""
 
 #: aleksis/apps/alsijil/tables.py:95
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:102
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:17
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126
 msgid "Period"
 msgstr ""
 
 #: aleksis/apps/alsijil/tables.py:103
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:231
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:131
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:257
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:336
 msgid "Teachers"
 msgstr ""
 
+#: aleksis/apps/alsijil/tables.py:109
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
+msgid "Tardiness"
+msgstr ""
+
 #: aleksis/apps/alsijil/tables.py:110
 msgid "Excuse"
 msgstr ""
@@ -552,7 +579,7 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:5
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:6
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:30
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:385
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:113
 msgid "Register absence"
 msgstr ""
@@ -603,13 +630,15 @@ msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:35
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:76
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:40
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:51
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:78
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90
 msgid "Students list"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:39
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:60
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:69
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:27
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:43
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:16
@@ -629,8 +658,8 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:50
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:20
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:42
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:44
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:58
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:97
 msgid "Generate printout"
 msgstr ""
 
@@ -647,107 +676,39 @@ msgstr ""
 msgid "Lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:21
-msgid "Back to week view"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:24
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:27
+msgid "Persons"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30
-msgid "My previous lesson"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:34
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:82
+msgid "Previous"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:39
-msgid "My next lesson"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:42
+msgid "More"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:51
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:187
-#, python-format
-msgid "%(period)s. period"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:75
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:81
+msgid "My previous lesson"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:86
-#, python-format
-msgid ""
-"\n"
-"            Previous %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:96
-#, python-format
-msgid ""
-"\n"
-"            Next %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:122
-msgid "Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:132
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:380
-msgid "Change history"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:186
-msgid "Overview: Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:193
-msgid "Lesson topic of previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:200
-msgid "Homework for this lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:207
-msgid "Group notes for previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:214
-msgid "Absent persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:221
-msgid "Late persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:264
-#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
-#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
-msgid "Tardiness"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:293
-msgid "Tardiness (in m)"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:399
-#, python-format
-msgid ""
-"\n"
-"              Previous %(subject)s lesson\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:92
+msgid "My next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:409
-#, python-format
-msgid ""
-"\n"
-"              Next %(subject)s lesson\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:93
+msgid "Next"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:425
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:143
 msgid ""
 "\n"
-"                This lesson overlaps with holidays and can't be edited.\n"
-"              "
+"                  This lesson overlaps with holidays and can't be edited.\n"
+"                "
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:10
@@ -792,6 +753,10 @@ msgstr ""
 msgid "Filter"
 msgstr ""
 
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:91
+msgid "Filter results"
+msgstr ""
+
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:119
 msgid "Statistics on absences, tardiness and remarks"
 msgstr ""
@@ -823,35 +788,47 @@ msgstr ""
 msgid "Students list: %(group)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:23
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:54
 msgid "Select"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:31
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:62
+msgid "Toggle filters"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:69
 #, python-format
 msgid ""
 "CW %(week)s:\n"
 "      %(instance)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:340
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:293
+msgid "Unfold"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:360
+msgid "Visit lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:398
 msgid "unexcused"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:343
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:401
 msgid "Summed up tardiness"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:346
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:404
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:92
 msgid "Count of tardiness"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:377
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:436
 msgid "No lessons available"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:380
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:439
 msgid ""
 "\n"
 "            There are no lessons for the selected group or teacher in this week.\n"
@@ -993,26 +970,95 @@ msgstr ""
 msgid "Excused absences"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:28
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:42
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:7
+#, python-format
+msgid "%(period)s. period"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:31
+#, python-format
+msgid ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  period\n"
+"          "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:8
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:135
+msgid "Save"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:19
+#, python-format
+msgid ""
+"\n"
+"        Previous %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:30
+#, python-format
+msgid ""
+"\n"
+"        Next %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html:13
+msgid "Change history"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:58
+msgid "Tardiness (in m)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:6
+msgid "Overview: Previous lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:13
+msgid "Lesson topic of previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:20
+msgid "Homework for this lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:27
+msgid "Group notes for previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:34
+msgid "Absent persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:41
+msgid "Late persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:6
 msgid "Data complete"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:12
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:25
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:17
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:30
 msgid "Missing data"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:14
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:27
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:19
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:32
 msgid "Pending"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:23
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:426
 msgid "Lesson cancelled"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:34
 msgid "Substitution"
 msgstr ""
 
@@ -1216,78 +1262,78 @@ msgstr ""
 msgid "Notes"
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:114
+#: aleksis/apps/alsijil/views.py:117
 msgid "You either selected an invalid lesson or there is currently no lesson in progress."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:147
+#: aleksis/apps/alsijil/views.py:150
 msgid "You are not allowed to create a lesson documentation for a lesson in the future."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:241
+#: aleksis/apps/alsijil/views.py:246
 msgid "The lesson documentation has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:275
+#: aleksis/apps/alsijil/views.py:280
 msgid "The personal notes have been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1031
+#: aleksis/apps/alsijil/views.py:1049
 msgid "The absence has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1052
+#: aleksis/apps/alsijil/views.py:1070
 msgid "The personal note has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1074
+#: aleksis/apps/alsijil/views.py:1092
 msgid "The extra mark has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1086
+#: aleksis/apps/alsijil/views.py:1104
 msgid "The extra mark has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1097
+#: aleksis/apps/alsijil/views.py:1115
 msgid "The extra mark has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1118
+#: aleksis/apps/alsijil/views.py:1136
 msgid "The excuse type has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1130
+#: aleksis/apps/alsijil/views.py:1148
 msgid "The excuse type has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1141
+#: aleksis/apps/alsijil/views.py:1159
 msgid "The excuse type has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1162
+#: aleksis/apps/alsijil/views.py:1180
 msgid "The group role has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1174
+#: aleksis/apps/alsijil/views.py:1192
 msgid "The group role has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1185
+#: aleksis/apps/alsijil/views.py:1203
 msgid "The group role has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1218 aleksis/apps/alsijil/views.py:1250
+#: aleksis/apps/alsijil/views.py:1236 aleksis/apps/alsijil/views.py:1268
 msgid "The group role has been assigned."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1269
+#: aleksis/apps/alsijil/views.py:1287
 msgid "The group role assignment has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1290
+#: aleksis/apps/alsijil/views.py:1308
 msgid "The group role assignment has been stopped."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1303
+#: aleksis/apps/alsijil/views.py:1321
 msgid "The group role assignment has been deleted."
 msgstr ""
diff --git a/aleksis/apps/alsijil/locale/ru/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/ru/LC_MESSAGES/django.po
new file mode 100644
index 0000000000000000000000000000000000000000..cfdaa5cfb780278cb399496235d9af4140f18d64
--- /dev/null
+++ b/aleksis/apps/alsijil/locale/ru/LC_MESSAGES/django.po
@@ -0,0 +1,1437 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-04-23 12:35+0000\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"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
+"%100>=11 && n%100<=14)? 2 : 3);\n"
+#: aleksis/apps/alsijil/actions.py:18
+msgid "Mark as excused"
+msgstr ""
+
+#: aleksis/apps/alsijil/actions.py:25
+msgid "Mark as unexcused"
+msgstr ""
+
+#: aleksis/apps/alsijil/actions.py:32
+#, python-brace-format
+msgid "Mark as {excuse_type.name}"
+msgstr ""
+
+#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29
+#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29
+msgid "Delete"
+msgstr ""
+
+#: aleksis/apps/alsijil/actions.py:68
+msgid "{} asks you to check some class register entries."
+msgstr ""
+
+#: aleksis/apps/alsijil/actions.py:86
+#, python-brace-format
+msgid "We have successfully sent notifications to {count_teachers} persons for {count_items} lessons."
+msgstr ""
+
+#: aleksis/apps/alsijil/actions.py:92
+msgid "Ask teacher to check data"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:12
+msgid "Delete object"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:22
+msgid "Set current groups"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:33
+msgid "Reset personal note to defaults"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:45
+msgid "Ensure that there are no personal notes in cancelled lessons"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:46
+msgid "The personal note is related to a cancelled lesson."
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:73
+msgid "Ensure that 'groups_of_person' is set for every personal note"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:74
+msgid "The personal note has no group in 'groups_of_person'."
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:99
+msgid "Ensure that there are no filled out lesson documentations on holidays"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:100
+msgid "The lesson documentation is on holidays."
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:133
+msgid "Ensure that there are no filled out personal notes on holidays"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:134
+msgid "The personal note is on holidays."
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:162
+msgid "Ensure that there are no excused personal notes without an absence"
+msgstr ""
+
+#: aleksis/apps/alsijil/data_checks.py:163
+msgid "The personal note is marked as excused, but not as absent."
+msgstr ""
+
+#: aleksis/apps/alsijil/filters.py:12
+msgid "After"
+msgstr ""
+
+#: aleksis/apps/alsijil/filters.py:13
+msgid "Before"
+msgstr ""
+
+#: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:302
+#: aleksis/apps/alsijil/tables.py:116
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:227
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:220
+msgid "Subject"
+msgstr ""
+
+#: aleksis/apps/alsijil/filters.py:30
+msgid "Tardiness is lower than"
+msgstr ""
+
+#: aleksis/apps/alsijil/filters.py:31
+msgid "Tardiness is bigger than"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:47
+msgid "Homework for the next lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:73 aleksis/apps/alsijil/forms.py:214
+#: aleksis/apps/alsijil/forms.py:301
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:219
+msgid "Group"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:79
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:190
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:221
+msgid "Teacher"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:96
+msgid "You can't select a group and a teacher both."
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:150 aleksis/apps/alsijil/forms.py:303
+#: aleksis/apps/alsijil/models.py:480
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64
+msgid "Start date"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/forms.py:304
+#: aleksis/apps/alsijil/models.py:484
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65
+msgid "End date"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:152
+msgid "Start period"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:153
+msgid "End period"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:154 aleksis/apps/alsijil/tables.py:117
+#: aleksis/apps/alsijil/tables.py:138
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:397
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:75
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:352
+msgid "Absent"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:155 aleksis/apps/alsijil/tables.py:146
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:134
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:31
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:85
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:84
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:297
+msgid "Excused"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:157 aleksis/apps/alsijil/models.py:71
+#: aleksis/apps/alsijil/models.py:245
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:73
+msgid "Excuse type"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:162
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:34
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:94
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:354
+msgid "Remarks"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:227
+#: aleksis/apps/alsijil/templates/alsijil/absences/register.html:9
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28
+msgid "Person"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:299
+msgid "School term"
+msgstr ""
+
+#: aleksis/apps/alsijil/forms.py:300
+msgid "Has lesson documentation"
+msgstr ""
+
+#: aleksis/apps/alsijil/managers.py:88 aleksis/apps/alsijil/tables.py:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:176
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:240
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:316
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:50
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:21
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:375
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:455
+#: aleksis/apps/alsijil/util/alsijil_helpers.py:315
+msgid "Event"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:6 aleksis/apps/alsijil/preferences.py:9
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:16
+msgid "Class register"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:16
+msgid "Current lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:27
+msgid "Current week"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:38
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:5
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:8
+msgid "My groups"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:49
+msgid "My overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:60
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:5
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:9
+msgid "My students"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:71
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:11
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:18
+msgid "Assign group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/all_objects.html:5
+#: aleksis/apps/alsijil/templates/alsijil/class_register/all_objects.html:8
+msgid "All lessons"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:93 aleksis/apps/alsijil/models.py:72
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html:8
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html:9
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:30
+msgid "Excuse types"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:250
+#: aleksis/apps/alsijil/models.py:432 aleksis/apps/alsijil/tables.py:120
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:18
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:331
+msgid "Extra marks"
+msgstr ""
+
+#: aleksis/apps/alsijil/menus.py:115
+msgid "Manage group roles"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:190
+msgid "Can view week overview of group class register"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:194
+msgid "Can view lesson overview of group class register"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:196
+msgid "Can view all personal notes of a group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:197
+msgid "Can edit all personal notes of a group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:199
+msgid "Can view all lesson documentation of a group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:202
+msgid "Can edit all lesson documentation of a group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:204
+msgid "Can view full register of a group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:206
+msgid "Can register an absence for all members of a group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:208
+msgid "Can assign a group role for this group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:209
+msgid "Can register an absence for a person"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:419
+msgid "Short name"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:420
+#: aleksis/apps/alsijil/models.py:444
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:23
+msgid "Name"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:55 aleksis/apps/alsijil/tables.py:41
+msgid "Count as absent"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:57
+msgid "If checked, this excuse type will be counted as a missed lesson. If not checked,it won't show up in the absence report."
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:225 aleksis/apps/alsijil/models.py:324
+msgid "Year"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:284
+msgid "Personal note"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:285
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:47
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:375
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:22
+msgid "Personal notes"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:336
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:263
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:342
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:26
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:421
+msgid "Lesson topic"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:337
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:133
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:269
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:347
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:34
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:422
+msgid "Homework"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:338
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:134
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:275
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:351
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:42
+msgid "Group note"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:385
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:17
+msgid "Lesson documentation"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:386
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:43
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:21
+msgid "Lesson documentations"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:431
+msgid "Extra mark"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:445
+msgid "Icon"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:446
+msgid "Colour"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:452 aleksis/apps/alsijil/models.py:467
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62
+msgid "Group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:453
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:34
+#: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8
+#: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9
+msgid "Group roles"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:457
+msgid "Can assign group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:473
+msgid "Assigned person"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:105
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:128
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:246
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:326
+msgid "Groups"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:485
+msgid "Can be left empty if end date is not clear yet"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:500
+msgid "Group role assignment"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:501
+msgid "Group role assignments"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:508
+msgid "Can view lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:509
+msgid "Can view week overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:510
+msgid "Can view full register"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:511
+msgid "Can register absence"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:512
+msgid "Can list all personal note filters"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:17
+msgid "Block adding personal notes for cancelled lessons"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:25
+msgid "Allow users to view their own personal notes"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:34
+msgid "Allow primary group owners to register future absences for students in their groups"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:43
+msgid "Allow original teachers to edit their lessons although they are substituted"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:52
+msgid "Carry over data from first lesson period to the following lesson periods in lessons over multiple periods"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:55
+msgid "This will carry over data only if the data in the following periods are empty."
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:63
+msgid "Carry over personal notes to all following lesson periods on the same day."
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:72
+msgid "Allow teachers to open lesson periods on the same day and not just at the beginning of the period"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:76
+msgid "Lessons in the past are not affected by this setting, you can open them whenever you want."
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:85
+msgid "Allow teachers to add data for lessons in holidays"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:94
+msgid "Allow group owners to assign group roles to the parents of the group's members"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:103
+msgid "Show assigned group roles in week view"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:104
+msgid "Only week view of groups"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:112
+msgid "Show assigned group roles in lesson view"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:122
+msgid "Items per page in lessons table"
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:126
+msgid "Each page must show at least one item."
+msgstr ""
+
+#: aleksis/apps/alsijil/preferences.py:134
+msgid "Filter lessons by existence of their lesson documentation on default"
+msgstr ""
+
+#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47
+#: aleksis/apps/alsijil/tables.py:72
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13
+msgid "Edit"
+msgstr ""
+
+#: aleksis/apps/alsijil/tables.py:96
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348
+msgid "Date"
+msgstr ""
+
+#: aleksis/apps/alsijil/tables.py:99
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:21
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126
+msgid "Period"
+msgstr ""
+
+#: aleksis/apps/alsijil/tables.py:111
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:131
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:257
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:336
+msgid "Teachers"
+msgstr ""
+
+#: aleksis/apps/alsijil/tables.py:118
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:160
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:16
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:39
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:114
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323
+msgid "Tardiness"
+msgstr ""
+
+#: aleksis/apps/alsijil/tables.py:119
+msgid "Excuse"
+msgstr ""
+
+#: aleksis/apps/alsijil/tables.py:156
+#, python-brace-format
+msgid "{value}' late"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register.html:5
+#: aleksis/apps/alsijil/templates/alsijil/absences/register.html:6
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:30
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:385
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:138
+msgid "Register absence"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:5
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:6
+msgid "Confirm: Register absence"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:10
+msgid ""
+"\n"
+"      Do you really want to register the following absence?\n"
+"    "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:26
+msgid ""
+"\n"
+"                As the length of this absence is longer than one day,\n"
+"                please double check the correctness of your entry.\n"
+"              "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:35
+#, python-format
+msgid " %(count)s affected lessons "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:40
+msgid ""
+"\n"
+"                  There are no affected lessons. Registering this absence won't have any effect.\n"
+"                "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:57
+msgid "Reset status to 'not absent'"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:79
+msgid "Cancel"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:21
+msgid "Students"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:35
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:76
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:78
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90
+msgid "Students list"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:39
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:72
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:81
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:27
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:43
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:16
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:35
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:6
+msgid "Week view"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:45
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:90
+msgid "Roles"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:51
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:31
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:50
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:20
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:42
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:97
+msgid "Generate printout"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:59
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:104
+msgid "No groups available."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:71
+msgid "students"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:5
+msgid "Lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:28
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:27
+msgid "Persons"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:36
+msgid "Seating plan"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:46
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:94
+msgid "Previous"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:54
+msgid "More"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:87
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:93
+msgid "My previous lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:104
+msgid "My next lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:105
+msgid "Next"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:161
+msgid ""
+"\n"
+"                  This lesson overlaps with holidays and can't be edited.\n"
+"                "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:10
+msgid "Class register: person"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:18
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:10
+msgid "Back"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:22
+#, python-format
+msgid ""
+"\n"
+"      Class register overview for %(person)s\n"
+"    "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:50
+msgid "Statistics"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:65
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:344
+msgid "Relevant personal notes"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:68
+msgid "Filter personal notes"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:73
+msgid "Clear all filters"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:76
+msgid "Close"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:79
+msgid "Filter"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:91
+msgid "Filter results"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:119
+msgid "Statistics on absences, tardiness and remarks"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:128
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:14
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:80
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:291
+msgid "Absences"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:138
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:296
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:302
+msgid "thereof"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:140
+msgid "Without Excuse Type"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:150
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:102
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:81
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:313
+msgid "Unexcused"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:5
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:12
+#, python-format
+msgid "Students list: %(group)s"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:54
+msgid "Select"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:62
+msgid "Toggle filters"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:69
+#, python-format
+msgid ""
+"CW %(week)s:\n"
+"      %(instance)s"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:293
+msgid "Unfold"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:360
+msgid "Visit lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:398
+msgid "unexcused"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:401
+msgid "Summed up tardiness"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:404
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:117
+msgid "Count of tardiness"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:436
+msgid "No lessons available"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:439
+msgid ""
+"\n"
+"            There are no lessons for the selected group or teacher in this week.\n"
+"          "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/create.html:6
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/create.html:7
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html:18
+msgid "Create excuse type"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/edit.html:6
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/edit.html:7
+msgid "Edit excuse type"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html:4
+#: aleksis/apps/alsijil/templates/alsijil/group_role/warning.html:4
+msgid ""
+"\n"
+"    This function should only be used to define alternatives to the default excuse which also will be counted extra.\n"
+"    Don't use this to create a default excuse or if you don't divide between different types of excuse.\n"
+"  "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14
+msgid "Create extra mark"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7
+msgid "Edit extra mark"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16
+#, python-format
+msgid "Assign group role for %(group)s"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:34
+msgid "Assign"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:9
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:12
+#, python-format
+msgid "Group roles for %(group)s"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:28
+msgid "Back to my groups"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:36
+msgid "Assign a role to a person"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:45
+msgid "Current roles"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:48
+msgid "All assignments"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:66
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:83
+msgid "Actions"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/create.html:6
+#: aleksis/apps/alsijil/templates/alsijil/group_role/create.html:7
+#: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:16
+msgid "Create group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/edit.html:6
+#: aleksis/apps/alsijil/templates/alsijil/group_role/edit.html:7
+msgid "Edit group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/edit_assignment.html:7
+#: aleksis/apps/alsijil/templates/alsijil/group_role/edit_assignment.html:8
+msgid "Edit group role assignment"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assigned_roles.html:31
+msgid "No one assigned."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assigned_roles.html:41
+msgid ""
+"\n"
+"    You can get some additional actions for each group role assignment if you click on the name of the\n"
+"    corresponding person.\n"
+"  "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:21
+msgid "Stop"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/notifications/check.html:1
+msgid "Please check if the following class register entries are complete and correct:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/absences.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:22
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:27
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:50
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:139
+msgid "(e)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/absences.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:14
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:56
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:143
+msgid "(u)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:4
+msgid "Legend"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:7
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:71
+msgid "General"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:10
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:137
+msgid "(a)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:14
+msgid "Unexcused absences"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:18
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:26
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:49
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:138
+msgid "Sum (e)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:18
+msgid "Sum of excused absences"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:22
+msgid "Regular excused absences"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:41
+msgid "Excuse types (not counted as absent)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:28
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:42
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:7
+#, python-format
+msgid "%(period)s. period"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:31
+#, python-format
+msgid ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  period\n"
+"          "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:8
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:136
+msgid "Save"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:19
+#, python-format
+msgid ""
+"\n"
+"        Previous %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:30
+#, python-format
+msgid ""
+"\n"
+"        Next %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html:13
+msgid "Change history"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:59
+msgid "Tardiness (in m)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:6
+msgid "Overview: Previous lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:13
+msgid "Lesson topic of previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:20
+msgid "Homework for this lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:27
+msgid "Group notes for previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:34
+msgid "Absent persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:41
+msgid "Late persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:8
+#, python-format
+msgid ""
+"Seating plan for %(group)s in\n"
+"          %(room)s"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:14
+#, python-format
+msgid ""
+"\n"
+"            This seating plan is taken from the parent group of %(child_group)s.\n"
+"            If you want, you can take it over for your group and then customize it.\n"
+"          "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:30
+msgid "Edit seating plan"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:37
+msgid "Copy plan and edit"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:56
+msgid "There is no seating plan for this lesson."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:64
+#, python-format
+msgid ""
+"\n"
+"                  Create a new seating plan for %(group)s (%(subject)s) in %(room)s\n"
+"                "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:78
+#, python-format
+msgid ""
+"\n"
+"                    Create a new seating plan for %(group)s in %(room)s\n"
+"                  "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:6
+msgid "Data complete"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:17
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:30
+msgid "Missing data"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:19
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:32
+msgid "Pending"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:28
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:466
+msgid "Lesson cancelled"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:34
+msgid "Substitution"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html:4
+msgid "Lesson filter"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html:9
+msgid "Update filters"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html:22
+msgid "Lesson table"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html:31
+msgid "Execute"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:6
+msgid "No students available."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:13
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:24
+msgid "Primary group"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
+msgid "Uncounted Absences"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:48
+msgid "Sum"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:90
+msgid "Regular excused"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:130
+msgid "Show more details"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:131
+msgid "Details"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:6
+msgid "Class register:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:26
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:59
+msgid "Owners"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:30
+msgid "Printed on"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:38
+msgid ""
+"\n"
+"        This printout is intended for archival purposes. The main copy of\n"
+"        the class register is stored in the AlekSIS School Information\n"
+"        System.\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:45
+msgid ""
+"\n"
+"        Copies of the class register, both digital and as printout, must\n"
+"        only be kept inside the school and/or on devices authorised by the\n"
+"        school.\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:52
+msgid ""
+"\n"
+"        The owner of the group and the headteacher confirm the above, as\n"
+"        well as the correctness of this printout.\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:62
+msgid "Headteacher"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:69
+msgid "Abbreviations"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:78
+msgid "Late"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:89
+msgid "Custom excuse types"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:101
+msgid "Custom excuse types (not counted as absent)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:113
+msgid "Available extra marks"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:127
+msgid "Persons in group"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:132
+msgid "No."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:133
+msgid "Last name"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:134
+msgid "First name"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:135
+msgid "Sex"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:136
+msgid "Date of birth"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:147
+msgid "(b)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:184
+msgid "Teachers and lessons in group"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:191
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:222
+msgid "Lesson start"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:192
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:223
+msgid "Lesson end"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:193
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:224
+msgid "Per week"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:214
+msgid "Teachers and lessons in child groups"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:247
+msgid "Personal overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:249
+msgid "Contact details"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:288
+msgid "Absences and tardiness"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:303
+msgid "Without excuse type"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:349
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:419
+msgid "Pe."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:350
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:420
+msgid "Subj."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:351
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:424
+msgid "Te."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:353
+msgid "Tard."
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:381
+msgid "Yes"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:386
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:484
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:499
+msgid "e"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:413
+msgid "Week"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:423
+msgid "Notes"
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:118
+msgid "You either selected an invalid lesson or there is currently no lesson in progress."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:151
+msgid "You are not allowed to create a lesson documentation for a lesson in the future."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:266
+msgid "The lesson documentation has been saved."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:300
+msgid "The personal notes have been saved."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1079
+msgid "The absence has been saved."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1100
+msgid "The personal note has been deleted."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1122
+msgid "The extra mark has been created."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1134
+msgid "The extra mark has been saved."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1145
+msgid "The extra mark has been deleted."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1166
+msgid "The excuse type has been created."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1178
+msgid "The excuse type has been saved."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1189
+msgid "The excuse type has been deleted."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1210
+msgid "The group role has been created."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1222
+msgid "The group role has been saved."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1233
+msgid "The group role has been deleted."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1266 aleksis/apps/alsijil/views.py:1298
+msgid "The group role has been assigned."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1317
+msgid "The group role assignment has been saved."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1338
+msgid "The group role assignment has been stopped."
+msgstr ""
+
+#: aleksis/apps/alsijil/views.py:1351
+msgid "The group role assignment has been deleted."
+msgstr ""
diff --git a/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po
index c9fcfa46f7015bda5734a25052658daacf71e2fb..0f75a14f7e9b4a4ec0b20f5fe915794fbb6aa540 100644
--- a/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po
+++ b/aleksis/apps/alsijil/locale/tr_TR/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-08-28 17:33+0200\n"
+"POT-Creation-Date: 2021-12-24 13:24+0100\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"
@@ -109,10 +109,10 @@ msgstr ""
 msgid "Before"
 msgstr ""
 
-#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:293
+#: aleksis/apps/alsijil/filters.py:12 aleksis/apps/alsijil/forms.py:302
 #: aleksis/apps/alsijil/tables.py:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:106
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:202
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:227
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:169
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:200
 msgid "Subject"
@@ -130,99 +130,100 @@ msgstr ""
 msgid "Homework for the next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:72 aleksis/apps/alsijil/forms.py:208
-#: aleksis/apps/alsijil/forms.py:292
+#: aleksis/apps/alsijil/forms.py:73 aleksis/apps/alsijil/forms.py:214
+#: aleksis/apps/alsijil/forms.py:301
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:199
 msgid "Group"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:75
+#: aleksis/apps/alsijil/forms.py:79
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:170
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:201
 msgid "Teacher"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:90
+#: aleksis/apps/alsijil/forms.py:96
 msgid "You can't select a group and a teacher both."
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:144 aleksis/apps/alsijil/forms.py:294
-#: aleksis/apps/alsijil/models.py:446
+#: aleksis/apps/alsijil/forms.py:150 aleksis/apps/alsijil/forms.py:303
+#: aleksis/apps/alsijil/models.py:471
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64
 msgid "Start date"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:145 aleksis/apps/alsijil/forms.py:295
-#: aleksis/apps/alsijil/models.py:450
+#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/forms.py:304
+#: aleksis/apps/alsijil/models.py:475
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65
 msgid "End date"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:146
+#: aleksis/apps/alsijil/forms.py:152
 msgid "Start period"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:147
+#: aleksis/apps/alsijil/forms.py:153
 msgid "End period"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:148
+#: aleksis/apps/alsijil/forms.py:154 aleksis/apps/alsijil/tables.py:108
+#: aleksis/apps/alsijil/tables.py:129
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:263
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:339
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:397
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:75
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:312
 msgid "Absent"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:149 aleksis/apps/alsijil/tables.py:137
+#: aleksis/apps/alsijil/forms.py:155 aleksis/apps/alsijil/tables.py:137
 #: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:265
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:134
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:72
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:84
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:275
 msgid "Excused"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/models.py:62
-#: aleksis/apps/alsijil/models.py:232
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:266
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:307
+#: aleksis/apps/alsijil/forms.py:157 aleksis/apps/alsijil/models.py:62
+#: aleksis/apps/alsijil/models.py:236
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:31
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:72
 msgid "Excuse type"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:156
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:268
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:328
+#: aleksis/apps/alsijil/forms.py:162
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:93
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:314
 msgid "Remarks"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:218
+#: aleksis/apps/alsijil/forms.py:227
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:9
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:262
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:27
 msgid "Person"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:290
+#: aleksis/apps/alsijil/forms.py:299
 msgid "School term"
 msgstr ""
 
-#: aleksis/apps/alsijil/forms.py:291
+#: aleksis/apps/alsijil/forms.py:300
 msgid "Has lesson documentation"
 msgstr ""
 
-#: aleksis/apps/alsijil/managers.py:81 aleksis/apps/alsijil/tables.py:121
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:57
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:151
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:214
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:268
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:16
+#: aleksis/apps/alsijil/managers.py:88 aleksis/apps/alsijil/tables.py:121
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:176
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:240
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:316
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:50
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:21
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:335
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:415
-#: aleksis/apps/alsijil/util/alsijil_helpers.py:314
+#: aleksis/apps/alsijil/util/alsijil_helpers.py:315
 msgid "Event"
 msgstr ""
 
@@ -274,12 +275,12 @@ msgstr ""
 msgid "Excuse types"
 msgstr ""
 
-#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:237
-#: aleksis/apps/alsijil/models.py:401
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:267
+#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:241
+#: aleksis/apps/alsijil/models.py:423 aleksis/apps/alsijil/tables.py:111
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9
 #: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:41
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:17
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:293
 msgid "Extra marks"
@@ -289,164 +290,178 @@ msgstr ""
 msgid "Manage group roles"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:180
+#: aleksis/apps/alsijil/model_extensions.py:191
 msgid "Can view week overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:183
+#: aleksis/apps/alsijil/model_extensions.py:195
 msgid "Can view lesson overview of group class register"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:185
+#: aleksis/apps/alsijil/model_extensions.py:197
 msgid "Can view all personal notes of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:186
+#: aleksis/apps/alsijil/model_extensions.py:198
 msgid "Can edit all personal notes of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:188
+#: aleksis/apps/alsijil/model_extensions.py:200
 msgid "Can view all lesson documentation of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:191
+#: aleksis/apps/alsijil/model_extensions.py:203
 msgid "Can edit all lesson documentation of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:193
+#: aleksis/apps/alsijil/model_extensions.py:205
 msgid "Can view full register of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:195
+#: aleksis/apps/alsijil/model_extensions.py:207
 msgid "Can register an absence for all members of a group"
 msgstr ""
 
-#: aleksis/apps/alsijil/model_extensions.py:197
+#: aleksis/apps/alsijil/model_extensions.py:209
+msgid "Can assign a group role for this group"
+msgstr ""
+
+#: aleksis/apps/alsijil/model_extensions.py:210
 msgid "Can register an absence for a person"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:388
+#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:410
 msgid "Short name"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:389
-#: aleksis/apps/alsijil/models.py:413
+#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:411
+#: aleksis/apps/alsijil/models.py:435
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:22
 msgid "Name"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:303
+#: aleksis/apps/alsijil/models.py:216 aleksis/apps/alsijil/models.py:315
 msgid "Year"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:271
+#: aleksis/apps/alsijil/models.py:275
 msgid "Personal note"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:272
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:115
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:253
+#: aleksis/apps/alsijil/models.py:276
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:47
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:71
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:317
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:375
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:18
 msgid "Personal notes"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:315
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:150
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:108
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:237
+#: aleksis/apps/alsijil/models.py:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:263
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:342
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:26
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:381
 msgid "Lesson topic"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:316
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:158
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:109
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:243
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:289
+#: aleksis/apps/alsijil/models.py:328
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:133
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:269
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:347
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:34
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:382
 msgid "Homework"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:317
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:166
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:110
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:249
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:295
+#: aleksis/apps/alsijil/models.py:329
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:134
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:275
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:351
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:42
 msgid "Group note"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:363
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:111
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:141
+#: aleksis/apps/alsijil/models.py:376
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:17
 msgid "Lesson documentation"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:364
+#: aleksis/apps/alsijil/models.py:377
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:43
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:68
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:21
 msgid "Lesson documentations"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:400
+#: aleksis/apps/alsijil/models.py:422
 msgid "Extra mark"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:414
+#: aleksis/apps/alsijil/models.py:436
 msgid "Icon"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:415
+#: aleksis/apps/alsijil/models.py:437
 msgid "Colour"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:421 aleksis/apps/alsijil/models.py:435
+#: aleksis/apps/alsijil/models.py:443 aleksis/apps/alsijil/models.py:458
 #: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62
 msgid "Group role"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:422
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:128
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:75
+#: aleksis/apps/alsijil/models.py:444
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:34
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8
 #: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9
 msgid "Group roles"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:441
+#: aleksis/apps/alsijil/models.py:448
+msgid "Can assign group role"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:464
 msgid "Assigned person"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:444 aleksis/apps/alsijil/tables.py:98
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:104
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:220
+#: aleksis/apps/alsijil/models.py:469 aleksis/apps/alsijil/tables.py:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:128
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:246
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:326
 msgid "Groups"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:451
+#: aleksis/apps/alsijil/models.py:476
 msgid "Can be left empty if end date is not clear yet"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:466
+#: aleksis/apps/alsijil/models.py:491
 msgid "Group role assignment"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:467
+#: aleksis/apps/alsijil/models.py:492
 msgid "Group role assignments"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:474
+#: aleksis/apps/alsijil/models.py:499
+msgid "Can view lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:500
 msgid "Can view week overview"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:475
+#: aleksis/apps/alsijil/models.py:501
+msgid "Can view full register"
+msgstr ""
+
+#: aleksis/apps/alsijil/models.py:502
 msgid "Can register absence"
 msgstr ""
 
-#: aleksis/apps/alsijil/models.py:476
+#: aleksis/apps/alsijil/models.py:503
 msgid "Can list all personal note filters"
 msgstr ""
 
@@ -530,16 +545,28 @@ msgid "Date"
 msgstr ""
 
 #: aleksis/apps/alsijil/tables.py:95
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:102
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:17
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126
 msgid "Period"
 msgstr ""
 
 #: aleksis/apps/alsijil/tables.py:103
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:107
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:231
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:131
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:257
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:336
 msgid "Teachers"
 msgstr ""
 
+#: aleksis/apps/alsijil/tables.py:109
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
+msgid "Tardiness"
+msgstr ""
+
 #: aleksis/apps/alsijil/tables.py:110
 msgid "Excuse"
 msgstr ""
@@ -552,7 +579,7 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:5
 #: aleksis/apps/alsijil/templates/alsijil/absences/register.html:6
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:30
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:327
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:385
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:113
 msgid "Register absence"
 msgstr ""
@@ -603,13 +630,15 @@ msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:35
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:76
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:40
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:51
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:78
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90
 msgid "Students list"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:39
 #: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:60
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:69
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:27
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:43
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:16
@@ -629,8 +658,8 @@ msgstr ""
 #: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:50
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:20
 #: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:42
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:44
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:58
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:97
 msgid "Generate printout"
 msgstr ""
 
@@ -647,107 +676,39 @@ msgstr ""
 msgid "Lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:21
-msgid "Back to week view"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:24
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:27
+msgid "Persons"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:30
-msgid "My previous lesson"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:34
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:82
+msgid "Previous"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:39
-msgid "My next lesson"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:42
+msgid "More"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:51
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:187
-#, python-format
-msgid "%(period)s. period"
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:75
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:81
+msgid "My previous lesson"
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:86
-#, python-format
-msgid ""
-"\n"
-"            Previous %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:96
-#, python-format
-msgid ""
-"\n"
-"            Next %(subject)s lesson\n"
-"          "
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:122
-msgid "Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:132
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:380
-msgid "Change history"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:186
-msgid "Overview: Previous lesson"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:193
-msgid "Lesson topic of previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:200
-msgid "Homework for this lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:207
-msgid "Group notes for previous lesson:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:214
-msgid "Absent persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:221
-msgid "Late persons:"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:264
-#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:146
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:32
-#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:89
-#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:287
-msgid "Tardiness"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:293
-msgid "Tardiness (in m)"
-msgstr ""
-
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:399
-#, python-format
-msgid ""
-"\n"
-"              Previous %(subject)s lesson\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:92
+msgid "My next lesson"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:409
-#, python-format
-msgid ""
-"\n"
-"              Next %(subject)s lesson\n"
-"            "
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:93
+msgid "Next"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:425
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:143
 msgid ""
 "\n"
-"                This lesson overlaps with holidays and can't be edited.\n"
-"              "
+"                  This lesson overlaps with holidays and can't be edited.\n"
+"                "
 msgstr ""
 
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:10
@@ -792,6 +753,10 @@ msgstr ""
 msgid "Filter"
 msgstr ""
 
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:91
+msgid "Filter results"
+msgstr ""
+
 #: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:119
 msgid "Statistics on absences, tardiness and remarks"
 msgstr ""
@@ -823,35 +788,47 @@ msgstr ""
 msgid "Students list: %(group)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:23
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:54
 msgid "Select"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:31
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:62
+msgid "Toggle filters"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:69
 #, python-format
 msgid ""
 "CW %(week)s:\n"
 "      %(instance)s"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:340
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:293
+msgid "Unfold"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:360
+msgid "Visit lesson overview"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:398
 msgid "unexcused"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:343
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:401
 msgid "Summed up tardiness"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:346
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:404
 #: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:92
 msgid "Count of tardiness"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:377
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:436
 msgid "No lessons available"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:380
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:439
 msgid ""
 "\n"
 "            There are no lessons for the selected group or teacher in this week.\n"
@@ -993,26 +970,95 @@ msgstr ""
 msgid "Excused absences"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:28
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:42
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:7
+#, python-format
+msgid "%(period)s. period"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:31
+#, python-format
+msgid ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  period\n"
+"          "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:8
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:135
+msgid "Save"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:19
+#, python-format
+msgid ""
+"\n"
+"        Previous %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:30
+#, python-format
+msgid ""
+"\n"
+"        Next %(subject)s lesson\n"
+"      "
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html:13
+msgid "Change history"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:58
+msgid "Tardiness (in m)"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:6
+msgid "Overview: Previous lesson"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:13
+msgid "Lesson topic of previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:20
+msgid "Homework for this lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:27
+msgid "Group notes for previous lesson:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:34
+msgid "Absent persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:41
+msgid "Late persons:"
+msgstr ""
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:6
 msgid "Data complete"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:12
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:25
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:17
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:30
 msgid "Missing data"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:14
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:27
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:19
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:32
 msgid "Pending"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:23
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:28
 #: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:426
 msgid "Lesson cancelled"
 msgstr ""
 
-#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html:29
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:34
 msgid "Substitution"
 msgstr ""
 
@@ -1216,78 +1262,78 @@ msgstr ""
 msgid "Notes"
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:114
+#: aleksis/apps/alsijil/views.py:117
 msgid "You either selected an invalid lesson or there is currently no lesson in progress."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:147
+#: aleksis/apps/alsijil/views.py:150
 msgid "You are not allowed to create a lesson documentation for a lesson in the future."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:241
+#: aleksis/apps/alsijil/views.py:246
 msgid "The lesson documentation has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:275
+#: aleksis/apps/alsijil/views.py:280
 msgid "The personal notes have been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1031
+#: aleksis/apps/alsijil/views.py:1049
 msgid "The absence has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1052
+#: aleksis/apps/alsijil/views.py:1070
 msgid "The personal note has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1074
+#: aleksis/apps/alsijil/views.py:1092
 msgid "The extra mark has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1086
+#: aleksis/apps/alsijil/views.py:1104
 msgid "The extra mark has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1097
+#: aleksis/apps/alsijil/views.py:1115
 msgid "The extra mark has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1118
+#: aleksis/apps/alsijil/views.py:1136
 msgid "The excuse type has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1130
+#: aleksis/apps/alsijil/views.py:1148
 msgid "The excuse type has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1141
+#: aleksis/apps/alsijil/views.py:1159
 msgid "The excuse type has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1162
+#: aleksis/apps/alsijil/views.py:1180
 msgid "The group role has been created."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1174
+#: aleksis/apps/alsijil/views.py:1192
 msgid "The group role has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1185
+#: aleksis/apps/alsijil/views.py:1203
 msgid "The group role has been deleted."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1218 aleksis/apps/alsijil/views.py:1250
+#: aleksis/apps/alsijil/views.py:1236 aleksis/apps/alsijil/views.py:1268
 msgid "The group role has been assigned."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1269
+#: aleksis/apps/alsijil/views.py:1287
 msgid "The group role assignment has been saved."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1290
+#: aleksis/apps/alsijil/views.py:1308
 msgid "The group role assignment has been stopped."
 msgstr ""
 
-#: aleksis/apps/alsijil/views.py:1303
+#: aleksis/apps/alsijil/views.py:1321
 msgid "The group role assignment has been deleted."
 msgstr ""
diff --git a/aleksis/apps/alsijil/locale/uk/LC_MESSAGES/django.po b/aleksis/apps/alsijil/locale/uk/LC_MESSAGES/django.po
new file mode 100644
index 0000000000000000000000000000000000000000..9375b86c3d4dd90ab2cd0f6e76eebad2b5e65b9f
--- /dev/null
+++ b/aleksis/apps/alsijil/locale/uk/LC_MESSAGES/django.po
@@ -0,0 +1,1526 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-04-23 12:35+0000\n"
+"PO-Revision-Date: 2022-05-18 23:27+0000\n"
+"Last-Translator: Serhii Horichenko <m@sgg.im>\n"
+"Language-Team: Ukrainian <https://translate.edugit.org/projects/aleksis/"
+"aleksis-app-alsijil/uk/>\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 "
+"? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > "
+"14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % "
+"100 >=11 && n % 100 <=14 )) ? 2: 3);\n"
+"X-Generator: Weblate 4.12.1\n"
+
+#: aleksis/apps/alsijil/actions.py:18
+msgid "Mark as excused"
+msgstr "Позначити як пояснений"
+
+#: aleksis/apps/alsijil/actions.py:25
+msgid "Mark as unexcused"
+msgstr "Позначити як непояснений"
+
+#: aleksis/apps/alsijil/actions.py:32
+#, python-brace-format
+msgid "Mark as {excuse_type.name}"
+msgstr "Позначити як {excuse_type.name}"
+
+#: aleksis/apps/alsijil/actions.py:48 aleksis/apps/alsijil/tables.py:29
+#: aleksis/apps/alsijil/tables.py:53 aleksis/apps/alsijil/tables.py:78
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:29
+msgid "Delete"
+msgstr "Видалити"
+
+#: aleksis/apps/alsijil/actions.py:68
+msgid "{} asks you to check some class register entries."
+msgstr "{} просить тебе перевірити деякі записи класного журналу."
+
+#: aleksis/apps/alsijil/actions.py:86
+#, python-brace-format
+msgid "We have successfully sent notifications to {count_teachers} persons for {count_items} lessons."
+msgstr ""
+"Ми надіслали сповіщення для {count_teachers} осіб щодо {count_items} уроків."
+
+#: aleksis/apps/alsijil/actions.py:92
+msgid "Ask teacher to check data"
+msgstr "Попросити вчителя перевірити дані"
+
+#: aleksis/apps/alsijil/data_checks.py:12
+msgid "Delete object"
+msgstr "Видалити об'єкт"
+
+#: aleksis/apps/alsijil/data_checks.py:22
+msgid "Set current groups"
+msgstr "Встановити поточні групи"
+
+#: aleksis/apps/alsijil/data_checks.py:33
+msgid "Reset personal note to defaults"
+msgstr "Скинути персональні нотатки на типові"
+
+#: aleksis/apps/alsijil/data_checks.py:45
+msgid "Ensure that there are no personal notes in cancelled lessons"
+msgstr "Переконайтеся, щоб у скасованих уроках не було особистих нотаток"
+
+#: aleksis/apps/alsijil/data_checks.py:46
+msgid "The personal note is related to a cancelled lesson."
+msgstr "У скасованого уроку є пов'язані особисті нотатки."
+
+#: aleksis/apps/alsijil/data_checks.py:73
+msgid "Ensure that 'groups_of_person' is set for every personal note"
+msgstr ""
+"Переконайтеся, що для кожної особистої нотатки установлені \"групи_осіб\""
+
+#: aleksis/apps/alsijil/data_checks.py:74
+msgid "The personal note has no group in 'groups_of_person'."
+msgstr "Ця особиста нотатка не має групи у \"групі_осіб\"."
+
+#: aleksis/apps/alsijil/data_checks.py:99
+msgid "Ensure that there are no filled out lesson documentations on holidays"
+msgstr "Переконайтеся, що на вихідні немає заповненого учбового матеріалу"
+
+#: aleksis/apps/alsijil/data_checks.py:100
+msgid "The lesson documentation is on holidays."
+msgstr "Цей учбовий матеріал є на вихідних."
+
+#: aleksis/apps/alsijil/data_checks.py:133
+msgid "Ensure that there are no filled out personal notes on holidays"
+msgstr "Переконайтеся, що на вихідні немає заповнених особистих нотаток"
+
+#: aleksis/apps/alsijil/data_checks.py:134
+msgid "The personal note is on holidays."
+msgstr "Ці особисті нотатки є на вихідних."
+
+#: aleksis/apps/alsijil/data_checks.py:162
+msgid "Ensure that there are no excused personal notes without an absence"
+msgstr "Переконайтеся, що немає особистих нотаток щодо пояснення без пропусків"
+
+#: aleksis/apps/alsijil/data_checks.py:163
+msgid "The personal note is marked as excused, but not as absent."
+msgstr "Ця персональна нотатка відмічена як пояснення, але не як пропуск."
+
+#: aleksis/apps/alsijil/filters.py:12
+msgid "After"
+msgstr "Після"
+
+#: aleksis/apps/alsijil/filters.py:13
+msgid "Before"
+msgstr "Перед"
+
+#: aleksis/apps/alsijil/filters.py:14 aleksis/apps/alsijil/forms.py:302
+#: aleksis/apps/alsijil/tables.py:116
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:227
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:189
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:220
+msgid "Subject"
+msgstr "Предмет"
+
+#: aleksis/apps/alsijil/filters.py:30
+msgid "Tardiness is lower than"
+msgstr "Запізнення менше ніж на"
+
+#: aleksis/apps/alsijil/filters.py:31
+msgid "Tardiness is bigger than"
+msgstr "Запізнення більше ніж на"
+
+#: aleksis/apps/alsijil/forms.py:47
+msgid "Homework for the next lesson"
+msgstr "Домашня робота на наступний урок"
+
+#: aleksis/apps/alsijil/forms.py:73 aleksis/apps/alsijil/forms.py:214
+#: aleksis/apps/alsijil/forms.py:301
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:219
+msgid "Group"
+msgstr "Група"
+
+#: aleksis/apps/alsijil/forms.py:79
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:190
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:221
+msgid "Teacher"
+msgstr "Викладач"
+
+#: aleksis/apps/alsijil/forms.py:96
+msgid "You can't select a group and a teacher both."
+msgstr "Ви не можете обрати одночасно групу та викладача."
+
+#: aleksis/apps/alsijil/forms.py:150 aleksis/apps/alsijil/forms.py:303
+#: aleksis/apps/alsijil/models.py:480
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:64
+msgid "Start date"
+msgstr "Дата початку"
+
+#: aleksis/apps/alsijil/forms.py:151 aleksis/apps/alsijil/forms.py:304
+#: aleksis/apps/alsijil/models.py:484
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:65
+msgid "End date"
+msgstr "Дата закінчення"
+
+#: aleksis/apps/alsijil/forms.py:152
+msgid "Start period"
+msgstr "Початок уроків"
+
+#: aleksis/apps/alsijil/forms.py:153
+msgid "End period"
+msgstr "Закінчення уроків"
+
+#: aleksis/apps/alsijil/forms.py:154 aleksis/apps/alsijil/tables.py:117
+#: aleksis/apps/alsijil/tables.py:138
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:50
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:397
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:29
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:75
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:352
+msgid "Absent"
+msgstr "Відсутній(-я)"
+
+#: aleksis/apps/alsijil/forms.py:155 aleksis/apps/alsijil/tables.py:146
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:54
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:134
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:31
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:85
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:84
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:297
+msgid "Excused"
+msgstr "Пояснено"
+
+#: aleksis/apps/alsijil/forms.py:157 aleksis/apps/alsijil/models.py:71
+#: aleksis/apps/alsijil/models.py:245
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:32
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:73
+msgid "Excuse type"
+msgstr "Тип пояснення"
+
+#: aleksis/apps/alsijil/forms.py:162
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:34
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:94
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:354
+msgid "Remarks"
+msgstr "Зауваження"
+
+#: aleksis/apps/alsijil/forms.py:227
+#: aleksis/apps/alsijil/templates/alsijil/absences/register.html:9
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:63
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:28
+msgid "Person"
+msgstr "Особа"
+
+#: aleksis/apps/alsijil/forms.py:299
+msgid "School term"
+msgstr "Навчальний рік"
+
+#: aleksis/apps/alsijil/forms.py:300
+msgid "Has lesson documentation"
+msgstr "Має учбовий матеріал"
+
+#: aleksis/apps/alsijil/managers.py:88 aleksis/apps/alsijil/tables.py:130
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:176
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:240
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:316
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:50
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:21
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:375
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:455
+#: aleksis/apps/alsijil/util/alsijil_helpers.py:315
+msgid "Event"
+msgstr "Подія"
+
+#: aleksis/apps/alsijil/menus.py:6 aleksis/apps/alsijil/preferences.py:9
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:16
+msgid "Class register"
+msgstr "Класний журнал"
+
+#: aleksis/apps/alsijil/menus.py:16
+msgid "Current lesson"
+msgstr "Поточний урок"
+
+#: aleksis/apps/alsijil/menus.py:27
+msgid "Current week"
+msgstr "Поточний тиждень"
+
+#: aleksis/apps/alsijil/menus.py:38
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:5
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:8
+msgid "My groups"
+msgstr "Мої групи"
+
+#: aleksis/apps/alsijil/menus.py:49
+msgid "My overview"
+msgstr "Мій огляд"
+
+#: aleksis/apps/alsijil/menus.py:60
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:5
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:9
+msgid "My students"
+msgstr "Мої студенти"
+
+#: aleksis/apps/alsijil/menus.py:71
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:11
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:18
+msgid "Assign group role"
+msgstr "Призначити роль групи"
+
+#: aleksis/apps/alsijil/menus.py:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/all_objects.html:5
+#: aleksis/apps/alsijil/templates/alsijil/class_register/all_objects.html:8
+msgid "All lessons"
+msgstr "Усі уроки"
+
+#: aleksis/apps/alsijil/menus.py:93 aleksis/apps/alsijil/models.py:72
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html:8
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html:9
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:30
+msgid "Excuse types"
+msgstr "Типи пояснень"
+
+#: aleksis/apps/alsijil/menus.py:104 aleksis/apps/alsijil/models.py:250
+#: aleksis/apps/alsijil/models.py:432 aleksis/apps/alsijil/tables.py:120
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:8
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:9
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:57
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:18
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:331
+msgid "Extra marks"
+msgstr "Додаткові відмітки"
+
+#: aleksis/apps/alsijil/menus.py:115
+msgid "Manage group roles"
+msgstr "Керування ролями групи"
+
+#: aleksis/apps/alsijil/model_extensions.py:190
+msgid "Can view week overview of group class register"
+msgstr "Може бачити класний журнал групи за тиждень"
+
+#: aleksis/apps/alsijil/model_extensions.py:194
+msgid "Can view lesson overview of group class register"
+msgstr "Може бачити класний журнал групи за урок"
+
+#: aleksis/apps/alsijil/model_extensions.py:196
+msgid "Can view all personal notes of a group"
+msgstr "Може бачити усі особисті нотатки групи"
+
+#: aleksis/apps/alsijil/model_extensions.py:197
+msgid "Can edit all personal notes of a group"
+msgstr "Може редагувати усі особисті нотатки групи"
+
+#: aleksis/apps/alsijil/model_extensions.py:199
+msgid "Can view all lesson documentation of a group"
+msgstr "Може бачити увесь учбовий матеріал групи"
+
+#: aleksis/apps/alsijil/model_extensions.py:202
+msgid "Can edit all lesson documentation of a group"
+msgstr "Може редагувати увесь учбовий матеріал групи"
+
+#: aleksis/apps/alsijil/model_extensions.py:204
+msgid "Can view full register of a group"
+msgstr "Може бачити класний журнал групи без обмежень"
+
+#: aleksis/apps/alsijil/model_extensions.py:206
+msgid "Can register an absence for all members of a group"
+msgstr "Може реєструвати пропуски для усіх учасників групи"
+
+#: aleksis/apps/alsijil/model_extensions.py:208
+msgid "Can assign a group role for this group"
+msgstr "Може призначати роль групи для цієї групи"
+
+#: aleksis/apps/alsijil/model_extensions.py:209
+msgid "Can register an absence for a person"
+msgstr "Може реєструвати відсутність особи"
+
+#: aleksis/apps/alsijil/models.py:50 aleksis/apps/alsijil/models.py:419
+msgid "Short name"
+msgstr "Коротке ім'я"
+
+#: aleksis/apps/alsijil/models.py:51 aleksis/apps/alsijil/models.py:420
+#: aleksis/apps/alsijil/models.py:444
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:20
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:12
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:23
+msgid "Name"
+msgstr "Повне ім'я"
+
+#: aleksis/apps/alsijil/models.py:55 aleksis/apps/alsijil/tables.py:41
+msgid "Count as absent"
+msgstr "Кількість відсутніх"
+
+#: aleksis/apps/alsijil/models.py:57
+msgid "If checked, this excuse type will be counted as a missed lesson. If not checked,it won't show up in the absence report."
+msgstr ""
+"Якщо відмічено, цей тип пояснення буде зарахований як пропущений урок. Якщо "
+"не відмічено, то без запису у звіт відсутності."
+
+#: aleksis/apps/alsijil/models.py:225 aleksis/apps/alsijil/models.py:324
+msgid "Year"
+msgstr "Рік"
+
+#: aleksis/apps/alsijil/models.py:284
+msgid "Personal note"
+msgstr "Особиста нотатка"
+
+#: aleksis/apps/alsijil/models.py:285
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:47
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:375
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:22
+msgid "Personal notes"
+msgstr "Особисті нотатки"
+
+#: aleksis/apps/alsijil/models.py:336
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:263
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:342
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:26
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:421
+msgid "Lesson topic"
+msgstr "Тема уроку"
+
+#: aleksis/apps/alsijil/models.py:337
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:133
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:269
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:347
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:34
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:422
+msgid "Homework"
+msgstr "Домашня робота"
+
+#: aleksis/apps/alsijil/models.py:338
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:134
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:275
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:351
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:42
+msgid "Group note"
+msgstr "Групова нотатка"
+
+#: aleksis/apps/alsijil/models.py:385
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html:17
+msgid "Lesson documentation"
+msgstr "Учбовий матеріал"
+
+#: aleksis/apps/alsijil/models.py:386
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:43
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:21
+msgid "Lesson documentations"
+msgstr "Учбові матеріали"
+
+#: aleksis/apps/alsijil/models.py:431
+msgid "Extra mark"
+msgstr "Додаткова відмітка"
+
+#: aleksis/apps/alsijil/models.py:445
+msgid "Icon"
+msgstr "Іконка"
+
+#: aleksis/apps/alsijil/models.py:446
+msgid "Colour"
+msgstr "Колір"
+
+#: aleksis/apps/alsijil/models.py:452 aleksis/apps/alsijil/models.py:467
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:62
+msgid "Group role"
+msgstr "Роль групи"
+
+#: aleksis/apps/alsijil/models.py:453
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:34
+#: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:8
+#: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:9
+msgid "Group roles"
+msgstr "Ролі груп"
+
+#: aleksis/apps/alsijil/models.py:457
+msgid "Can assign group role"
+msgstr "Може призначати роль групи"
+
+#: aleksis/apps/alsijil/models.py:473
+msgid "Assigned person"
+msgstr "Призначена особа"
+
+#: aleksis/apps/alsijil/models.py:478 aleksis/apps/alsijil/tables.py:105
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:128
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:246
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:326
+msgid "Groups"
+msgstr "Групи"
+
+#: aleksis/apps/alsijil/models.py:485
+msgid "Can be left empty if end date is not clear yet"
+msgstr "Якщо немає точної кінцевої дати, можна залишити порожнім"
+
+#: aleksis/apps/alsijil/models.py:500
+msgid "Group role assignment"
+msgstr "Призначення ролі групи"
+
+#: aleksis/apps/alsijil/models.py:501
+msgid "Group role assignments"
+msgstr "Призначення ролі групи"
+
+#: aleksis/apps/alsijil/models.py:508
+msgid "Can view lesson overview"
+msgstr "Може бачити огляд уроку"
+
+#: aleksis/apps/alsijil/models.py:509
+msgid "Can view week overview"
+msgstr "Може бачити огляд тижня"
+
+#: aleksis/apps/alsijil/models.py:510
+msgid "Can view full register"
+msgstr "Може бачити повний журнал"
+
+#: aleksis/apps/alsijil/models.py:511
+msgid "Can register absence"
+msgstr "Може реєструвати пропуск"
+
+#: aleksis/apps/alsijil/models.py:512
+msgid "Can list all personal note filters"
+msgstr "Може бачити усі фільтри особистих нотаток"
+
+#: aleksis/apps/alsijil/preferences.py:17
+msgid "Block adding personal notes for cancelled lessons"
+msgstr "Блокувати додавання особистих нотаток до скасованих уроків"
+
+#: aleksis/apps/alsijil/preferences.py:25
+msgid "Allow users to view their own personal notes"
+msgstr "Дозволити користувачам переглядати власні особисті нотатки"
+
+#: aleksis/apps/alsijil/preferences.py:34
+msgid "Allow primary group owners to register future absences for students in their groups"
+msgstr ""
+"Дозволити власникам основних груп реєструвати майбутні пропуски студентів у "
+"їх групах"
+
+#: aleksis/apps/alsijil/preferences.py:43
+msgid "Allow original teachers to edit their lessons although they are substituted"
+msgstr ""
+"Дозволити початковим викладачам навіть після їх заміни редагувати свої уроки"
+
+#: aleksis/apps/alsijil/preferences.py:52
+msgid "Carry over data from first lesson period to the following lesson periods in lessons over multiple periods"
+msgstr ""
+"Переносити дані з першого уроку в розкладі на поточні уроки через декілька "
+"уроків"
+
+#: aleksis/apps/alsijil/preferences.py:55
+msgid "This will carry over data only if the data in the following periods are empty."
+msgstr "Це перенесе дані лише в тому разі, коли в поточних уроках даних немає."
+
+#: aleksis/apps/alsijil/preferences.py:63
+msgid "Carry over personal notes to all following lesson periods on the same day."
+msgstr "Переносити особисті нотатки до всіх наступних уроків того ж дня."
+
+#: aleksis/apps/alsijil/preferences.py:72
+msgid "Allow teachers to open lesson periods on the same day and not just at the beginning of the period"
+msgstr ""
+"Дозволити викладачам відкривати уроки того самого дня і не лише на початку "
+"уроків"
+
+#: aleksis/apps/alsijil/preferences.py:76
+msgid "Lessons in the past are not affected by this setting, you can open them whenever you want."
+msgstr ""
+"Ці налаштування не впливають на минулі уроки. Ви можете відкривати їх "
+"будь-коли."
+
+#: aleksis/apps/alsijil/preferences.py:85
+msgid "Allow teachers to add data for lessons in holidays"
+msgstr ""
+"Дозволити викладачам додавати навчальний матеріал (дані для уроків) на "
+"вихідних"
+
+#: aleksis/apps/alsijil/preferences.py:94
+msgid "Allow group owners to assign group roles to the parents of the group's members"
+msgstr "Дозволити власникам груп призначати ролі груп батькам учасників груп"
+
+#: aleksis/apps/alsijil/preferences.py:103
+msgid "Show assigned group roles in week view"
+msgstr "Показати призначені ролі груп у тижневому огляді"
+
+#: aleksis/apps/alsijil/preferences.py:104
+msgid "Only week view of groups"
+msgstr "Лише тижневі огляди груп"
+
+#: aleksis/apps/alsijil/preferences.py:112
+msgid "Show assigned group roles in lesson view"
+msgstr "Показати призначені ролі груп в огляді уроку"
+
+#: aleksis/apps/alsijil/preferences.py:122
+msgid "Items per page in lessons table"
+msgstr "Кількість записів у розкладі на сторінку"
+
+#: aleksis/apps/alsijil/preferences.py:126
+msgid "Each page must show at least one item."
+msgstr "Кожна сторінка повинна мати принаймні один запис."
+
+#: aleksis/apps/alsijil/preferences.py:134
+msgid "Filter lessons by existence of their lesson documentation on default"
+msgstr "Типово фільтувати уроки за наявністю у них учбового матеріалу"
+
+#: aleksis/apps/alsijil/tables.py:23 aleksis/apps/alsijil/tables.py:47
+#: aleksis/apps/alsijil/tables.py:72
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:13
+msgid "Edit"
+msgstr "Редагувати"
+
+#: aleksis/apps/alsijil/tables.py:96
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:348
+msgid "Date"
+msgstr "Дата"
+
+#: aleksis/apps/alsijil/tables.py:99
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:21
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:126
+msgid "Period"
+msgstr "Урок"
+
+#: aleksis/apps/alsijil/tables.py:111
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:131
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:257
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:336
+msgid "Teachers"
+msgstr "Викладачі"
+
+#: aleksis/apps/alsijil/tables.py:118
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:160
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:30
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:16
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:39
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:114
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:323
+msgid "Tardiness"
+msgstr "Запізнення"
+
+#: aleksis/apps/alsijil/tables.py:119
+msgid "Excuse"
+msgstr "Пояснення"
+
+#: aleksis/apps/alsijil/tables.py:156
+#, python-brace-format
+msgid "{value}' late"
+msgstr "{value}' затримка"
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register.html:5
+#: aleksis/apps/alsijil/templates/alsijil/absences/register.html:6
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:30
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:385
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:138
+msgid "Register absence"
+msgstr "Реєстрація відсутності"
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:5
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:6
+msgid "Confirm: Register absence"
+msgstr "Підтвердження: Реєстрація відсутності"
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:10
+msgid ""
+"\n"
+"      Do you really want to register the following absence?\n"
+"    "
+msgstr ""
+"\n"
+"      Ви дійсно хочете зареєструвати цей пропуск?\n"
+"    "
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:26
+msgid ""
+"\n"
+"                As the length of this absence is longer than one day,\n"
+"                please double check the correctness of your entry.\n"
+"              "
+msgstr ""
+"\n"
+"                Оскільки пропуск більше одного дня,\n"
+"                переконайтеся, будь ласка, двічі у точності вашого запису.\n"
+"              "
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:35
+#, python-format
+msgid " %(count)s affected lessons "
+msgstr " %(count)s залежних уроків "
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:40
+msgid ""
+"\n"
+"                  There are no affected lessons. Registering this absence won't have any effect.\n"
+"                "
+msgstr ""
+"\n"
+"                  Залежних уроків немає. Реєстрація пропуску ні на що не "
+"впливає.\n"
+"                "
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:57
+msgid "Reset status to 'not absent'"
+msgstr "Скинути статус на 'не відсутній'"
+
+#: aleksis/apps/alsijil/templates/alsijil/absences/register_confirm.html:79
+msgid "Cancel"
+msgstr "Скасувати"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:21
+msgid "Students"
+msgstr "Студенти"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:35
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:76
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:78
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:90
+msgid "Students list"
+msgstr "Список студентів"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:39
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:72
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:81
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:27
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:43
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:16
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:35
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:6
+msgid "Week view"
+msgstr "Тижневий огляд"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:45
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:90
+msgid "Roles"
+msgstr "Ролі"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:51
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:31
+#: aleksis/apps/alsijil/templates/alsijil/class_register/persons.html:50
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:20
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:42
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:82
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:97
+msgid "Generate printout"
+msgstr "Підготувати для друку"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:59
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:104
+msgid "No groups available."
+msgstr "Групи не доступні."
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/groups.html:71
+msgid "students"
+msgstr "студенти"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:5
+msgid "Lesson"
+msgstr "Урок"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:28
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:27
+msgid "Persons"
+msgstr "Особи"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:36
+msgid "Seating plan"
+msgstr "План розміщення"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:46
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:94
+msgid "Previous"
+msgstr "Попередній"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:54
+msgid "More"
+msgstr "Ще"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:87
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:93
+msgid "My previous lesson"
+msgstr "Мій попередній урок"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:98
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:104
+msgid "My next lesson"
+msgstr "Мій наступний урок"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:105
+msgid "Next"
+msgstr "Наступний"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html:161
+msgid ""
+"\n"
+"                  This lesson overlaps with holidays and can't be edited.\n"
+"                "
+msgstr ""
+"\n"
+"                  Цей урок перекриває вихідні і його не можна редагувати.\n"
+"                "
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:10
+msgid "Class register: person"
+msgstr "Класний журнал: особа"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:18
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:10
+msgid "Back"
+msgstr "Назад"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:22
+#, python-format
+msgid ""
+"\n"
+"      Class register overview for %(person)s\n"
+"    "
+msgstr ""
+"\n"
+"      Огляд класного журналу для %(person)s\n"
+"    "
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:50
+msgid "Statistics"
+msgstr "Статистика"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:65
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:344
+msgid "Relevant personal notes"
+msgstr "Відповідні особисті нотатки"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:68
+msgid "Filter personal notes"
+msgstr "Фільтрувати особисті нотатки"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:73
+msgid "Clear all filters"
+msgstr "Очистити фільтри"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:76
+msgid "Close"
+msgstr "Закрити"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:79
+msgid "Filter"
+msgstr "Фільтри"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:91
+msgid "Filter results"
+msgstr "Результат фільтрів"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:119
+msgid "Statistics on absences, tardiness and remarks"
+msgstr "Статистика пропусків, запізнень та зауважень"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:128
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:14
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:25
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:80
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:291
+msgid "Absences"
+msgstr "Відсутності"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:132
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:138
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:296
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:302
+msgid "thereof"
+msgstr "отже"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:140
+msgid "Without Excuse Type"
+msgstr "Без Типу Пояснення"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/person.html:150
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:102
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:81
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:313
+msgid "Unexcused"
+msgstr "Необґрунтоване"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:5
+#: aleksis/apps/alsijil/templates/alsijil/class_register/students_list.html:12
+#, python-format
+msgid "Students list: %(group)s"
+msgstr "Список студентів: %(group)s"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:54
+msgid "Select"
+msgstr "Обрати"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:62
+msgid "Toggle filters"
+msgstr "Перемикнути фільтри"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:69
+#, python-format
+msgid ""
+"CW %(week)s:\n"
+"      %(instance)s"
+msgstr ""
+"ТЖ %(week)s:\n"
+"      %(instance)s"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:293
+msgid "Unfold"
+msgstr "Розгорнути"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:360
+msgid "Visit lesson overview"
+msgstr "Перегляд відвідування уроку"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:398
+msgid "unexcused"
+msgstr "непояснене"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:401
+msgid "Summed up tardiness"
+msgstr "Сумарні запізнення"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:404
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:117
+msgid "Count of tardiness"
+msgstr "Кількість запізень"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:436
+msgid "No lessons available"
+msgstr "Немає доступних уроків"
+
+#: aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html:439
+msgid ""
+"\n"
+"            There are no lessons for the selected group or teacher in this week.\n"
+"          "
+msgstr ""
+"\n"
+"            Для обраної групи або викладача на цьому тижні уроків немає.\n"
+"          "
+
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/create.html:6
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/create.html:7
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/list.html:18
+msgid "Create excuse type"
+msgstr "Створити тип пояснення"
+
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/edit.html:6
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/edit.html:7
+msgid "Edit excuse type"
+msgstr "Редагувати тип пояснення"
+
+#: aleksis/apps/alsijil/templates/alsijil/excuse_type/warning.html:4
+#: aleksis/apps/alsijil/templates/alsijil/group_role/warning.html:4
+msgid ""
+"\n"
+"    This function should only be used to define alternatives to the default excuse which also will be counted extra.\n"
+"    Don't use this to create a default excuse or if you don't divide between different types of excuse.\n"
+"  "
+msgstr ""
+"\n"
+"    Ця функція використовується лише для визначення альтернатив до типового "
+"пояснення, яке додатково буде враховане.\n"
+"    Не користуйтеся цим для створення типового пояснення або якщо не "
+"розділяєте на типи пояснень.\n"
+"  "
+
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:6
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/create.html:7
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/list.html:14
+msgid "Create extra mark"
+msgstr "Створити додаткову позначку"
+
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:6
+#: aleksis/apps/alsijil/templates/alsijil/extra_mark/edit.html:7
+msgid "Edit extra mark"
+msgstr "Редагувати додаткову позначку"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:9
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:16
+#, python-format
+msgid "Assign group role for %(group)s"
+msgstr "Призначити роль групи для %(group)s"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assign.html:34
+msgid "Assign"
+msgstr "Призначити"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:9
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:12
+#, python-format
+msgid "Group roles for %(group)s"
+msgstr "Ролі груп для %(group)s"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:28
+msgid "Back to my groups"
+msgstr "Назад до моїх груп"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:36
+msgid "Assign a role to a person"
+msgstr "Призначити роль особі"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:45
+msgid "Current roles"
+msgstr "Поточні ролі"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:48
+msgid "All assignments"
+msgstr "Усі призначення"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:66
+#: aleksis/apps/alsijil/templates/alsijil/group_role/assigned_list.html:83
+msgid "Actions"
+msgstr "Дії"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/create.html:6
+#: aleksis/apps/alsijil/templates/alsijil/group_role/create.html:7
+#: aleksis/apps/alsijil/templates/alsijil/group_role/list.html:16
+msgid "Create group role"
+msgstr "Створити роль групи"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/edit.html:6
+#: aleksis/apps/alsijil/templates/alsijil/group_role/edit.html:7
+msgid "Edit group role"
+msgstr "Редагувати роль групи"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/edit_assignment.html:7
+#: aleksis/apps/alsijil/templates/alsijil/group_role/edit_assignment.html:8
+msgid "Edit group role assignment"
+msgstr "Редагувати призначення ролі групи"
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assigned_roles.html:31
+msgid "No one assigned."
+msgstr "Ніхто не призначений."
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assigned_roles.html:41
+msgid ""
+"\n"
+"    You can get some additional actions for each group role assignment if you click on the name of the\n"
+"    corresponding person.\n"
+"  "
+msgstr ""
+"\n"
+"    Ви можете отримати деякі додаткові дії для кожного призначення ролі "
+"групи після кліку\n"
+"     на ім'я відповідної особи.\n"
+"  "
+
+#: aleksis/apps/alsijil/templates/alsijil/group_role/partials/assignment_options.html:21
+msgid "Stop"
+msgstr "Стоп"
+
+#: aleksis/apps/alsijil/templates/alsijil/notifications/check.html:1
+msgid "Please check if the following class register entries are complete and correct:"
+msgstr ""
+"Перевірте, будь ласка, чи ці записи класного журналу повні та правильні:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/absences.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:22
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:27
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:50
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:139
+msgid "(e)"
+msgstr "(п)"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/absences.html:6
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:14
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:33
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:56
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:143
+msgid "(u)"
+msgstr "(н)"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:4
+msgid "Legend"
+msgstr "Легенда"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:7
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:71
+msgid "General"
+msgstr "Загальне"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:10
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:137
+msgid "(a)"
+msgstr "(в)"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:14
+msgid "Unexcused absences"
+msgstr "Необґрунтовані пропуски"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:18
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:26
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:49
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:138
+msgid "Sum (e)"
+msgstr "Сума (п)"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:18
+msgid "Sum of excused absences"
+msgstr "Кількість пропусків з поясненням"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:22
+msgid "Regular excused absences"
+msgstr "Регулярні пояснення пропусків"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/legend.html:41
+msgid "Excuse types (not counted as absent)"
+msgstr "Типи пояснень (не враховані як пропуски)"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:28
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:42
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:7
+#, python-format
+msgid "%(period)s. period"
+msgstr "%(period)s. урок"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html:31
+#, python-format
+msgid ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  period\n"
+"          "
+msgstr ""
+"\n"
+"            %(period_from)s.–%(period_to)s.  уроки\n"
+"          "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:8
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:10
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:136
+msgid "Save"
+msgstr "Зберегти"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:19
+#, python-format
+msgid ""
+"\n"
+"        Previous %(subject)s lesson\n"
+"      "
+msgstr ""
+"\n"
+"        Попередній урок %(subject)s\n"
+"      "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html:30
+#, python-format
+msgid ""
+"\n"
+"        Next %(subject)s lesson\n"
+"      "
+msgstr ""
+"\n"
+"        Наступний урок %(subject)s\n"
+"      "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html:13
+msgid "Change history"
+msgstr "Змінити історію"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html:59
+msgid "Tardiness (in m)"
+msgstr "Запізнення (хв)"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:6
+msgid "Overview: Previous lesson"
+msgstr "Огляд: Попередній урок"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:13
+msgid "Lesson topic of previous lesson:"
+msgstr "Тема попереднього уроку:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:20
+msgid "Homework for this lesson:"
+msgstr "Домашня робота на цей урок:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:27
+msgid "Group notes for previous lesson:"
+msgstr "Нотатки групи на попередньому уроці:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:34
+msgid "Absent persons:"
+msgstr "Відсутні:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html:41
+msgid "Late persons:"
+msgstr "Запізнилися:"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:8
+#, python-format
+msgid ""
+"Seating plan for %(group)s in\n"
+"          %(room)s"
+msgstr ""
+"План розміщення %(group)s у\n"
+"          %(room)s"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:14
+#, python-format
+msgid ""
+"\n"
+"            This seating plan is taken from the parent group of %(child_group)s.\n"
+"            If you want, you can take it over for your group and then customize it.\n"
+"          "
+msgstr ""
+"\n"
+"            Цей план розміщення взятий із батьківської групи %(child_group)s."
+"\n"
+"            При необхідності, Ви можете його налаштувати під свою групу.\n"
+"          "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:30
+msgid "Edit seating plan"
+msgstr "Редагувати план розміщення"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:37
+msgid "Copy plan and edit"
+msgstr "Скопіювати план та відредагувати"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:56
+msgid "There is no seating plan for this lesson."
+msgstr "Для цього уроку немає плану розміщення."
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:64
+#, python-format
+msgid ""
+"\n"
+"                  Create a new seating plan for %(group)s (%(subject)s) in %(room)s\n"
+"                "
+msgstr ""
+"\n"
+"                  Створити новий план розміщення %(group)s (%(subject)s) у "
+"%(room)s\n"
+"                "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html:78
+#, python-format
+msgid ""
+"\n"
+"                    Create a new seating plan for %(group)s in %(room)s\n"
+"                  "
+msgstr ""
+"\n"
+"                    Створити новий план розміщення %(group)s у %(room)s\n"
+"                  "
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:6
+msgid "Data complete"
+msgstr "Дані заповнені"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:17
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:30
+msgid "Missing data"
+msgstr "Дані відсутні"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:19
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:32
+msgid "Pending"
+msgstr "В очікуванні"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:28
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:466
+msgid "Lesson cancelled"
+msgstr "Урок скасований"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html:34
+msgid "Substitution"
+msgstr "Заміна"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html:4
+msgid "Lesson filter"
+msgstr "Фільтр уроків"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html:9
+msgid "Update filters"
+msgstr "Оновити фільтри"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html:22
+msgid "Lesson table"
+msgstr "Розклад уроків"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/objects_table.html:31
+msgid "Execute"
+msgstr "Виконати"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:6
+msgid "No students available."
+msgstr "Немає доступних студентів."
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:13
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:24
+msgid "Primary group"
+msgstr "Основна група"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:15
+msgid "Uncounted Absences"
+msgstr "Невраховані пропуски"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:48
+msgid "Sum"
+msgstr "Сума"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:90
+msgid "Regular excused"
+msgstr "Регулярні пояснення"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:130
+msgid "Show more details"
+msgstr "Показати більш детально"
+
+#: aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html:131
+msgid "Details"
+msgstr "Деталі"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:6
+msgid "Class register:"
+msgstr "Класний журнал:"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:26
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:59
+msgid "Owners"
+msgstr "Власники"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:30
+msgid "Printed on"
+msgstr "Надруковано"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:38
+msgid ""
+"\n"
+"        This printout is intended for archival purposes. The main copy of\n"
+"        the class register is stored in the AlekSIS School Information\n"
+"        System.\n"
+"      "
+msgstr ""
+"\n"
+"        Ця роздруківка зроблена для архівних потреб. Основна копія\n"
+"        цього класного журналу зберігається в навчальній інформаційній\n"
+"         системі AlekSIS.\n"
+"      "
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:45
+msgid ""
+"\n"
+"        Copies of the class register, both digital and as printout, must\n"
+"        only be kept inside the school and/or on devices authorised by the\n"
+"        school.\n"
+"      "
+msgstr ""
+"\n"
+"        Копії цього класного журналу, в т.ч. цифрові та друковані, повинні\n"
+"        зберігатися лише всередині навчального закладу та/або на пристроях,\n"
+"        дозволених адміністрацією цього навчального закладу.\n"
+"      "
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:52
+msgid ""
+"\n"
+"        The owner of the group and the headteacher confirm the above, as\n"
+"        well as the correctness of this printout.\n"
+"      "
+msgstr ""
+"\n"
+"        Власник групи та директор погоджують зазначене вище, \n"
+"        а також правильність цієї роздруківки.\n"
+"      "
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:62
+msgid "Headteacher"
+msgstr "Директор"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:69
+msgid "Abbreviations"
+msgstr "Скорочення"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:78
+msgid "Late"
+msgstr "Запізнення"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:89
+msgid "Custom excuse types"
+msgstr "Користувацькі типи пояснень"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:101
+msgid "Custom excuse types (not counted as absent)"
+msgstr "Користувацькі типи пояснень (не враховані як пропуски)"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:113
+msgid "Available extra marks"
+msgstr "Доступні додаткові відмітки"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:127
+msgid "Persons in group"
+msgstr "Особи в групі"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:132
+msgid "No."
+msgstr "â„–"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:133
+msgid "Last name"
+msgstr "Прізвище"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:134
+msgid "First name"
+msgstr "Ім'я"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:135
+msgid "Sex"
+msgstr "Стать"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:136
+msgid "Date of birth"
+msgstr "Дата народження"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:147
+msgid "(b)"
+msgstr "(з)"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:184
+msgid "Teachers and lessons in group"
+msgstr "Викладачі та уроки в групі"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:191
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:222
+msgid "Lesson start"
+msgstr "Початок уроку"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:192
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:223
+msgid "Lesson end"
+msgstr "Кінець уроку"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:193
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:224
+msgid "Per week"
+msgstr "На тиждень"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:214
+msgid "Teachers and lessons in child groups"
+msgstr "Викладачі та уроки у підлеглих групах"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:247
+msgid "Personal overview"
+msgstr "Особистий огляд"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:249
+msgid "Contact details"
+msgstr "Контактні дані"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:288
+msgid "Absences and tardiness"
+msgstr "Пропуски та запізнення"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:303
+msgid "Without excuse type"
+msgstr "Без типу пояснення"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:349
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:419
+msgid "Pe."
+msgstr "Ур."
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:350
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:420
+msgid "Subj."
+msgstr "Предм."
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:351
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:424
+msgid "Te."
+msgstr "Вч."
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:353
+msgid "Tard."
+msgstr "Зап."
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:381
+msgid "Yes"
+msgstr "Так"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:386
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:484
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:499
+msgid "e"
+msgstr "п"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:413
+msgid "Week"
+msgstr "Тиждень"
+
+#: aleksis/apps/alsijil/templates/alsijil/print/full_register.html:423
+msgid "Notes"
+msgstr "Нотатки"
+
+#: aleksis/apps/alsijil/views.py:118
+msgid "You either selected an invalid lesson or there is currently no lesson in progress."
+msgstr "Або Ви обрали неправильний урок, або зараз уроку немає."
+
+#: aleksis/apps/alsijil/views.py:151
+msgid "You are not allowed to create a lesson documentation for a lesson in the future."
+msgstr "Вам не дозволено створювати учбові матеріали для уроку у майбутньому."
+
+#: aleksis/apps/alsijil/views.py:266
+msgid "The lesson documentation has been saved."
+msgstr "Учбовий матеріал збережений."
+
+#: aleksis/apps/alsijil/views.py:300
+msgid "The personal notes have been saved."
+msgstr "Особисті нотатки збережені."
+
+#: aleksis/apps/alsijil/views.py:1079
+msgid "The absence has been saved."
+msgstr "Пропуск збережений."
+
+#: aleksis/apps/alsijil/views.py:1100
+msgid "The personal note has been deleted."
+msgstr "Особиста нотатка видалена."
+
+#: aleksis/apps/alsijil/views.py:1122
+msgid "The extra mark has been created."
+msgstr "Додаткова позначка сторена."
+
+#: aleksis/apps/alsijil/views.py:1134
+msgid "The extra mark has been saved."
+msgstr "Додаткова позначка збережена."
+
+#: aleksis/apps/alsijil/views.py:1145
+msgid "The extra mark has been deleted."
+msgstr "Додаткова позначка видалена."
+
+#: aleksis/apps/alsijil/views.py:1166
+msgid "The excuse type has been created."
+msgstr "Тип пояснення створений."
+
+#: aleksis/apps/alsijil/views.py:1178
+msgid "The excuse type has been saved."
+msgstr "Тип пояснення збережений."
+
+#: aleksis/apps/alsijil/views.py:1189
+msgid "The excuse type has been deleted."
+msgstr "Тип пояснення видалений."
+
+#: aleksis/apps/alsijil/views.py:1210
+msgid "The group role has been created."
+msgstr "Роль групи створена."
+
+#: aleksis/apps/alsijil/views.py:1222
+msgid "The group role has been saved."
+msgstr "Роль групи збережена."
+
+#: aleksis/apps/alsijil/views.py:1233
+msgid "The group role has been deleted."
+msgstr "Роль групи видалена."
+
+#: aleksis/apps/alsijil/views.py:1266 aleksis/apps/alsijil/views.py:1298
+msgid "The group role has been assigned."
+msgstr "Роль групи призначена."
+
+#: aleksis/apps/alsijil/views.py:1317
+msgid "The group role assignment has been saved."
+msgstr "Призначення ролі групи збережене."
+
+#: aleksis/apps/alsijil/views.py:1338
+msgid "The group role assignment has been stopped."
+msgstr "Призначення ролі групи зупинене."
+
+#: aleksis/apps/alsijil/views.py:1351
+msgid "The group role assignment has been deleted."
+msgstr "Призначення ролі групи видалене."
diff --git a/aleksis/apps/alsijil/managers.py b/aleksis/apps/alsijil/managers.py
index 69cc3fd7d62e3669e770ea12468490bf08ea1009..9d97e58091af8ab2149122d7e51f767faccb61f6 100644
--- a/aleksis/apps/alsijil/managers.py
+++ b/aleksis/apps/alsijil/managers.py
@@ -68,7 +68,8 @@ class RegisterObjectRelatedQuerySet(QuerySet):
                 When(day__isnull=True, then="event__date_start"),
             ),
             day_end=Case(
-                When(day__isnull=False, then="day"), When(day__isnull=True, then="event__date_end"),
+                When(day__isnull=False, then="day"),
+                When(day__isnull=True, then="event__date_end"),
             ),
         )
 
@@ -76,8 +77,14 @@ class RegisterObjectRelatedQuerySet(QuerySet):
         """Annotate lesson documentations with the subjects."""
         return self.annotate(
             subject=Case(
-                When(lesson_period__isnull=False, then="lesson_period__lesson__subject__name",),
-                When(extra_lesson__isnull=False, then="extra_lesson__subject__name",),
+                When(
+                    lesson_period__isnull=False,
+                    then="lesson_period__lesson__subject__name",
+                ),
+                When(
+                    extra_lesson__isnull=False,
+                    then="extra_lesson__subject__name",
+                ),
                 default=Value(_("Event")),
             )
         )
@@ -142,7 +149,12 @@ class GroupRoleQuerySet(QuerySet):
             qs = GroupRoleAssignment.objects.on_day(time_ref)
 
         qs = qs.for_groups(groups).distinct()
-        return self.prefetch_related(Prefetch("assignments", queryset=qs,))
+        return self.prefetch_related(
+            Prefetch(
+                "assignments",
+                queryset=qs,
+            )
+        )
 
 
 class GroupRoleAssignmentManager(CurrentSiteManagerWithoutMigrations):
diff --git a/aleksis/apps/alsijil/migrations/0016_add_not_counted_excuse_types.py b/aleksis/apps/alsijil/migrations/0016_add_not_counted_excuse_types.py
new file mode 100644
index 0000000000000000000000000000000000000000..c45edee40fca69d73ca7edf67c816d389470f1ef
--- /dev/null
+++ b/aleksis/apps/alsijil/migrations/0016_add_not_counted_excuse_types.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.12 on 2022-03-20 10:12
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('alsijil', '0015_fix_unique_personal_note'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='excusetype',
+            name='count_as_absent',
+            field=models.BooleanField(default=True, help_text="If checked, this excuse type will be counted as a missed lesson. If not checked, it won't show up in the absence report.", verbose_name='Count as missed lesson'),
+        ),
+    ]
diff --git a/aleksis/apps/alsijil/model_extensions.py b/aleksis/apps/alsijil/model_extensions.py
index 1484c43df5454cde5b84b2ab7369a186d4593409..d18d66867ddfa2bf4c9fe763842b1e3401d6d24e 100644
--- a/aleksis/apps/alsijil/model_extensions.py
+++ b/aleksis/apps/alsijil/model_extensions.py
@@ -105,7 +105,11 @@ def mark_absent(
                 .prefetch_related(None)
                 .update_or_create(
                     person=self,
-                    defaults={"absent": absent, "excused": excused, "excuse_type": excuse_type,},
+                    defaults={
+                        "absent": absent,
+                        "excused": excused,
+                        "excuse_type": excuse_type,
+                    },
                     **q_attrs,
                 )
             )
@@ -150,12 +154,17 @@ def get_personal_notes(
         no_personal_notes=~Exists(PersonalNote.objects.filter(person__pk=OuterRef("pk"), **q_attrs))
     ).filter(
         member_of__in=Group.objects.filter(pk__in=self.get_groups().all()),
-        is_active=True,
         no_personal_notes=True,
     )
 
     # Create all missing personal notes
-    new_personal_notes = [PersonalNote(person=person, **q_attrs,) for person in missing_persons]
+    new_personal_notes = [
+        PersonalNote(
+            person=person,
+            **q_attrs,
+        )
+        for person in missing_persons
+    ]
     PersonalNote.objects.bulk_create(new_personal_notes)
 
     for personal_note in new_personal_notes:
@@ -177,10 +186,12 @@ ExtraLesson.method(get_personal_notes)
 # Dynamically add extra permissions to Group and Person models in core
 # Note: requires migrate afterwards
 Group.add_permission(
-    "view_week_class_register_group", _("Can view week overview of group class register"),
+    "view_week_class_register_group",
+    _("Can view week overview of group class register"),
 )
 Group.add_permission(
-    "view_lesson_class_register_group", _("Can view lesson overview of group class register"),
+    "view_lesson_class_register_group",
+    _("Can view lesson overview of group class register"),
 )
 Group.add_permission("view_personalnote_group", _("Can view all personal notes of a group"))
 Group.add_permission("edit_personalnote_group", _("Can edit all personal notes of a group"))
@@ -194,6 +205,7 @@ Group.add_permission("view_full_register_group", _("Can view full register of a
 Group.add_permission(
     "register_absence_group", _("Can register an absence for all members of a group")
 )
+Group.add_permission("assign_grouprole", _("Can assign a group role for this group"))
 Person.add_permission("register_absence_person", _("Can register an absence for a person"))
 
 
@@ -206,7 +218,8 @@ def get_lesson_documentation(
         week = self.week
     # Use all to make effect of prefetched data
     doc_filter = filter(
-        lambda d: d.week == week.week and d.year == week.year, self.documentations.all(),
+        lambda d: d.week == week.week and d.year == week.year,
+        self.documentations.all(),
     )
     try:
         return next(doc_filter)
@@ -409,9 +422,19 @@ def generate_person_list_with_class_register_statistics(
         )
     ).annotate(
         absences_count=Count(
-            "filtered_personal_notes", filter=Q(filtered_personal_notes__absent=True),
+            "filtered_personal_notes",
+            filter=Q(filtered_personal_notes__absent=True)
+            & ~Q(filtered_personal_notes__excuse_type__count_as_absent=False),
         ),
         excused=Count(
+            "filtered_personal_notes",
+            filter=Q(
+                filtered_personal_notes__absent=True,
+                filtered_personal_notes__excused=True,
+            )
+            & ~Q(filtered_personal_notes__excuse_type__count_as_absent=False),
+        ),
+        excused_without_excuse_type=Count(
             "filtered_personal_notes",
             filter=Q(
                 filtered_personal_notes__absent=True,
@@ -425,7 +448,8 @@ def generate_person_list_with_class_register_statistics(
         ),
         tardiness=Sum("filtered_personal_notes__late"),
         tardiness_count=Count(
-            "filtered_personal_notes", filter=Q(filtered_personal_notes__late__gt=0),
+            "filtered_personal_notes",
+            filter=Q(filtered_personal_notes__late__gt=0),
         ),
     )
 
diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index 9b49d23327ffa2cb8671fd52825bce7b20d99041..42189856b660e771f0dd36efd14414450a6485c9 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -55,6 +55,15 @@ class ExcuseType(ExtensibleModel):
     short_name = models.CharField(max_length=255, unique=True, verbose_name=_("Short name"))
     name = models.CharField(max_length=255, unique=True, verbose_name=_("Name"))
 
+    count_as_absent = models.BooleanField(
+        default=True,
+        verbose_name=_("Count as absent"),
+        help_text=_(
+            "If checked, this excuse type will be counted as a missed lesson. If not checked,"
+            "it won't show up in the absence report."
+        ),
+    )
+
     def __str__(self):
         return f"{self.name} ({self.short_name})"
 
@@ -234,7 +243,11 @@ class PersonalNote(RegisterObjectRelatedMixin, ExtensibleModel):
     late = models.PositiveSmallIntegerField(default=0)
     excused = models.BooleanField(default=False)
     excuse_type = models.ForeignKey(
-        ExcuseType, on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_("Excuse type"),
+        ExcuseType,
+        on_delete=models.SET_NULL,
+        null=True,
+        blank=True,
+        verbose_name=_("Excuse type"),
     )
 
     remarks = models.CharField(max_length=200, blank=True)
@@ -288,13 +301,16 @@ class PersonalNote(RegisterObjectRelatedMixin, ExtensibleModel):
                 check=lesson_related_constraint_q, name="one_relation_only_personal_note"
             ),
             models.UniqueConstraint(
-                fields=("week", "year", "lesson_period", "person"), name="unique_note_per_lp",
+                fields=("week", "year", "lesson_period", "person"),
+                name="unique_note_per_lp",
             ),
             models.UniqueConstraint(
-                fields=("week", "year", "event", "person"), name="unique_note_per_ev",
+                fields=("week", "year", "event", "person"),
+                name="unique_note_per_ev",
             ),
             models.UniqueConstraint(
-                fields=("week", "year", "extra_lesson", "person"), name="unique_note_per_el",
+                fields=("week", "year", "extra_lesson", "person"),
+                name="unique_note_per_el",
             ),
         ]
 
@@ -326,14 +342,13 @@ class LessonDocumentation(RegisterObjectRelatedMixin, ExtensibleModel):
     homework = models.CharField(verbose_name=_("Homework"), max_length=200, blank=True)
     group_note = models.CharField(verbose_name=_("Group note"), max_length=200, blank=True)
 
-    def _carry_over_data(self):
-        """Carry over data to directly adjacent periods in this lesson if data is not already set.
+    def carry_over_data(self, all_periods_of_lesson: LessonPeriod):
+        """Carry over data to given periods in this lesson if data is not already set.
 
-        Can be deactivated using site preference ``alsijil__carry_over``.
+        Both forms of carrying over data can be deactivated using site preferences
+        ``alsijil__carry_over_next_periods`` and ``alsijil__allow_carry_over_same_week``
+        respectively.
         """
-        all_periods_of_lesson = LessonPeriod.objects.filter(
-            lesson=self.lesson_period.lesson, period__weekday=self.lesson_period.period.weekday,
-        )
         for period in all_periods_of_lesson:
             lesson_documentation = period.get_or_create_lesson_documentation(
                 CalendarWeek(week=self.week, year=self.year)
@@ -354,19 +369,24 @@ class LessonDocumentation(RegisterObjectRelatedMixin, ExtensibleModel):
                 changed = True
 
             if changed:
-                lesson_documentation.save(carry_over=False)
+                lesson_documentation.save(carry_over_next_periods=False)
 
     def __str__(self) -> str:
         return f"{self.lesson_period}, {self.date_formatted}"
 
-    def save(self, carry_over=True, *args, **kwargs):
+    def save(self, carry_over_next_periods=True, *args, **kwargs):
         if (
-            get_site_preferences()["alsijil__carry_over"]
+            get_site_preferences()["alsijil__carry_over_next_periods"]
             and (self.topic or self.homework or self.group_note)
             and self.lesson_period
-            and carry_over
+            and carry_over_next_periods
         ):
-            self._carry_over_data()
+            self.carry_over_data(
+                LessonPeriod.objects.filter(
+                    lesson=self.lesson_period.lesson,
+                    period__weekday=self.lesson_period.period.weekday,
+                )
+            )
         super().save(*args, **kwargs)
 
     class Meta:
@@ -380,16 +400,20 @@ class LessonDocumentation(RegisterObjectRelatedMixin, ExtensibleModel):
         ]
         constraints = [
             CheckConstraint(
-                check=lesson_related_constraint_q, name="one_relation_only_lesson_documentation",
+                check=lesson_related_constraint_q,
+                name="one_relation_only_lesson_documentation",
             ),
             models.UniqueConstraint(
-                fields=("week", "year", "lesson_period"), name="unique_documentation_per_lp",
+                fields=("week", "year", "lesson_period"),
+                name="unique_documentation_per_lp",
             ),
             models.UniqueConstraint(
-                fields=("week", "year", "event"), name="unique_documentation_per_ev",
+                fields=("week", "year", "event"),
+                name="unique_documentation_per_ev",
             ),
             models.UniqueConstraint(
-                fields=("week", "year", "extra_lesson"), name="unique_documentation_per_el",
+                fields=("week", "year", "extra_lesson"),
+                name="unique_documentation_per_el",
             ),
         ]
 
@@ -438,6 +462,7 @@ class GroupRole(ExtensibleModel):
         constraints = [
             models.UniqueConstraint(fields=("site_id", "name"), name="unique_role_per_site"),
         ]
+        permissions = (("assign_group_role", _("Can assign group role")),)
 
 
 class GroupRoleAssignment(GroupPropertiesMixin, ExtensibleModel):
@@ -456,7 +481,9 @@ class GroupRoleAssignment(GroupPropertiesMixin, ExtensibleModel):
         verbose_name=_("Assigned person"),
     )
     groups = models.ManyToManyField(
-        "core.Group", related_name="group_roles", verbose_name=_("Groups"),
+        "core.Group",
+        related_name="group_roles",
+        verbose_name=_("Groups"),
     )
     date_start = models.DateField(verbose_name=_("Start date"))
     date_end = models.DateField(
@@ -517,7 +544,9 @@ class AlsijilGlobalPermissions(GlobalPermissionModel):
     class Meta:
         managed = False
         permissions = (
+            ("view_lesson", _("Can view lesson overview")),
             ("view_week", _("Can view week overview")),
+            ("view_full_register", _("Can view full register")),
             ("register_absence", _("Can register absence")),
             ("list_personal_note_filters", _("Can list all personal note filters")),
         )
diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py
index c563321150ad30a2a3ec54134c3f842c572f4f2e..35d0984effae2264de0e53844682b09eb60ac3f8 100644
--- a/aleksis/apps/alsijil/preferences.py
+++ b/aleksis/apps/alsijil/preferences.py
@@ -46,7 +46,7 @@ class EditLessonDocumentationAsOriginalTeacher(BooleanPreference):
 @site_preferences_registry.register
 class CarryOverDataToNextPeriods(BooleanPreference):
     section = alsijil
-    name = "carry_over"
+    name = "carry_over_next_periods"
     default = True
     verbose_name = _(
         "Carry over data from first lesson period to the "
@@ -55,6 +55,20 @@ class CarryOverDataToNextPeriods(BooleanPreference):
     help_text = _("This will carry over data only if the data in the following periods are empty.")
 
 
+@site_preferences_registry.register
+class AllowCarryOverLessonDocumentationToCurrentWeek(BooleanPreference):
+    section = alsijil
+    name = "allow_carry_over_same_week"
+    default = False
+    verbose_name = _(
+        "Allow carrying over data from any lesson period to all other lesson \
+                periods with the same lesson and in the same week"
+    )
+    help_text = _(
+        "This will carry over data only if the data in the aforementioned periods are empty."
+    )
+
+
 @site_preferences_registry.register
 class CarryOverPersonalNotesToNextPeriods(BooleanPreference):
     section = alsijil
diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py
index 3d20be8395f0c4298da0d93bb9e9f24b36048f49..621f3e3b2e6994fc2f06b0081d6fa8c191eca641 100644
--- a/aleksis/apps/alsijil/rules.py
+++ b/aleksis/apps/alsijil/rules.py
@@ -185,17 +185,19 @@ view_person_overview_personal_notes_predicate = view_person_overview_predicate &
     | has_person_group_object_perm("core.view_personalnote_group")
 )
 add_perm(
-    "alsijil.view_person_overview_personalnote_rule", view_person_overview_personal_notes_predicate,
+    "alsijil.view_person_overview_personalnote_rule",
+    view_person_overview_personal_notes_predicate,
 )
 
 # Edit person overview personal notes
 edit_person_overview_personal_notes_predicate = view_person_overview_predicate & (
     ~is_current_person
-    | has_global_perm("alsijil.edit_personalnote")
+    | has_global_perm("alsijil.change_personalnote")
     | has_person_group_object_perm("core.edit_personalnote_group")
 )
 add_perm(
-    "alsijil.edit_person_overview_personalnote_rule", edit_person_overview_personal_notes_predicate,
+    "alsijil.edit_person_overview_personalnote_rule",
+    edit_person_overview_personal_notes_predicate,
 )
 
 # View person statistics on personal notes
@@ -305,7 +307,7 @@ add_perm("alsijil.delete_grouproleassignment_rule", delete_group_role_assignment
 
 view_register_objects_list_predicate = has_person & (
     has_any_object("core.view_full_register_group", Group)
-    | has_global_perm("core.view_full_register")
+    | has_global_perm("alsijil.view_full_register")
 )
 add_perm("alsijil.view_register_objects_list_rule", view_register_objects_list_predicate)
 
diff --git a/aleksis/apps/alsijil/static/css/alsijil/full_register.css b/aleksis/apps/alsijil/static/css/alsijil/full_register.css
index 0584c12ee4e266f43fe8d34c8003d37d4a09815c..9068a104cb2464a0cb95073e3ee8a66bddfaf21e 100644
--- a/aleksis/apps/alsijil/static/css/alsijil/full_register.css
+++ b/aleksis/apps/alsijil/static/css/alsijil/full_register.css
@@ -30,18 +30,10 @@ td.rotate, th.rotate {
     transform: rotate(-90deg);
 }
 
-tr.lesson-cancelled td.subj {
-    text-decoration: line-through;
-}
-
 tr.lesson-cancelled td {
     background-color: #EF9A9A;
 }
 
-tr.lesson-substituted td.lesson-subj {
-    text-decoration: line-through;
-}
-
 tr.lesson-substituted td {
     background-color: #ffb74d;
 }
diff --git a/aleksis/apps/alsijil/static/css/alsijil/lesson.css b/aleksis/apps/alsijil/static/css/alsijil/lesson.css
index d402156fc7bc1f750e88a5a9c04bf46fa2fd0d5b..cb2d9399c9d865c7116c2f8137274edc1ec501d0 100644
--- a/aleksis/apps/alsijil/static/css/alsijil/lesson.css
+++ b/aleksis/apps/alsijil/static/css/alsijil/lesson.css
@@ -15,14 +15,119 @@
 }
 
 
-@media only screen and (max-width : 992px) {
-    table.responsive-table.alsijil-table th,
-    table.responsive-table.alsijil-table td {
-      margin: 0;
-      vertical-align: top;
-      height: 109px;}
+@media only screen and (max-width: 992px) {
+    .no-mobile-card {
+        border: unset;
+        padding: unset;
+        margin: unset;
+        box-shadow: unset;
+    }
+    .no-mobile-card .card-content {
+        padding: unset;
+    }
+    table.alsijil-table.horizontal-on-small {
+        display: block;
+        max-width: calc(100vw - 40px);
+    }
+    table.alsijil-table.horizontal-on-small thead {
+        display: none;
+    }
+    table.alsijil-table.horizontal-on-small tbody {
+        overflow-x: scroll;
+        display: flex;
+        column-gap: 1rem;
+        flex-wrap: nowrap;
+        align-items: stretch;
+        scroll-snap-type: x proximity;
+    }
+
+    table.alsijil-table.horizontal-on-small tr {
+        flex-basis: min(75vw, 400px);
+        flex-shrink: 0;
+        flex-grow: 1;
+        border-radius: 8px;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        scroll-snap-align: center;
+        transition: all .5s;
+        margin: 0.5rem 0 1rem 0;
+        background-color: #fff!important;
+    	box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2);
+        padding: 24px;
+    }
+    table.alsijil-table.horizontal-on-small tr:first-of-type {
+        margin-inline-start: .4rem;
+        -moz-margin-start: .4rem;
+        -webkit-margin-start: .4rem;
+    }
+
+    table.alsijil-table.horizontal-on-small tr:last-of-type {
+        margin-inline-end: .4rem;
+        -moz-margin-end: .4rem;
+        -webkit-margin-end: .4rem;
+    }
+    table.alsijil-table.horizontal-on-small td.center-align {
+        text-align: left;
+    }
+    table.alsijil-table.horizontal-on-small .person-name {
+        font-size: 24px;
+        font-weight: 300;
+        display: block;
+        line-height: 32px;
+        margin-bottom: 8px;
+    }
+}
+
+.alsijil-time-head, .alsijil-object-head {
+    display: block;
+}
+
+.alsijil-time-head {
+    font-size: 2rem;
+    line-height: 1.1;
+}
+
+.alsijil-object-head {
+    font-size: 3rem;
+}
+
+@media only screen and (max-width: 600px) {
+    .alsijil-time-head {
+        font-size: 1.5rem;
+    }
+
+    .alsijil-object-head {
+        font-size: 2.2rem;
+        line-height: 1.4;
+    }
+}
+
+.alsijil-nav {
+    line-height: 36px;
+}
+
+.alsijil-header-nav-button {
+    height: 66px;
+    padding: 0;
 }
 
-.alsijil-top-button {
-    margin-top: -20px;
+.alsijil-header-nav-button.left {
+    margin-right: 5px;
 }
+
+.alsijil-header-nav-button.right {
+    margin-left: 5px;
+}
+
+.alsijil-header-nav-button i.material-icons {
+    line-height: 60px;
+    height: 60px;
+    font-size: 40px;
+}
+
+.alsijil-nav-header {
+    width: calc(100% + 40px);
+    padding: 10px 20px;
+    margin: -10px -20px 0;
+}
\ No newline at end of file
diff --git a/aleksis/apps/alsijil/static/css/alsijil/week_view.css b/aleksis/apps/alsijil/static/css/alsijil/week_view.css
new file mode 100644
index 0000000000000000000000000000000000000000..ccd1595e0fa5ad3f3c10ee8857c644723892e6f2
--- /dev/null
+++ b/aleksis/apps/alsijil/static/css/alsijil/week_view.css
@@ -0,0 +1,116 @@
+@media screen and (max-width: 600px) {
+    #toggle-row button[type=submit] {
+        width: 100%;
+        margin-bottom: 1em;
+    }
+}
+
+.horizontal-scroll-container {
+    overflow-x: scroll;
+    display: flex;
+    column-gap: 1rem;
+    flex-wrap: nowrap;
+    align-items: stretch;
+    scroll-snap-type: x proximity;
+}
+
+.horizontal-scroll-container.vertical {
+    flex-wrap: wrap;
+    overflow-x: inherit;
+}
+
+.horizontal-scroll-container.vertical .horizontal-scroll-card {
+    margin-inline: 0;
+}
+
+dl {
+    margin: 0;
+    padding: 0;
+}
+
+dt {
+    font-weight: bold;
+}
+
+dd {
+    margin: 0;
+    padding: unset;
+}
+
+.horizontal-scroll-card {
+    flex-basis: min(75vw, 400px);
+    flex-shrink: 0;
+    flex-grow: 1;
+    border-radius: 8px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    scroll-snap-align: center;
+    transition: all .5s;
+}
+
+.horizontal-scroll-card:first-of-type {
+    margin-inline-start: .4rem;
+    -moz-margin-start: .4rem;
+    -webkit-margin-start: .4rem;
+}
+
+.horizontal-scroll-card:last-of-type {
+    margin-inline-end: .4rem;
+    -moz-margin-end: .4rem;
+    -webkit-margin-end: .4rem;
+}
+
+.horizontal-scroll-card .card-action {
+    margin-bottom: 5px;
+}
+
+.horizontal-scroll-card .card-content .card-title {
+    display: flex;
+    justify-content: space-between;
+}
+
+.horizontal-scroll-card .card-content .card-title .subject {
+    flex-grow: 5;
+}
+
+.horizontal-scroll-card .one-line {
+   display: grid;
+    grid-auto-flow: column;
+    grid-template-rows: 1fr 1fr;
+}
+
+p.subtitle {
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-end;
+}
+
+.btn-superflat ~ span {
+    line-height: 24px;
+}
+
+.btn-superflat, .btn-superflat:focus, .btn-superflat:active {
+    border: none;
+    line-height: 1;
+    height: 24px;
+    background: none;
+    font-weight: normal;
+}
+
+.btn-superflat i.material-icons {
+    vertical-align: middle;
+}
+
+.btn-superflat:hover {
+    cursor: pointer;
+}
+
+.unfold-trigger i.material-icons {
+    transition: transform .5s 0s ease-in-out;
+    transform: rotate(-90deg);
+}
+
+.unfold-trigger.vertical i.material-icons {
+    transform: rotate(-180deg);
+}
diff --git a/aleksis/apps/alsijil/static/js/alsijil/week_view.js b/aleksis/apps/alsijil/static/js/alsijil/week_view.js
new file mode 100644
index 0000000000000000000000000000000000000000..c5daa0451b63a63aac4e8b7703beaaa6d8b26fe5
--- /dev/null
+++ b/aleksis/apps/alsijil/static/js/alsijil/week_view.js
@@ -0,0 +1,21 @@
+$(document).ready(function () {
+    $("#id_group").change(function () {
+        $("#id_teacher").val("").formSelect();
+    });
+    $("#id_teacher").change(function () {
+        $("#id_group").val("").formSelect();
+    });
+    $("#toggle-row.pre-hidden").hide();
+
+});
+$("#toggle-button").click(function () {
+    $("#toggle-row").toggle();
+})
+$(".unfold-trigger").click(function (event) {
+    let target = event.target;
+    target.classList.toggle("vertical");
+    let next_container = $(target).parent().next(".horizontal-scroll-container");
+    if (next_container.length >= 1) {
+        next_container[0].classList.toggle("vertical");
+    }
+})
\ No newline at end of file
diff --git a/aleksis/apps/alsijil/tables.py b/aleksis/apps/alsijil/tables.py
index f4f064450fba28100e1ee9c775c12cd2db03776c..c82385265b37d6b37f365048b2ad8c4b6ae52cf1 100644
--- a/aleksis/apps/alsijil/tables.py
+++ b/aleksis/apps/alsijil/tables.py
@@ -37,6 +37,10 @@ class ExcuseTypeTable(tables.Table):
 
     name = tables.LinkColumn("edit_excuse_type", args=[A("id")])
     short_name = tables.Column()
+    count_as_absent = tables.BooleanColumn(
+        verbose_name=_("Count as absent"),
+        accessor="count_as_absent",
+    )
     edit = tables.LinkColumn(
         "edit_excuse_type",
         args=[A("id")],
@@ -89,22 +93,27 @@ class GroupRoleTable(tables.Table):
 class PersonalNoteTable(tables.Table):
     selected = SelectColumn(attrs={"input": {"name": "selected_objects"}}, accessor=A("pk"))
     date = tables.Column(
-        verbose_name=_("Date"), accessor=A("date_formatted"), order_by=A("day_start")
+        verbose_name=_("Date"), accessor=A("date_formatted"), order_by=A("day_start"), linkify=True
     )
     period = tables.Column(
-        verbose_name=_("Period"), accessor=A("period_formatted"), order_by=A("order_period")
+        verbose_name=_("Period"),
+        accessor=A("period_formatted"),
+        order_by=A("order_period"),
+        linkify=True,
     )
     groups = tables.Column(
         verbose_name=_("Groups"),
         accessor=A("register_object__group_names"),
         order_by=A("order_groups"),
+        linkify=True,
     )
     teachers = tables.Column(
         verbose_name=_("Teachers"),
         accessor=A("register_object__teacher_names"),
         order_by=A("order_teachers"),
+        linkify=True,
     )
-    subject = tables.Column(verbose_name=_("Subject"), accessor=A("subject"))
+    subject = tables.Column(verbose_name=_("Subject"), accessor=A("subject"), linkify=True)
     absent = tables.Column(verbose_name=_("Absent"))
     late = tables.Column(verbose_name=_("Tardiness"))
     excused = tables.Column(verbose_name=_("Excuse"))
@@ -192,15 +201,15 @@ class RegisterObjectTable(tables.Table):
     group_note = tables.Column(linkify=_get_link)
 
     def render_status(self, value, record):
-        return render_to_string(
-            "alsijil/partials/lesson_status_icon.html",
-            dict(
-                week=record.get("week"),
-                has_documentation=record.get("has_documentation", False),
-                substitution=record.get("substitution"),
-                register_object=value,
-            ),
-        )
+        context = {
+            "has_documentation": record.get("has_documentation", False),
+            "register_object": value,
+        }
+        if record.get("week"):
+            context["week"] = record["week"]
+        if record.get("substitution"):
+            context["substitution"] = record["substitution"]
+        return render_to_string("alsijil/partials/lesson_status.html", context)
 
 
 class RegisterObjectSelectTable(RegisterObjectTable):
diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html
index 7c27f555b113da2e420ad9455ec0b9bfe6e9acf6..6de367aee293d9a4c74708ebc2bdaabff775ed88 100644
--- a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html
+++ b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html
@@ -3,434 +3,170 @@
 {% load week_helpers material_form_internal material_form i18n static rules time_helpers %}
 
 {% block browser_title %}{% blocktrans %}Lesson{% endblocktrans %}{% endblock %}
-
+{% block no_page_title %}{% endblock %}
 {% block extra_head %}
   {{ block.super }}
   <link rel="stylesheet" href="{% static 'css/alsijil/lesson.css' %}"/>
-{% endblock %}
-
-{% block content %}
-  <h1>
-    {% if next_lesson_person or prev_lesson_person or lesson_documentation %}
-      <div class="row no-margin">
-        <div class="col s12 no-padding">
-          {# Back to week view #}
-          {% if back_to_week_url %}
-            <a href="{{ back_to_week_url }}"
-               class="btn primary-color waves-light waves-effect alsijil-top-button">
-              <i class="material-icons left">chevron_left</i> {% trans "Back to week view" %}
-            </a>
-          {% endif %}
 
-          {# Next lesson #}
-          {% if prev_lesson_person %}
-            <a class="btn primary waves-effect waves-light alsijil-top-button"
-               href="{% url "lesson_period" prev_lesson_person.week.year prev_lesson_person.week.week prev_lesson_person.id %}">
-            <i class="material-icons left">arrow_back</i>
-            {% trans "My previous lesson" %}
-            </a>
-          {% endif %}
+  {% if with_seating_plan %}
+    <link rel="stylesheet" href="{% static "css/stoelindeling/seating_plan.css" %}">
+  {% endif %}
+{% endblock %}
 
-          {# Previous lesson #}
-          {% if next_lesson_person %}
-            <a class="btn primary right waves-effect waves-light alsijil-top-button"
-               href="{% url "lesson_period" next_lesson_person.week.year next_lesson_person.week.week next_lesson_person.id %}">
-            <i class="material-icons right">arrow_forward</i>
-            {% trans "My next lesson" %}
-            </a>
-          {% endif %}
-        </div>
-      </div>
+{% block nav_content %}
+  <ul class="tabs tabs-transparent tabs-icons tabs-fixed-width">
+    <li class="tab">
+      <a href="#lesson-documentation">
+        <i class="material-icons">speaker_notes</i>
+        {% trans "Period" %}
+      </a>
+    </li>
+    {% if register_object.label_ != "lesson_period" or not register_object.get_substitution.cancelled or not request.site.preferences.alsijil__block_personal_notes_for_cancelled %}
+      <li class="tab">
+        <a href="#personal-notes">
+          <i class="material-icons">people</i>
+          {% trans "Persons" %}
+        </a>
+      </li>
     {% endif %}
-
-
-    {% if register_object.label_ == "event" %}
-      {{ register_object.date_start }} {{ register_object.period_from.period }}.–{{ register_object.date_end }}
-      {{ register_object.period_to.period }}.,
-    {% else %}
-      {{ day }}, {% blocktrans with period=register_object.period.period %}{{ period }}. period{% endblocktrans %} –
+    {% if with_seating_plan %}
+      <li class="tab">
+        <a href="#seating-plan">
+          <i class="material-icons">event_seat</i>
+          {% trans "Seating plan" %}
+        </a>
+      </li>
     {% endif %}
+    {% if prev_lesson %}
+      {% has_perm "alsijil.view_lessondocumentation_rule" user prev_lesson as can_view_prev_lesson_documentation %}
+      {% if prev_lesson.get_lesson_documentation and can_view_prev_lesson_documentation %}
+        <li class="tab">
+          <a href="#previous-lesson">
+            <i class="material-icons">history</i>
+            {% trans "Previous" %}
+          </a>
+        </li>
+      {% endif %}
+    {% endif %}
+    <li class="tab">
+      <a href="#more">
+        <i class="material-icons">more_horiz</i>
+        {% trans "More" %}
+      </a>
+    </li>
+  </ul>
+{% endblock %}
 
-    {{ register_object.group_names }},
-
-    {% if register_object.label_ == "event" %}
-      {% trans "Event" %} ({{ register_object.title }})
-    {% else %}
-      {{ register_object.get_subject.name }}
-    {% endif %},
-
-    {{ register_object.teacher_short_names }}
-
-    <span class="right">
-      {% include "alsijil/partials/lesson_status_icon.html" with register_object=register_object css_class="medium" %}
-    </span>
-  </h1>
-  <br/>
-
+{% block content %}
   {% has_perm "alsijil.view_lessondocumentation_rule" user register_object as can_view_lesson_documentation %}
   {% has_perm "alsijil.edit_lessondocumentation_rule" user register_object as can_edit_lesson_documentation %}
   {% has_perm "alsijil.edit_register_object_personalnote_rule" user register_object as can_edit_register_object_personalnote %}
 
-  <form method="post" class="row">
-    <p>
-      {% if not blocked_because_holidays %}
-        {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %}
-          {% include "core/partials/save_button.html" %}
+  {% if next_lesson_person or prev_lesson_person or back_to_week_url %}
+    <div class="row margin-bottom z-depth-1 alsijil-nav-header">
+      <div class="col s12 no-padding">
+        {# Back to week view #}
+        {% if back_to_week_url %}
+          <a href="{{ back_to_week_url }}"
+             class="btn secondary-color waves-light waves-effect margin-bottom {% if prev_lesson_person or next_lesson_person %}hide-on-extra-large-only{% endif %}">
+            <i class="material-icons left">chevron_left</i> {% trans "Week view" %}
+          </a>
         {% endif %}
-      {% endif %}
 
-      {% if prev_lesson %}
-        <a class="btn waves-effect waves-light primary"
-           href="{% url "lesson_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}">
-          <i class="material-icons left">arrow_back</i>
-          {% blocktrans with subject=register_object.get_subject.name %}
-            Previous {{ subject }} lesson
-          {% endblocktrans %}
-        </a>
-      {% endif %}
+        {% if prev_lesson_person or next_lesson_person %}
+          <div class="col s12 no-padding center alsijil-nav">
+            {% if back_to_week_url %}
+              <a href="{{ back_to_week_url }}"
+                 class="btn-flat secondary-color-text waves-light waves-effect left hide-on-med-and-down hide-on-large-only show-on-extra-large">
+                <i class="material-icons left">chevron_left</i> {% trans "Week view" %}
+              </a>
+            {% endif %}
 
-      {% if next_lesson %}
-        <a class="btn right waves-effect waves-light primary"
-           href="{% url "lesson_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}">
-          <i class="material-icons right">arrow_forward</i>
-          {% blocktrans with subject=register_object.get_subject.name %}
-            Next {{ subject }} lesson
-          {% endblocktrans %}
-        </a>
-      {% endif %}
-    </p>
+            {# Previous lesson #}
+            <a class="btn-flat waves-effect waves-light left primary-color-text {% if not prev_lesson_person %}disabled{% endif %}"
+               title="{% trans "My previous lesson" %}"
+                {% if prev_lesson_person %}
+               href="{% url "lesson_period" prev_lesson_person.week.year prev_lesson_person.week.week prev_lesson_person.id %}"
+                {% endif %}
+            >
+              <i class="material-icons left">navigate_before</i>
+              <span class="hide-on-small-only">{% trans "My previous lesson" %}</span>
+              <span class="hide-on-med-and-up">{% trans "Previous" %}</span>
+            </a>
+            {# Next lesson #}
+            <a class="btn-flat waves-effect waves-light right primary-color-text {% if not next_lesson_person %}disabled{% endif %}"
+               title="{% trans "My next lesson" %}"
+                {% if next_lesson_person %}
+               href="{% url "lesson_period" next_lesson_person.week.year next_lesson_person.week.week next_lesson_person.id %}"
+                {% endif %}
+            >
+              <i class="material-icons right">navigate_next</i>
+              <span class="hide-on-small-only">{% trans "My next lesson" %}</span>
+              <span class="hide-on-med-and-up">{% trans "Next" %}</span>
+            </a>
+            <span class="truncate">{{ request.user.person }}</span>
+          </div>
+        {% endif %}
+      </div>
+    </div>
+  {% endif %}
 
+  <form method="post" class="row">
     {% csrf_token %}
 
     {% if not blocked_because_holidays %}
-
       <div class="row">
-        <div class="col s12">
-          <ul class="tabs">
-            <li class="tab">
-              <a href="#lesson-documentation">{% trans "Lesson documentation" %}</a>
-            </li>
-            {% if register_object.label_ != "lesson_period" or not register_object.get_substitution.cancelled or not request.site.preferences.alsijil__block_personal_notes_for_cancelled %}
-              <li class="tab">
-                <a href="#personal-notes">{% trans "Personal notes" %}</a>
-              </li>
-            {% endif %}
-            {% if prev_lesson %}
-              {% has_perm "alsijil.view_lessondocumentation_rule" user prev_lesson as can_view_prev_lesson_documentation %}
-              {% if prev_lesson.get_lesson_documentation and can_view_prev_lesson_documentation %}
-                <li class="tab">
-                  <a href="#previous-lesson">{% trans "Previous lesson" %}</a>
-                </li>
-              {% endif %}
-            {% endif %}
-            {% if group_roles %}
-              <li class="tab">
-                <a href="#group-roles">{% trans "Group roles" %}</a>
-              </li>
-            {% endif %}
-            <li class="tab">
-              <a href="#version-history">{% trans "Change history" %}</a>
-            </li>
-          </ul>
-        </div>
-
-        <div class="col s12" id="lesson-documentation">
-          <div class="card">
-            <div class="card-content">
-              <span class="card-title">
-                {% blocktrans %}Lesson documentation{% endblocktrans %}
-              </span>
-
-              {% if can_edit_lesson_documentation %}
-                {% form form=lesson_documentation_form %}{% endform %}
-              {% elif can_view_lesson_documentation %}
-                <table>
-                  <tr>
-                    <th>
-                      {% trans "Lesson topic" %}
-                    </th>
-                    <td>
-                      {{ lesson_documentation.topic }}
-                    </td>
-                  </tr>
-                  <tr>
-                    <th>
-                      {% trans "Homework" %}
-                    </th>
-                    <td>
-                      {{ lesson_documentation.homework }}
-                    </td>
-                  </tr>
-                  <tr>
-                    <th>
-                      {% trans "Group note" %}
-                    </th>
-                    <td>
-                      {{ lesson_documentation.group_note }}
-                    </td>
-                  </tr>
-                </table>
-              {% endif %}
-            </div>
-          </div>
+        <div class="col s12 no-padding" id="lesson-documentation">
+          {% include "alsijil/partials/lesson/tabs/documentation.html" %}
         </div>
 
         {% with prev_doc=prev_lesson.get_lesson_documentation %}
           {% with absences=prev_lesson.get_absences tardinesses=prev_lesson.get_tardinesses extra_marks=prev_lesson.get_extra_marks %}
             {% has_perm "alsijil.view_lessondocumentation_rule" user prev_lesson as can_view_prev_lesson_documentation %}
             {% if prev_doc and can_view_prev_lesson_documentation %}
-              <div class="col s12" id="previous-lesson">
-                <div class="card">
-                  <div class="card-content">
-                    <span class="card-title">
-                      {% blocktrans %}Overview: Previous lesson{% endblocktrans %} ({{ prev_doc.date_formatted }},
-                      {% blocktrans with period=prev_lesson.period.period %}{{ period }}. period{% endblocktrans %})
-                    </span>
-
-                    <table>
-                      {% if prev_doc.topic %}
-                        <tr>
-                          <th class="collection-item">{% trans "Lesson topic of previous lesson:" %}</th>
-                          <td>{{ prev_doc.topic }}</td>
-                        </tr>
-                      {% endif %}
-
-                      {% if prev_doc.homework %}
-                        <tr>
-                          <th class="collection-item">{% trans "Homework for this lesson:" %}</th>
-                          <td>{{ prev_doc.homework }}</td>
-                        </tr>
-                      {% endif %}
-
-                      {% if prev_doc.group_note %}
-                        <tr>
-                          <th class="collection-item">{% trans "Group notes for previous lesson:" %}</th>
-                          <td>{{ prev_doc.group_note }}</td>
-                        </tr>
-                      {% endif %}
-
-                      {% if absences %}
-                        <tr>
-                          <th>{% trans "Absent persons:" %}</th>
-                          <td>{% include "alsijil/partials/absences.html" with notes=absences %}</td>
-                        </tr>
-                      {% endif %}
-
-                      {% if tardinesses %}
-                        <tr>
-                          <th>{% trans "Late persons:" %}</th>
-                          <td>{% include "alsijil/partials/tardinesses.html" with notes=tardinesses %}</td>
-                        </tr>
-                      {% endif %}
-
-                      {% for extra_mark, notes in extra_marks.items %}
-                        <tr>
-                          <th>{{ extra_mark.name }}</th>
-                          <td>
-                            {% for note in notes %}
-                              {% has_perm "alsijil.view_personalnote_rule" user note as can_view_personalnote %}
-                              {% if can_view_personalnote %}
-                                <span>{{ note.person }}{% if not forloop.last %},{% endif %}</span>
-                              {% endif %}
-                            {% endfor %}
-                          </td>
-                        </tr>
-                      {% endfor %}
-
-                    </table>
-                  </div>
-                </div>
+              <div class="col s12 no-padding" id="previous-lesson">
+                {% include "alsijil/partials/lesson/tabs/previous_lesson.html" %}
               </div>
             {% endif %}
           {% endwith %}
         {% endwith %}
 
         {% if register_object.label_ != "lesson_period" or not register_object.get_substitution.cancelled or not request.site.preferences.alsijil__block_personal_notes_for_cancelled %}
-          <div class="col s12" id="personal-notes">
-            <div class="card">
-              <div class="card-content">
-                <span class="card-title">
-                  {% blocktrans %}Personal notes{% endblocktrans %}
-                </span>
-                {% if can_edit_register_object_personalnote %}
-                  {% form form=personal_note_formset.management_form %}{% endform %}
-                {% endif %}
-
-                <table class="striped responsive-table alsijil-table">
-                  <thead>
-                  <tr>
-                    <th>{% blocktrans %}Person{% endblocktrans %}</th>
-                    <th>{% blocktrans %}Absent{% endblocktrans %}</th>
-                    <th>{% blocktrans %}Tardiness{% endblocktrans %}</th>
-                    <th>{% blocktrans %}Excused{% endblocktrans %}</th>
-                    <th>{% blocktrans %}Excuse type{% endblocktrans %}</th>
-                    <th>{% blocktrans %}Extra marks{% endblocktrans %}</th>
-                    <th>{% blocktrans %}Remarks{% endblocktrans %}</th>
-                  </tr>
-                  </thead>
-                  <tbody>
-                  {% for form in personal_note_formset %}
-                    {% if can_edit_register_object_personalnote %}
-                      <tr>
-                        {{ form.id }}
-                        <td>{{ form.person_name }}{{ form.person_name.value }}
-                          <p>
-                            {% for assignment in form.instance.person.group_roles.all %}
-                              {% include "alsijil/group_role/chip.html" with role=assignment.role %}
-                            {% endfor %}
-                          </p>
-                        </td>
-                        <td class="center-align">
-                          <label>
-                            {{ form.absent }}
-                            <span></span>
-                          </label>
-                        </td>
-                        <td>
-                          <div class="input-field">
-                            {{ form.late }}
-                            <label for="{{ form.absent.id_for_label }}">
-                              {% trans "Tardiness (in m)" %}
-                            </label>
-                          </div>
-                        </td>
-                        <td class="center-align">
-                          <label>
-                            {{ form.excused }}
-                            <span></span>
-                          </label>
-                        </td>
-                        <td>
-                          <div class="input-field">
-                            {{ form.excuse_type }}
-                            <label for="{{ form.excuse_type.id_for_label }}">
-                              {% trans "Excuse type" %}
-                            </label>
-                          </div>
-                        </td>
-                        <td>
-                          {% for group, items in form.extra_marks|select_options %}
-                            {% for choice, value, selected in items %}
-                              <label class="{% if selected %} active{% endif %} alsijil-check-box">
-                                <input type="checkbox"
-                                       {% if value == None or value == '' %}disabled{% else %}value="{{ value }}"{% endif %}
-                                    {% if selected %} checked="checked"{% endif %}
-                                       name="{{ form.extra_marks.html_name }}">
-                                <span>{{ choice }}</span>
-                              </label>
-                            {% endfor %}
-                          {% endfor %}
-                        </td>
-                        <td>
-                          <div class="input-field">
-                            {{ form.remarks }}
-                            <label for="{{ form.remarks.id_for_label }}">
-                              {% trans "Remarks" %}
-                            </label>
-                          </div>
-                        </td>
-                      </tr>
-                    {% else %}
-                      <tr>
-                        <td>{{ form.person_name.value }}
-                          <p>
-                            {% for assignment in form.instance.person.group_roles.all %}
-                              {% include "alsijil/group_role/chip.html" with role=assignment.role %}
-                            {% endfor %}
-                          </p>
-                        </td>
-                        <td><i class="material-icons center">{{ form.absent.value|yesno:"check,clear" }}</i></td>
-                        <td>
-                          <i class="material-icons center">{{ form.late.value|yesno:"check,clear" }}</i>
-                          <span class="alsijil-tardiness-text">
-                            {% if form.late.value %}{{ form.late.value|to_time|time:"i\m" }}{% endif %}
-                          </span>
-                        </td>
-                        <td><i class="material-icons center">{{ form.excused.value|yesno:"check,clear" }}</i></td>
-                        <td>{% firstof form.excuse_type.value "–" %}</td>
-                        <td>
-                          {% for extra_mark in form.extra_marks.value %}
-                            {{ extra_mark }}{% if not forloop.last %},{% endif %}
-                            {% empty %}
-                            –
-                          {% endfor %}
-                        </td>
-                        <td>{% firstof form.remarks.value "–" %}</td>
-                      </tr>
-                    {% endif %}
-                  {% endfor %}
-                  </tbody>
-                </table>
-              </div>
-            </div>
+          <div class="col s12 no-padding" id="personal-notes">
+            {% include "alsijil/partials/lesson/tabs/notes.html" %}
           </div>
         {% endif %}
 
-        {% if group_roles %}
-          <div class="col s12" id="group-roles">
-            {% include "alsijil/group_role/partials/assigned_roles.html" with roles=group_roles group=register_object.get_groups.first back_url=back_url %}
+        {% if with_seating_plan %}
+          <div class="col s12 no-padding" id="seating-plan">
+            {% include "alsijil/partials/lesson/tabs/seating_plan.html" %}
           </div>
         {% endif %}
 
-        {% if can_view_lesson_documentation %}
-          <div class="col s12" id="version-history">
-            <div class="card">
-              <div class="card-content">
-                <span class="card-title">
-                  {% blocktrans %}Change history{% endblocktrans %}
-                </span>
-                {% include 'core/partials/crud_events.html' with obj=lesson_documentation %}
-              </div>
-            </div>
-          </div>
-        {% endif %}
+        <div class="col s12 no-padding" id="more">
+          {% include "alsijil/partials/lesson/tabs/more.html" %}
+        </div>
       </div>
-
-
-      <p>
-        {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %}
-          {% include "core/partials/save_button.html" %}
-        {% endif %}
-
-        {% if prev_lesson %}
-          <a class="btn primary waves-effect waves-light"
-             href="{% url "lesson_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}">
-            <i class="material-icons left">arrow_back</i>
-            {% blocktrans with subject=register_object.get_subject.name %}
-              Previous {{ subject }} lesson
-            {% endblocktrans %}
-          </a>
-        {% endif %}
-
-        {% if next_lesson %}
-          <a class="btn primary right waves-effect waves-light"
-             href="{% url "lesson_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}">
-            <i class="material-icons right">arrow_forward</i>
-            {% blocktrans with subject=register_object.get_subject.name %}
-              Next {{ subject }} lesson
-            {% endblocktrans %}
-          </a>
-        {% endif %}
-      </p>
-
     {% else %}
+      {% include "alsijil/partials/lesson/heading.html" %}
+
       <div class="row no-margin">
-      <div class="container">
-        <div class="card">
-          <div class="card-content center-align">
-            <p>
-              <i class="material-icons medium orange-text">warning</i>
-            </p>
-            <p class="card-title">
-              {% blocktrans %}
-                This lesson overlaps with holidays and can't be edited.
-              {% endblocktrans %}
-            </p>
-            <span class="badge new blue no-float no-margin">{{ holiday }}</span>
+        <div class="container">
+          <div class="card">
+            <div class="card-content center-align">
+              <p>
+                <i class="material-icons medium orange-text">warning</i>
+              </p>
+              <p class="card-title">
+                {% blocktrans %}
+                  This lesson overlaps with holidays and can't be edited.
+                {% endblocktrans %}
+              </p>
+              <span class="badge new blue no-float no-margin">{{ holiday }}</span>
+            </div>
           </div>
         </div>
       </div>
-      </div>
     {% endif %}
   </form>
 {% endblock %}
diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/person.html b/aleksis/apps/alsijil/templates/alsijil/class_register/person.html
index 304aae60e48a0a4292848e3a10ca93f0fb42c370..d11b192fbecb27004b1cb850e0e3070239975187 100644
--- a/aleksis/apps/alsijil/templates/alsijil/class_register/person.html
+++ b/aleksis/apps/alsijil/templates/alsijil/class_register/person.html
@@ -125,30 +125,44 @@
             <div class="collapsible-body">
               <table>
                 <tr>
-                  <th colspan="2">{% trans 'Absences' %}</th>
+                  <th colspan="3">{% trans 'Absences' %}</th>
                   <td>{{ stat.absences_count }}</td>
                 </tr>
                 <tr>
-                  <td rowspan="{{ excuse_types.count|add:2 }}" class="hide-on-small-only">{% trans "thereof" %}</td>
-                  <td rowspan="{{ excuse_types.count|add:2 }}" class="hide-on-med-and-up"></td>
-                  <th class="truncate">{% trans 'Excused' %}</th>
+                  <td rowspan="{{ excuse_types.count|add:3 }}" class="hide-on-small-only">{% trans "thereof" %}</td>
+                  <td rowspan="{{ excuse_types.count|add:3 }}" class="hide-on-med-and-up"></td>
+                  <th colspan="2">{% trans 'Excused' %}</th>
                   <td>{{ stat.excused }}</td>
                 </tr>
+                <tr>
+                  <td rowspan="{{ excuse_types.count|add:1 }}" class="hide-on-small-only">{% trans "thereof" %}</td>
+                  <td rowspan="{{ excuse_types.count|add:1 }}" class="hide-on-med-and-up"></td>
+                  <th colspan="2" class="truncate">{% trans 'Without Excuse Type' %}</th>
+                  <td>{{ stat.excused_no_excuse_type }}</td>
+                </tr>
                 {% for excuse_type in excuse_types %}
-                  <th>{{ excuse_type.name }}</th>
-                  <td>{{ stat|get_dict:excuse_type.count_label }}</td>
+                  <tr>
+                    <th>{{ excuse_type.name }}</th>
+                    <td>{{ stat|get_dict:excuse_type.count_label }}</td>
+                  </tr>
                 {% endfor %}
                 <tr>
-                  <th>{% trans 'Unexcused' %}</th>
+                  <th colspan="2">{% trans 'Unexcused' %}</th>
                   <td>{{ stat.unexcused }}</td>
                 </tr>
+                {% for excuse_type in excuse_types_not_absent %}
+                  <tr>
+                    <th colspan="3">{{ excuse_type.name }}</th>
+                    <td>{{ stat|get_dict:excuse_type.count_label }}</td>
+                  </tr>
+                  {% endfor %}
                 <tr>
-                  <th colspan="2">{% trans 'Tardiness' %}</th>
+                  <th colspan="3">{% trans 'Tardiness' %}</th>
                   <td>{{ stat.tardiness }}'/{{ stat.tardiness_count }} &times;</td>
                 </tr>
                 {% for extra_mark in extra_marks %}
                   <tr>
-                    <th colspan="2">{{ extra_mark.name }}</th>
+                    <th colspan="3">{{ extra_mark.name }}</th>
                     <td>{{ stat|get_dict:extra_mark.count_label }}</td>
                   </tr>
                 {% endfor %}
diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html b/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html
index 1cdab7ff87800a30797da5c8d8c346c919ffecd9..4742b43208a86a35e4fcd51ea7e3ef07ddc4dee2 100644
--- a/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html
+++ b/aleksis/apps/alsijil/templates/alsijil/class_register/week_view.html
@@ -8,6 +8,36 @@
 {% block extra_head %}
   {{ block.super }}
   <link rel="stylesheet" href="{% static 'css/alsijil/alsijil.css' %}"/>
+  <link rel="stylesheet" href="{% static 'css/alsijil/week_view.css' %}"/>
+{% endblock %}
+
+{% block nav_content %}
+  {% if lesson_periods %}
+    <div class="">
+      <ul class="tabs tabs-transparent tabs-icons tabs-fixed-width">
+        <li class="tab col">
+          <a class="active" href="#week-overview">
+            <i class="material-icons">speaker_notes</i>
+            {% trans "Lesson documentations" %}
+          </a>
+        </li>
+        <li class="tab col">
+          <a href="#personal-notes">
+            <i class="material-icons">people</i>
+            {% trans "Persons" %}
+          </a>
+        </li>
+        {% if group_roles %}
+          <li class="tab col">
+            <a href="#group-roles">
+              <i class="material-icons">assignment_ind</i>
+              {% trans "Group roles" %}
+            </a>
+          </li>
+        {% endif %}
+      </ul>
+    </div>
+  {% endif %}
 {% endblock %}
 
 {% block content %}
@@ -15,15 +45,23 @@
   {{ week_select|json_script:"week_select" }}
   <script type="text/javascript" src="{% static "js/chronos/week_select.js" %}"></script>
   <div class="row">
-    <div class="col s12">
+    <div id="toggle-row" class="col s12 m8 l10 {% if lesson_periods %}pre-hidden{% endif %}">
       <form method="post" action="">
         {% csrf_token %}
         {% form form=select_form %}{% endform %}
-        <button type="submit" class="btn waves-effect waves-light">
+        <button type="submit" class="btn waves-effect waves-light primary-color">
+          <i class="material-icons left">check</i>
           {% blocktrans %}Select{% endblocktrans %}
         </button>
       </form>
     </div>
+    <div class="col s12 m4 l2 right">
+      <button type="button" class="btn waves-effect waves-light hundred-percent" id="toggle-button">
+        <i class="material-icons left">
+          filter_alt
+        </i> {% trans "Toggle filters" %}
+      </button>
+    </div>
   </div>
 
 
@@ -46,7 +84,8 @@
     </p>
 
     <p class="hide-on-med-and-up">
-      <a class="btn primary-color waves-effect waves-light hundred-percent" href="{% url "students_list" group.pk %}">
+      <a class="btn primary-color waves-effect waves-light hundred-percent"
+         href="{% url "students_list" group.pk %}">
         <i class="material-icons left">people</i>
         {% trans "Students list" %}
       </a>
@@ -62,39 +101,24 @@
 
   {% if lesson_periods %}
     <div class="row">
-      <div class="col s12">
-        <ul class="tabs">
-          <li class="tab col">
-            <a class="active" href="#week-overview">{% trans "Lesson documentations" %}</a>
-          </li>
-          <li class="tab col">
-            <a href="#personal-notes">{% trans "Personal notes" %}</a>
-          </li>
-          {% if group_roles %}
-            <li class="tab col">
-              <a href="#group-roles">{% trans "Group roles" %}</a>
-            </li>
-          {% endif %}
-        </ul>
-      </div>
       <div class="col s12" id="week-overview">
         {% for weekday, objects in regrouped_objects.items %}
           {% with weekdays|get_dict:objects.0.weekday as advanced_weekday %}
             {% if advanced_weekday.holiday and not request.site.preferences.alsijil__allow_entries_in_holidays %}
               <div class="card">
                 <div class="card-content">
-                  <span class="card-title">
-                    {{ advanced_weekday.name }}, {{ advanced_weekday.date }} <span
+                    <span class="card-title">
+                      {{ advanced_weekday.name }}, {{ advanced_weekday.date }} <span
                       class="badge new blue no-float">{{ advanced_weekday.holiday }}</span>
-                  </span>
+                    </span>
                 </div>
               </div>
             {% else %}
               <div class="card show-on-extra-large">
                 <div class="card-content">
-                  <span class="card-title">
-                    {{ advanced_weekday.name }}, {{ advanced_weekday.date }}
-                  </span>
+                    <span class="card-title">
+                      {{ advanced_weekday.name }}, {{ advanced_weekday.date }}
+                    </span>
                   <table class="striped datatable">
                     <thead>
                     <tr>
@@ -116,7 +140,7 @@
                       {% if can_view_lesson_documentation %}
                         <tr>
                           <td class="center-align">
-                            {% include "alsijil/partials/lesson_status_icon.html" with register_object=register_object %}
+                            {% include "alsijil/partials/lesson_status.html" with register_object=register_object %}
                           </td>
                           <td class="tr-link">
                             <a class="tr-link"
@@ -124,7 +148,8 @@
                               {% if register_object.period %}
                                 {{ register_object.period.period }}.
                               {% else %}
-                                {{ register_object.period_from_on_day }}.–{{ register_object.period_to_on_day }}.
+                                {{ register_object.period_from_on_day }}.–
+                                {{ register_object.period_to_on_day }}.
                               {% endif %}
                             </a>
                           </td>
@@ -155,7 +180,7 @@
                           <td>
                             <a class="tr-link"
                                href="{{ register_object.alsijil_url }}?back={{ back_url }}">
-                                {{ register_object.teacher_names }}
+                              {{ register_object.teacher_names }}
                             </a>
                           </td>
                           <td>
@@ -183,11 +208,11 @@
                   </table>
                 </div>
               </div>
-              <ul class="collapsible hide-on-extra-large-only">
+              <ul class="collapsible hide-on-extra-large-only hide-on-small-only">
                 <li class="">
                   <div class="collapsible-header flow-text">
                     {{ advanced_weekday.name }}, {{ advanced_weekday.date }} <i
-                      class="material-icons collapsible-icon-right">expand_more</i>
+                    class="material-icons collapsible-icon-right">expand_more</i>
                   </div>
                   <div class="collapsible-body">
                     <div class="collection">
@@ -196,15 +221,16 @@
                         {% if can_view_lesson_documentation %}
                           <a class="collection-item avatar"
                              href="{{ register_object.alsijil_url }}?back={{ back_url }}">
-                            {% include "alsijil/partials/lesson_status_icon.html" with register_object=register_object css_class="materialize-circle" color_suffix=" " %}
-                            <table class="hide-on-med-and-down">
+                            {% include "alsijil/partials/lesson_status.html" with register_object=register_object css_class="materialize-circle" color_suffix=" " %}
+                            <table>
                               <tr>
                                 <th>{% trans "Subject" %}</th>
                                 <td>
                                   {% if register_object.period %}
                                     {{ register_object.period.period }}.
                                   {% else %}
-                                    {{ register_object.period_from_on_day }}.–{{ register_object.period_to_on_day }}.
+                                    {{ register_object.period_from_on_day }}.–
+                                    {{ register_object.period_to_on_day }}.
                                   {% endif %}
                                   {% if register_object.get_subject %}
                                     {{ register_object.get_subject.name }}
@@ -230,14 +256,14 @@
                               <tr>
                                 <th>{% trans "Teachers" %}</th>
                                 <td>
-                                    {{ register_object.teacher_names }}
+                                  {{ register_object.teacher_names }}
                                 </td>
                               </tr>
                               <tr>
                                 <th>{% trans "Lesson topic" %}</th>
                                 <td>{% firstof register_object.get_lesson_documentation.topic "–" %}</td>
                               </tr>
-                              {% with period.get_lesson_documentation as lesson_documentation %}
+                              {% with register_object.get_lesson_documentation as lesson_documentation %}
                                 {% if lesson_documentation.homework %}
                                   <tr>
                                     <th>{% trans "Homework" %}</th>
@@ -252,53 +278,6 @@
                                 {% endif %}
                               {% endwith %}
                             </table>
-                            <div class="hide-on-large-only">
-                              <ul class="collection">
-                                <li class="collection-item">
-                                  {% if register_object.period %}
-                                    {{ register_object.period.period }}.
-                                  {% else %}
-                                    {{ register_object.period_from_on_day }}.–{{ register_object.period_to_on_day }}.
-                                  {% endif %}
-                                  {% if register_object.get_subject %}
-                                    {{ register_object.get_subject.name }}
-                                  {% elif register_object.subject %}
-                                    {{ register_object.subject }}
-                                  {% else %}
-                                    {% trans "Event" %} ({{ register_object.title }})
-                                  {% endif %}
-                                </li>
-                                {% if not group %}
-                                  <li class="collection-item">
-                                    {% if register_object.lesson %}
-                                      {{ register_object.lesson.group_names }}
-                                    {% else %}
-                                      {{ register_object.group_names }}
-                                    {% endif %}
-                                  </li>
-                                {% endif %}
-                                <li class="collection-item">
-                                  {{ register_object.teacher_names }}
-                                </li>
-                                <li class="collection-item">
-                                  {{ register_object.get_lesson_documentation.topic }}
-                                </li>
-                                {% with period.get_lesson_documentation as lesson_documentation %}
-                                  {% if lesson_documentation.homework %}
-                                    <li class="collection-item">
-                                      <strong>{% trans "Homework" %}</strong>
-                                      {% firstof register_object.get_lesson_documentation.homework "–" %}
-                                    </li>
-                                  {% endif %}
-                                  {% if lesson_documentation.group_note %}
-                                    <li class="collection-item">
-                                      <strong>{% trans "Group note" %}</strong>
-                                      {% firstof register_object.get_lesson_documentation.group_note "–" %}
-                                    </li>
-                                  {% endif %}
-                                {% endwith %}
-                              </ul>
-                            </div>
                           </a>
                         {% endif %}
                       {% endfor %}
@@ -306,6 +285,85 @@
                   </div>
                 </li>
               </ul>
+              <div class="hide-on-med-and-up">
+                <h3>{{ advanced_weekday.name }}</h3>
+                <p class="subtitle">
+                  <span>{{ advanced_weekday.date }}</span>
+                  <button class="btn-superflat right waves-effect unfold-trigger">
+                    {% trans "Unfold" %} <i class="material-icons">
+                    expand_less
+                  </i>
+                  </button>
+                </p>
+                <div class="horizontal-scroll-container">
+                  {% for register_object in objects %}
+                    <div class="card horizontal-scroll-card">
+                      <div class="card-content">
+                        <span class="card-title">
+                          <span class="period">
+                            {% if register_object.period %}
+                              {{ register_object.period.period }}.
+                            {% else %}
+                              {{ register_object.period_from_on_day }}.–{{ register_object.period_to_on_day }}.
+                            {% endif %}
+                          </span>
+                          <span class="subject">
+                            {% if register_object.get_subject %}
+                              {{ register_object.get_subject.name }}
+                            {% elif register_object.subject %}
+                              {{ register_object.subject }}
+                            {% else %}
+                              {% trans "Event" %}
+                            {% endif %}
+                          </span>
+                          <span class="lesson-icon">
+                            {% include "alsijil/partials/lesson_status.html" with register_object=register_object %}
+                          </span>
+                        </span>
+                        <dl>
+                          <div class="one-line">
+                            {% if not group %}
+                              <dt>{% trans "Groups" %}</dt>
+                              <dd>
+                                {% if register_object.lesson %}
+                                  {{ register_object.lesson.group_names }}
+                                {% else %}
+                                  {{ register_object.group_names }}
+                                {% endif %}
+                              </dd>
+                            {% endif %}
+
+                            <dt>{% trans "Teachers" %}</dt>
+                            <dd>
+                              {{ register_object.teacher_names }}
+                            </dd>
+                          </div>
+
+                          <dt>{% trans "Lesson topic" %}</dt>
+                          <dd>{% firstof register_object.get_lesson_documentation.topic "–" %}</dd>
+
+                          {% with register_object.get_lesson_documentation as lesson_documentation %}
+                            {% if lesson_documentation.homework %}
+                              <dt>{% trans "Homework" %}</dt>
+                              <dd>{% firstof register_object.get_lesson_documentation.homework "–" %}</dd>
+                            {% endif %}
+                            {% if lesson_documentation.group_note %}
+                              <dt>{% trans "Group note" %}</dt>
+                              <dd>{% firstof register_object.get_lesson_documentation.group_note "–" %}</dd>
+                            {% endif %}
+                          {% endwith %}
+                        </dl>
+                      </div>
+                      <div class="card-action">
+                        <a href="{{ register_object.alsijil_url }}?back={{ back_url }}"
+                           class="">
+                          {% trans "Visit lesson overview" %}
+                        </a>
+                      </div>
+                    </div>
+                  {% endfor %}
+                </div>
+              </div>
             {% endif %}
           {% endwith %}
         {% endfor %}
@@ -313,9 +371,9 @@
       <div class="col s12" id="personal-notes">
         <div class="card">
           <div class="card-content">
-            <span class="card-title">
-              {% blocktrans %}Personal notes{% endblocktrans %}
-            </span>
+              <span class="card-title">
+                {% blocktrans %}Personal notes{% endblocktrans %}
+              </span>
             {% for person in persons %}
               <h5 class="card-title">
                 <a href="{% url "overview_person" person.person.pk %}">{{ person.person.full_name }}</a>
@@ -371,9 +429,10 @@
       {% endif %}
     </div>
   {% else %}
-    <div class="card red darken-1">
-      <div class="card-content white-text">
+    <div class="card">
+      <div class="card-content">
         <span class="card-title">
+          <i class="material-icons red-text left">warning</i>
           {% blocktrans %}No lessons available{% endblocktrans %}
         </span>
         <p>
@@ -385,15 +444,5 @@
     </div>
   {% endif %}
 
-  <script>
-      $(document).ready(function () {
-          $("#id_group").change(function () {
-              $("#id_teacher").val("").formSelect();
-          });
-          $("#id_teacher").change(function () {
-              $("#id_group").val("").formSelect();
-          });
-      });
-
-  </script>
+  <script src="{% static 'js/alsijil/week_view.js' %}" type="text/javascript"></script>
 {% endblock %}
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/legend.html b/aleksis/apps/alsijil/templates/alsijil/partials/legend.html
index a2c6ba1aaee02c492155c08b902f1562b405b3a7..bf0c82d792b57943b36502f0b94dff3db193a70d 100644
--- a/aleksis/apps/alsijil/templates/alsijil/partials/legend.html
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/legend.html
@@ -7,17 +7,21 @@
         <h6>{% trans "General" %}</h6>
         <ul class="collection">
           <li class="collection-item chip-height">
-            <strong>(a)</strong> {% trans "Absences" %}
+            <strong>{% trans "(a)" %}</strong> {% trans "Absences" %}
             <span class="chip secondary-color white-text right">0</span>
           </li>
           <li class="collection-item chip-height">
-            <strong>(u)</strong> {% trans "Unexcused absences" %}
+            <strong>{% trans "(u)" %}</strong> {% trans "Unexcused absences" %}
             <span class="chip red white-text right">0</span>
           </li>
           <li class="collection-item chip-height">
-            <strong>(e)</strong> {% trans "Excused absences" %}
+            <strong>{% trans "Sum (e)" %}</strong> {% trans "Sum of excused absences" %}
             <span class="chip green white-text right">0</span>
           </li>
+          <li class="collection-item chip-height">
+            <strong>{% trans "(e)" %}</strong> {% trans "Regular excused absences" %}
+            <span class="chip grey white-text right">0</span>
+          </li>
         </ul>
       </div>
 
@@ -33,6 +37,18 @@
               </li>
             {% endfor %}
           </ul>
+          {% if excuse_types_not_absent %}
+            <h6>{% trans "Excuse types (not counted as absent)" %}</h6>
+
+            <ul class="collection">
+              {% for excuse_type in excuse_types_not_absent %}
+                <li class="collection-item chip-height">
+                  <strong>({{ excuse_type.short_name }})</strong> {{ excuse_type.name }}
+                  <span class="chip grey white-text right">0</span>
+                </li>
+              {% endfor %}
+            </ul>
+          {% endif %}
         </div>
       {% endif %}
 
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html
new file mode 100644
index 0000000000000000000000000000000000000000..07c14a649a96892987b984aa315e955df856cbf7
--- /dev/null
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/heading.html
@@ -0,0 +1,61 @@
+{% load i18n %}
+
+<h1>
+  <span class="right hide-on-small-only">
+    {% include "alsijil/partials/lesson_status.html" with register_object=register_object css_class="medium" %}
+  </span>
+
+  <a class="btn-flat waves-effect waves-light primary-color-text left alsijil-header-nav-button hide-on-med-and-up {% if not prev_lesson %}disabled{% endif %}"
+      {% if prev_lesson %}
+     href="{% url "lesson_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}"
+      {% endif %}
+  >
+    <i class="material-icons center">navigate_before</i>
+  </a>
+  <a class="btn-flat waves-effect waves-light primary-color-text right alsijil-header-nav-button hide-on-med-and-up {% if not next_lesson %}disabled{% endif %}"
+      {% if next_lesson %}
+     href="{% url "lesson_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}"
+      {% endif %}
+  >
+    <i class="material-icons center">navigate_next</i>
+  </a>
+
+  <span class="alsijil-time-head">
+    {% if register_object.label_ == "event" %}
+      {% if register_object.date_start == register_object.date_end %}
+        {% if register_object.period_from.period == register_object.period_to.period %}
+          {{ register_object.date_start|date:"SHORT_DATE_FORMAT" }},
+          {% blocktrans with period=register_object.period_from.period %}{{ period }}. period{% endblocktrans %}
+        {% else %}
+          {{ register_object.date_start|date:"SHORT_DATE_FORMAT" }},
+          {% blocktrans with period_from=register_object.period_from.period  period_to=register_object.period_to.period %}
+            {{ period_from }}.–{{ period_to }}.  period
+          {% endblocktrans %}
+        {% endif %}
+      {% else %}
+        {{ register_object.date_start|date:"SHORT_DATE_FORMAT" }},
+        {{ register_object.period_from.period }}.–{{ register_object.date_end|date:"SHORT_DATE_FORMAT" }},
+        {{ register_object.period_to.period }}.
+      {% endif %}
+    {% else %}
+      {{ day|date:"SHORT_DATE_FORMAT" }},
+      {% blocktrans with period=register_object.period.period %}{{ period }}. period{% endblocktrans %}
+    {% endif %}
+  </span>
+
+  <span class="alsijil-object-head">
+    {{ register_object.group_names }},
+
+    {% if register_object.label_ == "event" %}
+      {% trans "Event" %} ({{ register_object.title }}),
+    {% else %}
+      {{ register_object.get_subject.short_name }},
+    {% endif %}
+
+    {{ register_object.teacher_short_names }}
+  </span>
+</h1>
+
+<div class="hide-on-med-and-up margin-bottom">
+  {% include "alsijil/partials/lesson_status.html" with register_object=register_object chip=1 css_class="hundred-percent center" %}
+</div>
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html
new file mode 100644
index 0000000000000000000000000000000000000000..dcddcfcc13a6437bf1982f9e3ce20930e9aaf774
--- /dev/null
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/prev_next.html
@@ -0,0 +1,37 @@
+{% load i18n %}
+
+<div class="row no-margin hide-on-small-only">
+  <div class="col s12 no-padding">
+    {% if not blocked_because_holidays and with_save %}
+      {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %}
+        <button type="submit" class="btn waves-effect waves-light green margin-bottom">
+          <i class="material-icons left">save</i> {% trans "Save" %}
+        </button>
+      {% endif %}
+    {% endif %}
+
+    <a class="btn waves-effect waves-light primary margin-bottom {% if not prev_lesson %}disabled{% endif %}"
+        {% if prev_lesson %}
+       href="{% url "lesson_period" prev_lesson.week.year prev_lesson.week.week prev_lesson.id %}"
+        {% endif %}
+    >
+      <i class="material-icons left">arrow_back</i>
+      {% blocktrans with subject=register_object.get_subject.short_name %}
+        Previous {{ subject }} lesson
+      {% endblocktrans %}
+    </a>
+
+    <a class="btn right waves-effect waves-light primary margin-bottom {% if not next_lesson %}disabled{% endif %}"
+        {% if next_lesson %}
+       href="{% url "lesson_period" next_lesson.week.year next_lesson.week.week next_lesson.id %}"
+        {% endif %}
+    >
+      <i class="material-icons right">arrow_forward</i>
+      {% blocktrans with subject=register_object.get_subject.short_name %}
+        Next {{ subject }} lesson
+      {% endblocktrans %}
+    </a>
+  </div>
+</div>
+
+
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html
new file mode 100644
index 0000000000000000000000000000000000000000..ef0f42048bf1df524924ec1f380f8d88dd7fab3e
--- /dev/null
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/documentation.html
@@ -0,0 +1,66 @@
+{% load i18n material_form_internal material_form %}
+
+{% include "alsijil/partials/lesson/heading.html" %}
+{% include "alsijil/partials/lesson/prev_next.html" with with_save=0 %}
+
+<div class="hide-on-med-and-up margin-bottom">
+  {% if not blocked_because_holidays %}
+    {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %}
+      {% include "core/partials/save_button.html" %}
+    {% endif %}
+  {% endif %}
+</div>
+
+<div class="card">
+  <div class="card-content">
+    <span class="card-title">
+      {% blocktrans %}Lesson documentation{% endblocktrans %}
+    </span>
+
+    {% if can_edit_lesson_documentation %}
+      {% form form=lesson_documentation_form %}{% endform %}
+    {% elif can_view_lesson_documentation %}
+      <table>
+        <tr>
+          <th>
+            {% trans "Lesson topic" %}
+          </th>
+          <td>
+            {{ lesson_documentation.topic }}
+          </td>
+        </tr>
+        <tr>
+          <th>
+            {% trans "Homework" %}
+          </th>
+          <td>
+            {{ lesson_documentation.homework }}
+          </td>
+        </tr>
+        <tr>
+          <th>
+            {% trans "Group note" %}
+          </th>
+          <td>
+            {{ lesson_documentation.group_note }}
+          </td>
+        </tr>
+      </table>
+    {% endif %}
+  </div>
+  <div class="card-action-light hide-on-small-only">
+    {% if not blocked_because_holidays %}
+      {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %}
+        {% include "core/partials/save_button.html" %}
+      {% endif %}
+    {% endif %}
+  </div>
+</div>
+
+<div class="hide-on-med-and-up">
+  {% if not blocked_because_holidays %}
+    {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %}
+      {% include "core/partials/save_button.html" %}
+    {% endif %}
+  {% endif %}
+</div>
\ No newline at end of file
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html
new file mode 100644
index 0000000000000000000000000000000000000000..b7e010125077dd003e529bb85432dfc64adad7ab
--- /dev/null
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/more.html
@@ -0,0 +1,18 @@
+{% load i18n %}
+
+{% include "alsijil/partials/lesson/heading.html" %}
+
+{% if group_roles %}
+  {% include "alsijil/group_role/partials/assigned_roles.html" with roles=group_roles group=register_object.get_groups.first back_url=back_url %}
+{% endif %}
+
+{% if can_view_lesson_documentation %}
+  <div class="card">
+    <div class="card-content">
+      <span class="card-title">
+        {% blocktrans %}Change history{% endblocktrans %}
+      </span>
+      {% include 'core/partials/crud_events.html' with obj=lesson_documentation %}
+    </div>
+  </div>
+{% endif %}
\ No newline at end of file
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html
new file mode 100644
index 0000000000000000000000000000000000000000..42dcac323f7086de7818ae1cfb69fd8e41d15a8e
--- /dev/null
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/notes.html
@@ -0,0 +1,139 @@
+{% load i18n material_form_internal material_form time_helpers %}
+
+{% include "alsijil/partials/lesson/heading.html" %}
+{% include "alsijil/partials/lesson/prev_next.html" with with_save=1 %}
+
+{% if not blocked_because_holidays %}
+  {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %}
+    <button type="submit"
+            class="btn waves-effect waves-light green margin-bottom hundred-percent hide-on-med-and-up">
+      <i class="material-icons left">save</i> {% trans "Save" %}
+    </button>
+  {% endif %}
+{% endif %}
+
+{% if can_edit_register_object_personalnote %}
+  {% form form=personal_note_formset.management_form %}{% endform %}
+{% endif %}
+
+<div class="card no-mobile-card">
+  <div class="card-content">
+    <span class="card-title">
+      {% blocktrans %}Personal notes{% endblocktrans %}
+    </span>
+
+    <table class="striped alsijil-table horizontal-on-small">
+      <thead>
+      <tr>
+        <th>{% blocktrans %}Person{% endblocktrans %}</th>
+        <th>{% blocktrans %}Absent{% endblocktrans %}</th>
+        <th>{% blocktrans %}Tardiness{% endblocktrans %}</th>
+        <th>{% blocktrans %}Excused{% endblocktrans %}</th>
+        <th>{% blocktrans %}Excuse type{% endblocktrans %}</th>
+        <th>{% blocktrans %}Extra marks{% endblocktrans %}</th>
+        <th>{% blocktrans %}Remarks{% endblocktrans %}</th>
+      </tr>
+      </thead>
+      <tbody>
+      {% for form in personal_note_formset %}
+        {% if can_edit_register_object_personalnote %}
+          <tr>
+            {{ form.id }}
+            <td class="person-name">{{ form.person_name }}{{ form.person_name.value }}
+              <p>
+                {% for assignment in form.instance.person.group_roles.all %}
+                  {% include "alsijil/group_role/chip.html" with role=assignment.role %}
+                {% endfor %}
+              </p>
+            </td>
+            <td class="center-align">
+              <label>
+                {{ form.absent }}
+                <span><span class="hide-on-large-only">{{ form.absent.label }}</span></span>
+              </label>
+            </td>
+            <td>
+              <div class="input-field">
+                {{ form.late }}
+                <label for="{{ form.absent.id_for_label }}">
+                  {% trans "Tardiness (in m)" %}
+                </label>
+              </div>
+            </td>
+            <td class="center-align">
+              <label>
+                {{ form.excused }}
+                <span><span class="hide-on-large-only">{{ form.excused.label }}</span></span>
+              </label>
+            </td>
+            <td>
+              <div class="input-field">
+                {{ form.excuse_type }}
+                <label for="{{ form.excuse_type.id_for_label }}">
+                  {% trans "Excuse type" %}
+                </label>
+              </div>
+            </td>
+            <td>
+              {% for group, items in form.extra_marks|select_options %}
+                {% for choice, value, selected in items %}
+                  <label class="{% if selected %} active{% endif %} alsijil-check-box">
+                    <input type="checkbox"
+                           {% if value == None or value == '' %}disabled{% else %}value="{{ value }}"{% endif %}
+                        {% if selected %} checked="checked"{% endif %}
+                           name="{{ form.extra_marks.html_name }}">
+                    <span>{{ choice }}</span>
+                  </label>
+                {% endfor %}
+              {% endfor %}
+            </td>
+            <td>
+              <div class="input-field">
+                {{ form.remarks }}
+                <label for="{{ form.remarks.id_for_label }}">
+                  {% trans "Remarks" %}
+                </label>
+              </div>
+            </td>
+          </tr>
+        {% else %}
+          <tr>
+            <td>{{ form.person_name.value }}
+              <p>
+                {% for assignment in form.instance.person.group_roles.all %}
+                  {% include "alsijil/group_role/chip.html" with role=assignment.role %}
+                {% endfor %}
+              </p>
+            </td>
+            <td><i class="material-icons center">{{ form.absent.value|yesno:"check,clear" }}</i></td>
+            <td>
+              <i class="material-icons center">{{ form.late.value|yesno:"check,clear" }}</i>
+              <span class="alsijil-tardiness-text">
+                {% if form.late.value %}{{ form.late.value|to_time|time:"i\m" }}{% endif %}
+              </span>
+            </td>
+            <td><i class="material-icons center">{{ form.excused.value|yesno:"check,clear" }}</i></td>
+            <td>{% firstof form.instance.excuse_type "–" %}</td>
+            <td>
+              {% for extra_mark in form.instance.extra_marks.all %}
+                {{ extra_mark }}{% if not forloop.last %},{% endif %}
+              {% empty %}
+                –
+              {% endfor %}
+            </td>
+            <td>{% firstof form.remarks.value "–" %}</td>
+          </tr>
+        {% endif %}
+      {% endfor %}
+      </tbody>
+    </table>
+  </div>
+</div>
+{% if not blocked_because_holidays %}
+  {% if can_edit_lesson_documentation or can_edit_register_object_personalnote %}
+    <button type="submit"
+            class="btn waves-effect waves-light green margin-bottom hundred-percent hide-on-med-and-up">
+      <i class="material-icons left">save</i> {% trans "Save" %}
+    </button>
+  {% endif %}
+{% endif %}
\ No newline at end of file
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html
new file mode 100644
index 0000000000000000000000000000000000000000..8457576b786f579032d5c02052c3ea02a940b6ce
--- /dev/null
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/previous_lesson.html
@@ -0,0 +1,62 @@
+{% load i18n rules %}
+
+<div class="card">
+  <div class="card-content">
+    <span class="card-title">
+      {% blocktrans %}Overview: Previous lesson{% endblocktrans %} ({{ prev_doc.date_formatted }},
+      {% blocktrans with period=prev_lesson.period.period %}{{ period }}. period{% endblocktrans %})
+    </span>
+
+    <table>
+      {% if prev_doc.topic %}
+        <tr>
+          <th class="collection-item">{% trans "Lesson topic of previous lesson:" %}</th>
+          <td>{{ prev_doc.topic }}</td>
+        </tr>
+      {% endif %}
+
+      {% if prev_doc.homework %}
+        <tr>
+          <th class="collection-item">{% trans "Homework for this lesson:" %}</th>
+          <td>{{ prev_doc.homework }}</td>
+        </tr>
+      {% endif %}
+
+      {% if prev_doc.group_note %}
+        <tr>
+          <th class="collection-item">{% trans "Group notes for previous lesson:" %}</th>
+          <td>{{ prev_doc.group_note }}</td>
+        </tr>
+      {% endif %}
+
+      {% if absences %}
+        <tr>
+          <th>{% trans "Absent persons:" %}</th>
+          <td>{% include "alsijil/partials/absences.html" with notes=absences %}</td>
+        </tr>
+      {% endif %}
+
+      {% if tardinesses %}
+        <tr>
+          <th>{% trans "Late persons:" %}</th>
+          <td>{% include "alsijil/partials/tardinesses.html" with notes=tardinesses %}</td>
+        </tr>
+      {% endif %}
+
+      {% for extra_mark, notes in extra_marks.items %}
+        <tr>
+          <th>{{ extra_mark.name }}</th>
+          <td>
+            {% for note in notes %}
+              {% has_perm "alsijil.view_personalnote_rule" user note as can_view_personalnote %}
+              {% if can_view_personalnote %}
+                <span>{{ note.person }}{% if not forloop.last %},{% endif %}</span>
+              {% endif %}
+            {% endfor %}
+          </td>
+        </tr>
+      {% endfor %}
+
+    </table>
+  </div>
+</div>
\ No newline at end of file
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html
new file mode 100644
index 0000000000000000000000000000000000000000..1dcfbed7d043b1f068e8e8f7f2f74e9028aa8de7
--- /dev/null
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson/tabs/seating_plan.html
@@ -0,0 +1,89 @@
+{% load i18n material_form_internal material_form time_helpers rules %}
+
+
+{% if seating_plan %}
+  <div class="card no-mobile-card">
+    <div class="card-content">
+      <div class="card-title margin-bottom">
+        {% blocktrans with group=seating_plan.group room=seating_plan.room %}Seating plan for {{ group }} in
+          {{ room }}{% endblocktrans %}
+      </div>
+      {% if seating_plan_parent %}
+        <figure class="alert primary">
+          <i class="material-icons left">info</i>
+          {% blocktrans with child_group=first_group %}
+            This seating plan is taken from the parent group of {{ child_group }}.
+            If you want, you can take it over for your group and then customize it.
+          {% endblocktrans %}
+        </figure>
+      {% endif %}
+
+      <div class="row margin-bottom no-padding">
+        <div class="col s12 no-padding">
+          {% has_perm "stoelindeling.edit_seatingplan_rule" user seating_plan as can_edit %}
+          {% has_perm "stoelindeling.copy_seatingplan_for_group_rule" user first_group as can_copy %}
+
+          {% if can_edit %}
+            <a class="btn orange waves-effect waves-light"
+               href="{% url "edit_seating_plan" seating_plan.pk %}?next={{ back_url }}#seating-plan">
+              <i class="material-icons left">edit</i>
+              {% trans "Edit seating plan" %}
+            </a>
+          {% endif %}
+          {% if can_copy and seating_plan_parent %}
+            <a class="btn orange waves-effect waves-light"
+               href="{% url "copy_seating_plan" seating_plan.pk %}?next={{ back_url }}#seating-plan">
+              <i class="material-icons left">content_copy</i>
+              {% trans "Copy plan and edit" %}
+            </a>
+          {% endif %}
+        </div>
+      </div>
+
+      <div class="row">
+        <div class="col s12">
+          {% include "stoelindeling/seating_plan/render.html" %}
+        </div>
+      </div>
+    </div>
+  </div>
+{% else %}
+  <div class="container">
+    <div class="card">
+      <div class="card-content">
+        <div class="card-title">
+          <i class="material-icons left small orange-text">warning</i>
+          {% trans "There is no seating plan for this lesson." %}
+        </div>
+        {% has_perm "stoelindeling.add_seatingplan_rule" user first_group as can_add %}
+        {% if can_add %}
+          <div class="row margin-bottom">
+            <div class="col s12">
+              <a class="btn waves-effect waves-light" href="{% url "create_seating_plan" %}?group={{ first_group.pk }}&subject={{ register_object.get_subject.pk }}&room={{ register_object.get_room.pk }}&next={{ back_url }}#seating-plan">
+                <i class="material-icons left">add</i>
+                {% blocktrans with group=first_group.name subject=register_object.get_subject.name room=register_object.get_room.name %}
+                  Create a new seating plan for {{ group }} ({{ subject }}) in {{ room }}
+                {% endblocktrans %}
+              </a>
+            </div>
+          </div>
+        {% endif %}
+        {% for parent_group in first_group.parent_groups.all %}
+          {% has_perm "stoelindeling.add_seatingplan_rule" user parent_group as can_add %}
+          {% if can_add %}
+            <div class="row">
+              <div class="col s12">
+                <a class="btn waves-effect waves-light" href="{% url "create_seating_plan" %}?group={{ parent_group.pk }}&subject={{ register_object.get_subject.pk }}&room={{ register_object.get_room.pk }}&next={{ back_url }}#seating-plan">
+                  <i class="material-icons left">add</i>
+                  {% blocktrans with group=parent_group.name room=register_object.get_room.name %}
+                    Create a new seating plan for {{ group }} in {{ room }}
+                  {% endblocktrans %}
+                </a>
+              </div>
+            </div>
+          {% endif %}
+        {% endfor %}
+      </div>
+    </div>
+  </div>
+{% endif %}
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html
new file mode 100644
index 0000000000000000000000000000000000000000..41c80fd25d208e34f38bbcd9e4137016a0734301
--- /dev/null
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status.html
@@ -0,0 +1,36 @@
+{% load i18n week_helpers %}
+
+{% now_datetime as now_dt %}
+
+{% if has_documentation or register_object.has_documentation %}
+  {% include "alsijil/partials/lesson_status_icon.html" with text=_("Data complete") icon="check_circle" color="green" %}
+{% elif not register_object.period %}
+  {% if week %}
+    {% period_to_time_start week register_object.raw_period_from_on_day as time_start %}
+    {% period_to_time_end week register_object.raw_period_to_on_day as time_end %}
+  {% else %}
+    {% period_to_time_start register_object.date_start register_object.period_from as time_start %}
+    {% period_to_time_end register_object.date_end register_object.period_to as time_end %}
+  {% endif %}
+
+  {% if now_dt > time_end %}
+    {% include "alsijil/partials/lesson_status_icon.html" with text=_("Missing data") icon="warning" color="red" %}
+  {% elif now_dt > time_start and now_dt < time_end %}
+    {% include "alsijil/partials/lesson_status_icon.html" with text=_("Pending") icon="more_horiz" color="orange" %}
+  {% else %}
+    {% include "alsijil/partials/lesson_status_icon.html" with text=_("Event") icon="event" color="purple" %}
+  {% endif %}
+{% else %}
+  {% period_to_time_start week register_object.period as time_start %}
+  {% period_to_time_end week register_object.period as time_end %}
+
+  {% if substitution.cancelled or register_object.get_substitution.cancelled %}
+    {% include "alsijil/partials/lesson_status_icon.html" with text=_("Lesson cancelled") icon="cancel" color="red" %}
+  {% elif now_dt > time_end %}
+    {% include "alsijil/partials/lesson_status_icon.html" with text=_("Missing data") icon="warning" color="red" %}
+  {% elif now_dt > time_start and now_dt < time_end %}
+    {% include "alsijil/partials/lesson_status_icon.html" with text=_("Pending") icon="more_horiz" color="orange" %}
+  {% elif substitution or register_object.get_substitution %}
+    {% include "alsijil/partials/lesson_status_icon.html" with text=_("Substitution") icon="update" color="orange" %}
+  {% endif %}
+{% endif %}
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html
index 52f55e9723c3b9650bcd09f63725467a75f8993d..046b3ffbdacbbb5f18232668363fae195457faa1 100644
--- a/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/lesson_status_icon.html
@@ -1,31 +1,14 @@
-{% load i18n week_helpers %}
-
-{% now_datetime as now_dt %}
-
-{% if has_documentation or register_object.has_documentation %}
-  <i class="material-icons green{% firstof color_suffix "-text"%} tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Data complete" %}" title="{% trans "Data complete" %}">check_circle</i>
-{% elif not register_object.period %}
-  {% period_to_time_start week register_object.raw_period_from_on_day as time_start %}
-  {% period_to_time_end week register_object.raw_period_to_on_day as time_end %}
-
-  {% if now_dt > time_end %}
-    <i class="material-icons red{% firstof color_suffix "-text"%} tooltipped {{ css_class }}"  data-position="bottom" data-tooltip="{% trans "Missing data" %}" title="{% trans "Missing data" %}">history</i>
-  {% elif now_dt > time_start and now_dt < time_end %}
-    <i class="material-icons orange{% firstof color_suffix "-text"%} tooltipped {{ css_class }}"  data-position="bottom" data-tooltip="{% trans "Pending" %}" title="{% trans "Pending" %}">more_horiz</i>
-  {% else %}
-    <i class="material-icons purple{% firstof color_suffix "-text"%} tooltipped {{ css_class }}" data-position="bottom" data-tooltip="{% trans "Event" %}" title="{% trans "Event" %}">event</i>
-  {% endif %}
+{% if chip %}
+  <span class="{% if chip %}chip{% endif %} {{ color }} white-text {{ css_class }}">
+    <i class="material-icons left">
+      {{ icon }}
+    </i>
+    {{ text }}
+  </span>
 {% else %}
-  {% period_to_time_start week register_object.period as time_start %}
-  {% period_to_time_end week register_object.period as time_end %}
-
-  {% if substitution.cancelled or register_object.get_substitution.cancelled %}
-    <i class="material-icons red{% firstof color_suffix "-text"%} tooltipped {{ css_class }}"  data-position="bottom" data-tooltip="{% trans "Lesson cancelled" %}" title="{% trans "Lesson cancelled" %}">cancel</i>
-  {% elif now_dt > time_end %}
-    <i class="material-icons red{% firstof color_suffix "-text"%} tooltipped {{ css_class }}"  data-position="bottom" data-tooltip="{% trans "Missing data" %}" title="{% trans "Missing data" %}">history</i>
-  {% elif now_dt > time_start and now_dt < time_end %}
-    <i class="material-icons orange{% firstof color_suffix "-text"%} tooltipped {{ css_class }}"  data-position="bottom" data-tooltip="{% trans "Pending" %}" title="{% trans "Pending" %}">more_horiz</i>
-  {% elif substitution or register_object.get_substitution %}
-    <i class="material-icons orange{% firstof color_suffix "-text"%} tooltipped {{ css_class }}"  data-position="bottom" data-tooltip="{% trans "Substitution" %}" title="{% trans "Substitution" %}">update</i>
-  {% endif %}
+  <i class="material-icons {{ color }}{% firstof color_suffix "-text" %} tooltipped {{ css_class }}"
+     data-position="bottom"
+     data-tooltip="{{ text }}" title="{{ text }}">
+    {{ icon }}
+  </i>
 {% endif %}
diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html b/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html
index 404705dfbc3fe7cb4d6cfde5561ed2f3fb82de13..efa5bc3a89d72c75fbf5f3d1c9de5426c668270f 100644
--- a/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html
+++ b/aleksis/apps/alsijil/templates/alsijil/partials/persons_with_stats.html
@@ -11,7 +11,8 @@
   <tr class="hide-on-med-and-down">
     <th rowspan="2">{% trans "Name" %}</th>
     <th rowspan="2">{% trans "Primary group" %}</th>
-    <th colspan="{{ excuse_types.count|add:3 }}">{% trans "Absences" %}</th>
+    <th colspan="{{ excuse_types.count|add:4 }}">{% trans "Absences" %}</th>
+    <th colspan="{{ excuse_types_not_absent.count }}">{% trans "Uncounted Absences" %}</th>
     <th rowspan="2">{% trans "Tardiness" %}</th>
     {% if extra_marks %}
       <th colspan="{{ extra_marks.count }}">{% trans "Extra marks" %}</th>
@@ -22,6 +23,7 @@
     <th class="truncate">{% trans "Name" %}</th>
     <th class="truncate">{% trans "Primary group" %}</th>
     <th class="truncate chip-height">{% trans "Absences" %}</th>
+    <th class="chip-height">{% trans "Sum (e)" %}</th>
     <th class="chip-height">{% trans "(e)" %}</th>
     {% for excuse_type in excuse_types %}
       <th class="chip-height">
@@ -29,6 +31,11 @@
       </th>
     {% endfor %}
     <th class="chip-height">{% trans "(u)" %}</th>
+    {% for excuse_type in excuse_types_not_absent %}
+      <th class="chip-height">
+        ({{ excuse_type.short_name }})
+      </th>
+    {% endfor %}
     <th class="truncate chip-height">{% trans "Tardiness" %}</th>
     {% for extra_mark in extra_marks %}
       <th class="chip-height">
@@ -39,6 +46,7 @@
   </tr>
   <tr class="hide-on-med-and-down">
     <th>{% trans "Sum" %}</th>
+    <th>{% trans "Sum (e)" %}</th>
     <th>{% trans "(e)" %}</th>
     {% for excuse_type in excuse_types %}
       <th>
@@ -46,6 +54,11 @@
       </th>
     {% endfor %}
     <th>{% trans "(u)" %}</th>
+    {% for excuse_type in excuse_types_not_absent %}
+      <th>
+        ({{ excuse_type.short_name }})
+      </th>
+    {% endfor %}
     {% for extra_mark in extra_marks %}
       <th>
         {{ extra_mark.short_name }}
@@ -73,6 +86,11 @@
         {{ person.excused }}
         </span>
       </td>
+      <td>
+        <span class="chip grey white-text" title="{% trans "Regular excused" %}">
+          {{ person.excused_without_excuse_type }}
+        </span>
+      </td>
       {% for excuse_type in excuse_types %}
         <td>
           <span class="chip grey white-text" title="{{ excuse_type.name }}">
@@ -85,6 +103,13 @@
         {{ person.unexcused }}
         </span>
       </td>
+      {% for excuse_type in excuse_types_not_absent %}
+        <td>
+          <span class="chip grey white-text" title="{{ excuse_type.name }}">
+            {{ person|get_dict:excuse_type.count_label }}
+          </span>
+        </td>
+      {% endfor %}
       <td>
         <span class="chip orange white-text" title="{% trans "Tardiness" %}">
           {% firstof person.tardiness|to_time|time:"H\h i\m"  "–" %}
diff --git a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
index 1f8b6132fa0dee3033c7ea466e872e2ffd61fa64..ab63dc7a7c9b44f9808d8c4af5460439ee7cdb8d 100644
--- a/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
+++ b/aleksis/apps/alsijil/templates/alsijil/print/full_register.html
@@ -97,6 +97,18 @@
     </ul>
   {% endif %}
 
+  {% if excuse_types_not_absent %}
+    <h5>{% trans "Custom excuse types (not counted as absent)" %}</h5>
+
+    <ul class="collection">
+      {% for excuse_type in excuse_types_not_absent %}
+        <li class="collection-item">
+          <strong>({{ excuse_type.short_name }})</strong> {{ excuse_type.name }}
+        </li>
+      {% endfor %}
+    </ul>
+  {% endif %}
+
   {% if extra_marks %}
     <h5>{% trans "Available extra marks" %}</h5>
 
@@ -123,11 +135,15 @@
       <th>{% trans 'Sex' %}</th>
       <th>{% trans 'Date of birth' %}</th>
       <th>{% trans '(a)' %}</th>
+      <th>{% trans "Sum (e)" %}</th>
       <th>{% trans "(e)" %}</th>
       {% for excuse_type in excuse_types %}
         <th>({{ excuse_type.short_name }})</th>
       {% endfor %}
       <th>{% trans '(u)' %}</th>
+      {% for excuse_type in excuse_types_not_absent %}
+        <th>({{ excuse_type.short_name }})</th>
+      {% endfor %}
       <th>{% trans '(b)' %}</th>
       {% for extra_mark in extra_marks %}
         <th>{{ extra_mark.short_name }}</th>
@@ -145,11 +161,15 @@
         <td>{{ person.date_of_birth }}</td>
         <td>{{ person.absences_count }}</td>
         <td>{{ person.excused }}</td>
+        <td>{{ person.excused_without_excuse_type }}</td>
         {% for excuse_type in excuse_types %}
           <td>{{ person|get_dict:excuse_type.count_label }}</td>
         {% endfor %}
         <td>{{ person.unexcused }}</td>
-        <td>{{ person.tardiness }}'/{{ person.tardiness_count }} &times;</td>
+        {% for excuse_type in excuse_types_not_absent %}
+          <td>{{ person|get_dict:excuse_type.count_label }}</td>
+        {% endfor %}
+        <td>{{ person.tardiness }}'/{{ person.tardiness_count }}&times;</td>
         {% for extra_mark in extra_marks %}
           <td>{{ person|get_dict:extra_mark.count_label }}</td>
         {% endfor %}
@@ -263,43 +283,63 @@
       </tr>
     </table>
 
-    <h5>{% trans 'Absences and tardiness' %}</h5>
-    <table>
-      <tr>
-        <th colspan="2">{% trans 'Absences' %}</th>
-        <td>{{ person.absences_count }}</td>
-      </tr>
-      <tr>
-        <td rowspan="{{ excuse_types.count|add:2 }}" style="width: 16mm;"
-            class="rotate small-print">{% trans "thereof" %}</td>
-        <th>{% trans 'Excused' %}</th>
-        <td>{{ person.excused }}</td>
-      </tr>
-      {% for excuse_type in excuse_types %}
-        <th>{{ excuse_type.name }}</th>
-        <td>{{ person|get_dict:excuse_type.count_label }}</td>
-      {% endfor %}
-      <tr>
-        <th>{% trans 'Unexcused' %}</th>
-        <td>{{ person.unexcused }}</td>
-      </tr>
-      <tr>
-        <th colspan="2">{% trans 'Tardiness' %}</th>
-        <td>{{ person.tardiness }}'/{{ person.tardiness_count }} &times;</td>
-      </tr>
-    </table>
-
-    {% if extra_marks %}
-      <h5>{% trans 'Extra marks' %}</h5>
-      <table>
-        {% for extra_mark in extra_marks %}
+    <div class="row">
+      <div class="col s6">
+        <h5>{% trans 'Absences and tardiness' %}</h5>
+        <table>
           <tr>
-            <th>{{ extra_mark.name }}</th>
-            <td>{{ person|get_dict:extra_mark.count_label }}</td>
+            <th colspan="3">{% trans 'Absences' %}</th>
+            <td>{{ person.absences_count }}</td>
           </tr>
-        {% endfor %}
-      </table>
-    {% endif %}
+          <tr>
+            <td rowspan="{{ excuse_types.count|add:3 }}" style="width: 16mm;"
+                class="rotate small-print">{% trans "thereof" %}</td>
+            <th colspan="2">{% trans 'Excused' %}</th>
+            <td>{{ person.excused }}</td>
+          </tr>
+          <tr>
+            <td rowspan="{{ excuse_types.count|add:1 }}" style="width: 16mm;"
+                class="rotate small-print">{% trans "thereof" %}</td>
+            <th>{% trans "Without excuse type" %}</th>
+            <td>{{ person.excused_without_excuse_type }}</td>
+          </tr>
+          {% for excuse_type in excuse_types %}
+            <tr>
+              <th>{{ excuse_type.name }}</th>
+              <td>{{ person|get_dict:excuse_type.count_label }}</td>
+            </tr>
+          {% endfor %}
+          <tr>
+            <th colspan="2">{% trans 'Unexcused' %}</th>
+            <td>{{ person.unexcused }}</td>
+          </tr>
+          {% for excuse_type in excuse_types_not_absent %}
+            <tr>
+              <th colspan="3">{{ excuse_type.name }}</th>
+              <td>{{ person|get_dict:excuse_type.count_label }}</td>
+            </tr>
+          {% endfor %}
+          <tr>
+            <th colspan="3">{% trans 'Tardiness' %}</th>
+            <td>{{ person.tardiness }}'/{{ person.tardiness_count }}&times;</td>
+          </tr>
+        </table>
+      </div>
+
+      <div class="col s6">
+        {% if extra_marks %}
+        <h5>{% trans 'Extra marks' %}</h5>
+        <table>
+          {% for extra_mark in extra_marks %}
+            <tr>
+              <th>{{ extra_mark.name }}</th>
+              <td>{{ person|get_dict:extra_mark.count_label }}</td>
+            </tr>
+          {% endfor %}
+        </table>
+      {% endif %}
+      </div>
+    </div>
 
     <h5>{% trans 'Relevant personal notes' %}</h5>
     <table class="small-print">
diff --git a/aleksis/apps/alsijil/urls.py b/aleksis/apps/alsijil/urls.py
index 91fbb68bc428a3ff2f63686a59dc7135bf9c3223..f7551eb8eb53e4bd21b639eb8b67d0a69daf0ced 100644
--- a/aleksis/apps/alsijil/urls.py
+++ b/aleksis/apps/alsijil/urls.py
@@ -16,12 +16,21 @@ urlpatterns = [
         {"model": "extra_lesson"},
         name="extra_lesson",
     ),
-    path("event/<int:id_>/", views.register_object, {"model": "event"}, name="event",),
+    path(
+        "event/<int:id_>/",
+        views.register_object,
+        {"model": "event"},
+        name="event",
+    ),
     path("week/", views.week_view, name="week_view"),
     path("week/<int:year>/<int:week>/", views.week_view, name="week_view_by_week"),
     path("week/year/cw/", views.week_view, name="week_view_placeholders"),
     path("week/<str:type_>/<int:id_>/", views.week_view, name="week_view"),
-    path("week/year/cw/<str:type_>/<int:id_>/", views.week_view, name="week_view_placeholders",),
+    path(
+        "week/year/cw/<str:type_>/<int:id_>/",
+        views.week_view,
+        name="week_view_placeholders",
+    ),
     path(
         "week/<int:year>/<int:week>/<str:type_>/<int:id_>/",
         views.week_view,
@@ -40,17 +49,31 @@ urlpatterns = [
     ),
     path("absence/new/<int:id_>/", views.register_absence, name="register_absence"),
     path("extra_marks/", views.ExtraMarkListView.as_view(), name="extra_marks"),
-    path("extra_marks/create/", views.ExtraMarkCreateView.as_view(), name="create_extra_mark",),
-    path("extra_marks/<int:pk>/edit/", views.ExtraMarkEditView.as_view(), name="edit_extra_mark",),
+    path(
+        "extra_marks/create/",
+        views.ExtraMarkCreateView.as_view(),
+        name="create_extra_mark",
+    ),
+    path(
+        "extra_marks/<int:pk>/edit/",
+        views.ExtraMarkEditView.as_view(),
+        name="edit_extra_mark",
+    ),
     path(
         "extra_marks/<int:pk>/delete/",
         views.ExtraMarkDeleteView.as_view(),
         name="delete_extra_mark",
     ),
     path("excuse_types/", views.ExcuseTypeListView.as_view(), name="excuse_types"),
-    path("excuse_types/create/", views.ExcuseTypeCreateView.as_view(), name="create_excuse_type",),
     path(
-        "excuse_types/<int:pk>/edit/", views.ExcuseTypeEditView.as_view(), name="edit_excuse_type",
+        "excuse_types/create/",
+        views.ExcuseTypeCreateView.as_view(),
+        name="create_excuse_type",
+    ),
+    path(
+        "excuse_types/<int:pk>/edit/",
+        views.ExcuseTypeEditView.as_view(),
+        name="edit_excuse_type",
     ),
     path(
         "excuse_types/<int:pk>/delete/",
@@ -59,7 +82,11 @@ urlpatterns = [
     ),
     path("group_roles/", views.GroupRoleListView.as_view(), name="group_roles"),
     path("group_roles/create/", views.GroupRoleCreateView.as_view(), name="create_group_role"),
-    path("group_roles/<int:pk>/edit/", views.GroupRoleEditView.as_view(), name="edit_group_role",),
+    path(
+        "group_roles/<int:pk>/edit/",
+        views.GroupRoleEditView.as_view(),
+        name="edit_group_role",
+    ),
     path(
         "group_roles/<int:pk>/delete/",
         views.GroupRoleDeleteView.as_view(),
diff --git a/aleksis/apps/alsijil/util/alsijil_helpers.py b/aleksis/apps/alsijil/util/alsijil_helpers.py
index 95c49a0b5517d77d02d989999a8480e3621fbd97..640431a902c147d6322d485ba666fdb244635155 100644
--- a/aleksis/apps/alsijil/util/alsijil_helpers.py
+++ b/aleksis/apps/alsijil/util/alsijil_helpers.py
@@ -285,8 +285,8 @@ def _generate_dicts_for_events_and_extra_lessons(
             continue
 
         if isinstance(register_object, ExtraLesson):
-            day = date_format(register_object.day)
-            day_sort = register_object.day
+            day = date_format(register_object.date)
+            day_sort = register_object.date
             period = f"{register_object.period.period}."
             period_sort = register_object.period.period
         else:
diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py
index 48520bb72fe53d7f02ead00d943ab03d672f0d29..17b6e2dee3b7e0a1d28fea2986ba6a4b8d11571e 100644
--- a/aleksis/apps/alsijil/views.py
+++ b/aleksis/apps/alsijil/views.py
@@ -3,6 +3,7 @@ from copy import deepcopy
 from datetime import date, datetime, timedelta
 from typing import Any, Dict, Optional
 
+from django.apps import apps
 from django.core.exceptions import PermissionDenied
 from django.db.models import Count, Exists, FilteredRelation, OuterRef, Prefetch, Q, Sum
 from django.db.models.expressions import Case, When
@@ -107,7 +108,10 @@ def register_object(
     if not all((year, week, id_)):
         if register_object and model == "lesson":
             return redirect(
-                "lesson_period", wanted_week.year, wanted_week.week, register_object.pk,
+                "lesson_period",
+                wanted_week.year,
+                wanted_week.week,
+                register_object.pk,
             )
         elif not register_object:
             raise Http404(
@@ -183,6 +187,11 @@ def register_object(
     )
 
     if not blocked_because_holidays:
+        groups = register_object.get_groups().all()
+        if groups:
+            first_group = groups.first()
+            context["first_group"] = first_group
+
         # Group roles
         show_group_roles = request.user.person.preferences[
             "alsijil__group_roles_in_lesson_view"
@@ -190,14 +199,30 @@ def register_object(
             "alsijil.view_assigned_grouproles_for_register_object_rule", register_object
         )
         if show_group_roles:
-            groups = register_object.get_groups().all()
             group_roles = GroupRole.objects.with_assignments(date_of_lesson, groups)
             context["group_roles"] = group_roles
 
+        with_seating_plan = (
+            apps.is_installed("aleksis.apps.stoelindeling")
+            and groups
+            and request.user.has_perm("stoelindeling.view_seatingplan_for_group_rule", first_group)
+        )
+        context["with_seating_plan"] = with_seating_plan
+
+        if with_seating_plan:
+            seating_plan = register_object.seating_plan
+            context["seating_plan"] = register_object.seating_plan
+            if seating_plan and seating_plan.group != first_group:
+                context["seating_plan_parent"] = True
+
         # Create or get lesson documentation object; can be empty when first opening lesson
         lesson_documentation = register_object.get_or_create_lesson_documentation(wanted_week)
+        context["has_documentation"] = bool(lesson_documentation.topic)
+
         lesson_documentation_form = LessonDocumentationForm(
-            request.POST or None, instance=lesson_documentation, prefix="lesson_documentation",
+            request.POST or None,
+            instance=lesson_documentation,
+            prefix="lesson_documentation",
         )
 
         # Prefetch object permissions for all related groups of the register object
@@ -283,11 +308,13 @@ def register_object(
 
         back_url = request.GET.get("back", "")
         back_url_is_safe = url_has_allowed_host_and_scheme(
-            url=back_url, allowed_hosts={request.get_host()}, require_https=request.is_secure(),
+            url=back_url,
+            allowed_hosts={request.get_host()},
+            require_https=request.is_secure(),
         )
         if back_url_is_safe:
             context["back_to_week_url"] = back_url
-        else:
+        elif register_object.get_groups().all():
             context["back_to_week_url"] = reverse(
                 "week_view_by_week",
                 args=[
@@ -422,7 +449,7 @@ def week_view(
 
     if lesson_periods_pk or events_pk or extra_lessons_pk:
         # Aggregate all personal notes for this group and week
-        persons_qs = Person.objects.filter(is_active=True)
+        persons_qs = Person.objects.all()
 
         if not request.user.has_perm("alsijil.view_week_personalnote_rule", instance):
             persons_qs = persons_qs.filter(pk=request.user.person.pk)
@@ -476,7 +503,8 @@ def week_view(
 
         persons_qs = persons_qs.annotate(
             absences_count=Count(
-                "filtered_personal_notes", filter=Q(filtered_personal_notes__absent=True),
+                "filtered_personal_notes",
+                filter=Q(filtered_personal_notes__absent=True),
             ),
             unexcused_count=Count(
                 "filtered_personal_notes",
@@ -486,7 +514,8 @@ def week_view(
             ),
             tardiness_sum=Sum("filtered_personal_notes__late"),
             tardiness_count=Count(
-                "filtered_personal_notes", filter=Q(filtered_personal_notes__late__gt=0),
+                "filtered_personal_notes",
+                filter=Q(filtered_personal_notes__late__gt=0),
             ),
         )
 
@@ -638,7 +667,10 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
                 )
             )
 
-    weeks = CalendarWeek.weeks_within(group.school_term.date_start, group.school_term.date_end,)
+    weeks = CalendarWeek.weeks_within(
+        group.school_term.date_start,
+        group.school_term.date_end,
+    )
 
     for lesson_period in lesson_periods:
         for week in weeks:
@@ -681,7 +713,8 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
 
     context["school_term"] = group.school_term
     context["persons"] = prefetched_persons
-    context["excuse_types"] = ExcuseType.objects.all()
+    context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True)
+    context["excuse_types_not_absent"] = ExcuseType.objects.filter(count_as_absent=False)
     context["extra_marks"] = ExtraMark.objects.all()
     context["group"] = group
     context["weeks"] = weeks
@@ -737,12 +770,15 @@ def my_students(request: HttpRequest) -> HttpResponse:
         new_groups.append((group, persons_for_group))
 
     context["groups"] = new_groups
-    context["excuse_types"] = ExcuseType.objects.all()
+    context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True)
+    context["excuse_types_not_absent"] = ExcuseType.objects.filter(count_as_absent=False)
     context["extra_marks"] = ExtraMark.objects.all()
     return render(request, "alsijil/class_register/persons.html", context)
 
 
-@permission_required("alsijil.view_my_groups_rule",)
+@permission_required(
+    "alsijil.view_my_groups_rule",
+)
 def my_groups(request: HttpRequest) -> HttpResponse:
     context = {}
     context["groups"] = request.user.person.get_owner_groups_with_lessons().annotate(
@@ -761,7 +797,8 @@ class StudentsList(PermissionRequiredMixin, DetailView):
         context["group"] = self.object
         context["persons"] = self.object.generate_person_list_with_class_register_statistics()
         context["extra_marks"] = ExtraMark.objects.all()
-        context["excuse_types"] = ExcuseType.objects.all()
+        context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True)
+        context["excuse_types_not_absent"] = ExcuseType.objects.filter(count_as_absent=False)
         return context
 
 
@@ -854,7 +891,11 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp
             ),
         )
         .order_by(
-            "-school_term_start", "-order_year", "-order_week", "-order_weekday", "order_period",
+            "-school_term_start",
+            "-order_year",
+            "-order_week",
+            "-order_weekday",
+            "order_period",
         )
         .annotate_date_range()
         .annotate_subject()
@@ -874,7 +915,8 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp
         note.set_object_permission_checker(checker)
         personal_notes_list.append(note)
     context["personal_notes"] = personal_notes_list
-    context["excuse_types"] = ExcuseType.objects.all()
+    context["excuse_types"] = ExcuseType.objects.filter(count_as_absent=True)
+    context["excuse_types_not_absent"] = ExcuseType.objects.filter(count_as_absent=False)
 
     form = PersonOverviewForm(request, request.POST or None, queryset=allowed_personal_notes)
     if request.method == "POST" and request.user.has_perm(
@@ -908,12 +950,19 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp
                 continue
 
             stat.update(
-                personal_notes.filter(absent=True).aggregate(absences_count=Count("absent"))
+                personal_notes.filter(absent=True)
+                .exclude(excuse_type__count_as_absent=False)
+                .aggregate(absences_count=Count("absent"))
+            )
+            stat.update(
+                personal_notes.filter(absent=True, excused=True)
+                .exclude(excuse_type__count_as_absent=False)
+                .aggregate(excused=Count("absent"))
             )
             stat.update(
-                personal_notes.filter(
-                    absent=True, excused=True, excuse_type__isnull=True
-                ).aggregate(excused=Count("absent"))
+                personal_notes.filter(absent=True, excused=True, excuse_type__isnull=True)
+                .exclude(excuse_type__count_as_absent=False)
+                .aggregate(excused_no_excuse_type=Count("absent"))
             )
             stat.update(
                 personal_notes.filter(absent=True, excused=False).aggregate(
@@ -940,7 +989,6 @@ def overview_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResp
             stats.append((school_term, stat))
         context["stats"] = stats
 
-    context["excuse_types"] = excuse_types
     context["extra_marks"] = extra_marks
 
     # Build filter with own form and logic as django-filter can't work with different models
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..51285967a7d9722c5bdee4f6a81c154a56aa0846
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,19 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/_static/assign_group_role.png b/docs/_static/assign_group_role.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac77c11efecdfa5a76ff6e19811ecfb5343a0bfc
Binary files /dev/null and b/docs/_static/assign_group_role.png differ
diff --git a/docs/_static/create_excuse_type.png b/docs/_static/create_excuse_type.png
new file mode 100644
index 0000000000000000000000000000000000000000..f7a3e8be3e250b602984a7809838131fa22b1299
Binary files /dev/null and b/docs/_static/create_excuse_type.png differ
diff --git a/docs/_static/create_extra_mark.png b/docs/_static/create_extra_mark.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce0a37ae9edddf1877fb807d8bfcbb6c6c358200
Binary files /dev/null and b/docs/_static/create_extra_mark.png differ
diff --git a/docs/_static/edit_group_role.png b/docs/_static/edit_group_role.png
new file mode 100644
index 0000000000000000000000000000000000000000..f63c77fb1a7b09100b9253ff74776155249e7d46
Binary files /dev/null and b/docs/_static/edit_group_role.png differ
diff --git a/docs/_static/excuse_types.png b/docs/_static/excuse_types.png
new file mode 100644
index 0000000000000000000000000000000000000000..08180e8fc4d50c24c0be07bc2cd39bc80b8e344c
Binary files /dev/null and b/docs/_static/excuse_types.png differ
diff --git a/docs/_static/extra_marks.png b/docs/_static/extra_marks.png
new file mode 100644
index 0000000000000000000000000000000000000000..8696b594b122968a490448adcad4edfd75c2a6ab
Binary files /dev/null and b/docs/_static/extra_marks.png differ
diff --git a/docs/_static/group_roles.png b/docs/_static/group_roles.png
new file mode 100644
index 0000000000000000000000000000000000000000..2181f711cf31458cf82bc28e21961c01f9b44380
Binary files /dev/null and b/docs/_static/group_roles.png differ
diff --git a/docs/_static/lesson_documentation.png b/docs/_static/lesson_documentation.png
new file mode 100644
index 0000000000000000000000000000000000000000..e4904c0a5db7db39270a62ade9ccf6c06deb04f3
Binary files /dev/null and b/docs/_static/lesson_documentation.png differ
diff --git a/docs/_static/lesson_personal_notes.png b/docs/_static/lesson_personal_notes.png
new file mode 100644
index 0000000000000000000000000000000000000000..1ac6bd861cb86630624d910b6011cb884fd34333
Binary files /dev/null and b/docs/_static/lesson_personal_notes.png differ
diff --git a/docs/_static/lesson_version_history.png b/docs/_static/lesson_version_history.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c21de59eb712128f1ddcf3c82dd60cbf4a539b7
Binary files /dev/null and b/docs/_static/lesson_version_history.png differ
diff --git a/docs/_static/my_groups.png b/docs/_static/my_groups.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ab0b6b007222d23d79ccf475f4a157e2e35dba7
Binary files /dev/null and b/docs/_static/my_groups.png differ
diff --git a/docs/_static/my_students.png b/docs/_static/my_students.png
new file mode 100644
index 0000000000000000000000000000000000000000..7473831c7f8d577f0576a022e7ce14de442b9c4a
Binary files /dev/null and b/docs/_static/my_students.png differ
diff --git a/docs/_static/overview_lessons.png b/docs/_static/overview_lessons.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4a48c5c03b29c33321cd4104144fd3d8e96b0df
Binary files /dev/null and b/docs/_static/overview_lessons.png differ
diff --git a/docs/_static/overview_person.png b/docs/_static/overview_person.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca351866c3451610baf74536e9827f66919cc4a7
Binary files /dev/null and b/docs/_static/overview_person.png differ
diff --git a/docs/_static/register_absence.png b/docs/_static/register_absence.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7e886066911d1c51681df9645c023e9ff4336b6
Binary files /dev/null and b/docs/_static/register_absence.png differ
diff --git a/docs/_static/register_absence_confirm.png b/docs/_static/register_absence_confirm.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0085121364c2ab5a2dc5dc0b908fc1b06285fca
Binary files /dev/null and b/docs/_static/register_absence_confirm.png differ
diff --git a/docs/_static/students_list.png b/docs/_static/students_list.png
new file mode 100644
index 0000000000000000000000000000000000000000..737deca414eff7a2f686b8e844c20e62a2406a43
Binary files /dev/null and b/docs/_static/students_list.png differ
diff --git a/docs/_static/week_view.png b/docs/_static/week_view.png
new file mode 100644
index 0000000000000000000000000000000000000000..59cee6ed16bb8ed8a12e6ba3225989613d4f0a18
Binary files /dev/null and b/docs/_static/week_view.png differ
diff --git a/docs/_static/week_view_personal_notes.png b/docs/_static/week_view_personal_notes.png
new file mode 100644
index 0000000000000000000000000000000000000000..564472ffca8fcc422692396dddbccc32c9b7ec85
Binary files /dev/null and b/docs/_static/week_view_personal_notes.png differ
diff --git a/docs/admin/00_index.rst b/docs/admin/00_index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c5786831bae68eab1102891f1b03126ec1d4957c
--- /dev/null
+++ b/docs/admin/00_index.rst
@@ -0,0 +1,7 @@
+Setting up a digital class register with AlekSIS-App-Alsijil
+============================================================
+
+.. toctree::
+   :glob:
+
+   *
diff --git a/docs/admin/30_configure.rst b/docs/admin/30_configure.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e208afe91c18526b59f2505ef611090c430eff6f
--- /dev/null
+++ b/docs/admin/30_configure.rst
@@ -0,0 +1,52 @@
+Defining base data
+==================
+
+With sufficient authorisation, two additional menu items appear in the class register menu.
+
+Excuse types
+------------
+
+Additional types of excuse for an absence can be created here.
+This can be useful if you only want to count certain absences.
+For example, if a student is busy at a school event and misses lessons,
+this may not be counted as a normal absence.
+
+.. image:: ../_static/excuse_types.png
+  :width: 100%
+  :alt: List with defined excuse types
+
+.. image:: ../_static/create_excuse_type.png
+  :width: 100%
+  :alt: Form for creating new excuse types
+
+Extra marks
+-----------
+
+Some remarks are repeated over and over again, such as 'Forgot homework'.
+In order not to have to write this again and again in the remark field,
+additional marks can be set, which then only have to be clicked on in the class register.
+
+.. image:: ../_static/extra_marks.png
+  :width: 100%
+  :alt: List with defined extra marks
+
+.. image:: ../_static/create_extra_mark.png
+  :width: 100%
+  :alt: Form for creating new extra marks
+
+Group roles
+-----------
+
+To track special roles in groups in the class register, group roles
+like class representatives or ventilation services can be defined here.
+
+.. image:: ../_static/group_roles.png
+  :width: 100%
+  :alt: Overview about group roles
+
+.. image:: ../_static/edit_group_role.png
+  :width: 100%
+  :alt: Form for managing a group role
+
+Group roles can be managed via menu entry "Manage group roles" located in
+the submenu "Class register".
diff --git a/docs/admin/40_preferences.rst b/docs/admin/40_preferences.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b6e5ccf08856bea311776d34c4abe239f0679d81
--- /dev/null
+++ b/docs/admin/40_preferences.rst
@@ -0,0 +1,29 @@
+System-wide settings for the digital class register
+===================================================
+
+The behaviour of the digital class register  can be customised
+under `Admin → Configuration → Class Register`. The section contains the
+following preferences:
+
+* **Block adding personal notes for cancelled lessons**: If this option is
+  activated, teachers will not be able to add personal notes for cancelled
+  lessons.
+* **Allow users to view their own personal notes:** With this option, the school management
+  can control whether students should be able to view their own personal notes.
+* **Allow primary group owners to register future absences for students in their groups**:
+  This allows owners of the student's primary group (e. g. the class)
+  to register future absences like doctor's appointments or family celebrations.
+* **Allow original teachers to edit their lessons although they are substituted:**
+  In the case of substitute teaching, absent teachers can be given write-in privileges for the lesson.
+* **Carry over data from first lesson period to the following lesson periods in lessons over multiple periods:**
+  For double (or even more adjacent) lessons, the lesson data from the first lesson period
+  can be automatically carried over to the following lessons.
+* **Carry over personal notes to all following lesson periods on the same day:**
+  For double (or more adjacent) lessons, the personal notes from the first lesson period
+  can be automatically carried over to the following lessons.
+* **Allow teachers to open lesson periods on the same day and not just at the beginning of the period:**
+  Teachers can open lessons earlier on the same day and not just at the beginning of the lesson.
+* **Allow teachers to add data for lessons in holidays:**
+  It is possible to allow entering content for lessons during the holidays.
+* **Allow group owners to assign group roles to the parents of the group's members:**
+  With this being activated, group roles like parent representatives can be managed by the class teacher.
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1074475351acac1216bd056058d546996fd6fea
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,207 @@
+# -*- coding: utf-8 -*-
+#
+# Configuration file for the Sphinx documentation builder.
+#
+# This file does only contain a selection of the most common options. For a
+# full list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
+
+# -- Path setup --------------------------------------------------------------
+
+import os
+import sys
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import django
+
+sys.path.insert(0, os.path.abspath(".."))
+os.environ["DJANGO_SETTINGS_MODULE"] = "aleksis.core.settings"
+os.environ["LOCAL_SETTINGS_FILE"] = os.path.abspath(os.path.join("..", "local.cfg"))
+django.setup()
+
+# -- Project information -----------------------------------------------------
+
+project = "AlekSIS-App-Alsijil"
+copyright = "2019-2022 The AlekSIS team"
+author = "The AlekSIS Team"
+
+# The short X.Y version
+version = "2.0"
+# The full version, including alpha/beta/rc tags
+release = "2.0.2.dev0"
+
+
+# -- General configuration ---------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    "sphinx.ext.autodoc",
+    "sphinxcontrib_django",
+    "sphinx_autodoc_typehints",
+    "sphinx.ext.intersphinx",
+    "sphinx.ext.viewcode",
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ["_templates"]
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = ".rst"
+
+# The master toctree document.
+master_doc = "index"
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = None
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = "sphinx_material"
+
+# html_favicon = "../aleksis/core/static/img/aleksis-icon.png"
+# html_logo = "../aleksis/core/static/img/aleksis-banner.svg"
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#
+html_theme_options = {
+    "repo_url": f"https://edugit.org/AlekSIS/official/{project}",
+    "repo_name": "EduGit",
+    "repo_type": "gitlab",
+    "theme_color": "#0d5eaf",
+    "color_primary": "#0d5eaf",
+    "color_accent": "#0d5eaf",
+    "globaltoc_depth": 2,
+    "globaltoc_collapse": False,
+}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ["_static"]
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# The default sidebars (for documents that don't match any pattern) are
+# defined by theme itself.  Builtin themes are using these templates by
+# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
+# 'searchbox.html']``.
+#
+html_sidebars = {
+    "**": ["logo-text.html", "globaltoc.html", "localtoc.html", "searchbox.html"]
+}
+
+
+# -- Options for HTMLHelp output ---------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = f"{project}doc"
+
+
+# -- Options for LaTeX output ------------------------------------------------
+
+latex_elements = {
+    # The paper size ('letterpaper' or 'a4paper').
+    #
+    # 'papersize': 'letterpaper',
+    # The font size ('10pt', '11pt' or '12pt').
+    #
+    # 'pointsize': '10pt',
+    # Additional stuff for the LaTeX preamble.
+    #
+    # 'preamble': '',
+    # Latex figure (float) alignment
+    #
+    # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+    (master_doc, f"{project}.tex", f"{project} Documentation", author, "manual"),
+]
+
+
+# -- Options for manual page output ------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [(master_doc, "aleksis", f"{project} Documentation", [author], 1)]
+
+
+# -- Options for Texinfo output ----------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+    (
+        master_doc,
+        project,
+        f"{project} Documentation",
+        author,
+        project,
+        "One line description of project.",
+        "Miscellaneous",
+    ),
+]
+
+
+# -- Options for Epub output -------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = project
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#
+# epub_identifier = ''
+
+# A unique identification for the text.
+#
+# epub_uid = ''
+
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ["search.html"]
+
+
+# -- Extension configuration -------------------------------------------------
+
+# -- Options for intersphinx extension ---------------------------------------
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {
+    "https://docs.python.org/": None,
+    "https://docs.djangoproject.com/en/stable": "https://docs.djangoproject.com/en/stable/_objects",
+}
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..be6e93c3f650f9ea1faa2d7e0ed39e3889f05fec
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,24 @@
+.. AlekSIS documentation master file, created by
+   sphinx-quickstart on Thu Aug 15 10:49:03 2019.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to AlekSIS-App-Alsijil's documentation!
+===============================================
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Contents:
+
+   user/00_index
+   admin/00_index
+   dev/00_index
+   ref/00_index
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000000000000000000000000000000000000..27f573b87af11e2cbbd9f54eb1ee285a58550146
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+	echo.
+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+	echo.installed, then set the SPHINXBUILD environment variable to point
+	echo.to the full path of the 'sphinx-build' executable. Alternatively you
+	echo.may add the Sphinx directory to PATH.
+	echo.
+	echo.If you don't have Sphinx installed, grab it from
+	echo.http://sphinx-doc.org/
+	exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd
diff --git a/docs/user/00_index.rst b/docs/user/00_index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..afa9d42c569858cb04a7513a0a7922a24b26467f
--- /dev/null
+++ b/docs/user/00_index.rst
@@ -0,0 +1,7 @@
+Digital class register
+======================
+
+.. toctree::
+   :glob:
+
+   *
diff --git a/docs/user/10_basic.rst b/docs/user/10_basic.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d51047195b6ed2e8e2684621975e9552c1020974
--- /dev/null
+++ b/docs/user/10_basic.rst
@@ -0,0 +1,37 @@
+Concept of Alsijil and overview about functionality
+===================================================
+
+AlekSIS provides a privacy-compliant online class register solution.
+It is not simply the digital equivalent of a paper class book, although elements are adopted
+for easier orientation and smoother transition for teachers. For example, there is a weekly
+view of all lessons and a list of all the students in the class. Lesson content,
+notes about the student and also remarks about the learning group can be entered.
+
+However, the application uses the possibilities and therefore the advantages of a digital application.
+The student lists do not have to be filled in by the class teacher,
+but are provided automatically by the system. The timetable is also already stored.
+
+In addition, statistical evaluation, like counting absences, is done
+automatically.
+
+In an overview, Alsijil currently provides the following functionality:
+
+- Direct link to the lesson currently taking place
+- Overview with all lessons of one week
+    + Navigation between lessons
+    + Filtering according to learning groups/courses and teachers
+- List of learning groups
+    + List of students with current statistics (absences, lateness, etc.)
+    + printing of the group-specific class register
+- "My overview" for pupils with an overview of "personal notes" such as omissions, lateness, remarks
+- "My overview" for teachers with a list of their own lessons over the last four weeks and the following filtering options:
+    + Specifying the period
+    + Restriction to lessons with or without entry for lesson content
+    + Restriction to certain groups
+    + Restriction to certain lesson contents
+- Only for teachers: Listing of students from their own lessons with totalled absences and lateness as well as other remarks
+- Only for teachers with special privileges: Listing of all lessons of a specific class in preparation for printing the class register
+- For administrators only: Definition of types of excuses, e.g. for absences due to school-related reasons
+- For administrators only: Determination of types of remark, e.g. HA for homework forgotten
+- Only for administrators: Assignment of special group roles, e.g. for the evaluation of class book entries or access to the print function
+- Only for administrators: Creating group roles
diff --git a/docs/user/15_concepts.rst b/docs/user/15_concepts.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6fbcb74809358195239021f5b2230971f2e1536b
--- /dev/null
+++ b/docs/user/15_concepts.rst
@@ -0,0 +1,34 @@
+Basic data concepts
+===================
+
+Timetable data
+--------------
+
+The class register uses the data from the timetable app. This means that timetables with
+all current changes such as substitutions, events and exams can be found directly in the class book.
+
+Even basic settings such as lesson times, holidays and public holidays do not have to be
+entered separately in the class book, as they are managed centrally.
+
+Lesson documentations
+---------------------
+
+Three input fields are provided for the lesson content:
+
+1. **Lesson topic:** The content of the lesson is to be noted here, if necessary with information on the material used.
+2. **Homework:** In this field, the teacher can enter the homework for the next lesson.
+3. **Group note:** Here, there is space for notes that concern the whole learning group, e.g. instructions, dates, or similar.
+
+Personal notes
+--------------
+
+Under the tab 'Personal Notes', you will find a student list of the group. The following entries can be made there:
+
+1. **Absent:**
+2. **Tardiness in minutes**
+3. **Excused**
+4. **Excuse type:** Several types can be set up for an excuse for absence, e.g. in case a student was absent due to a school event.
+5. **Extra marks:** This item is also configurable. A selection field for missing homework or similar would be possible here.
+6. **Remarks:**
+
+With the appropriate configuration, students can view all personal notes concerning themselves.
diff --git a/docs/user/20_overview.rst b/docs/user/20_overview.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6a44ca2372c6a19b4acd19ab1bccddcc82b7af62
--- /dev/null
+++ b/docs/user/20_overview.rst
@@ -0,0 +1,86 @@
+Overviews about lessons and students
+====================================
+
+Week overview
+-------------
+
+In the weekly overview, all lessons of the week for the respective user are displayed in a weekly schedule.
+Clicking on a lesson takes you to the data for that lesson.
+Above the schedule, you can navigate to the previous or following week.
+It is also possible to filter the schedule according to certain groups or teachers.
+
+.. image:: ../_static/week_view.png
+  :width: 100%
+  :alt: Week view
+
+.. image:: ../_static/week_view_personal_notes.png
+  :width: 100%
+  :alt: Personal notes tab in week view
+
+My overview
+-----------
+
+Personal overview for students
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This menu item provides the student with an overview of the personal notes
+such as tardiness, absences and remarks that teachers have entered in the class register.
+This enables them to quickly check whether excuses still need to be submitted,
+and to verify what notes have been made about them.
+
+.. image:: ../_static/overview_person.png
+  :width: 100%
+  :alt: Overview for students
+
+Personal overview for teachers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For teachers, this view shows their own lessons for the last four weeks.
+A filter can be used to adjust the list with regard to period,
+missing entries, certain groups or certain lesson contents.
+A corresponding symbol in each line immediately shows
+whether entries are still missing for the lesson in question.
+Individual lessons can be called up from the list to add or change entries.
+
+.. image:: ../_static/overview_lessons.png
+  :width: 100%
+  :alt: Overview of lessons for teachers
+
+My groups
+---------
+
+This menu item is only available for teachers.
+
+With this quick access to your own learning groups,
+you can on the one hand access the relevant student lists
+and the weekly view of the lessons of this group,
+and on the other hand you can print the course-specific class book.
+
+.. image:: ../_static/my_groups.png
+  :width: 100%
+  :alt: List with all groups and their students
+
+My students
+-----------
+
+With this menu item, teachers receive a list of all students from their lessons.
+From each entry, you can switch to a detailed view to add specific data.
+
+.. image:: ../_static/my_students.png
+  :width: 100%
+  :alt: List with all students of a teacher
+
+You are also able to create custom excuse types via the menu entry "Excuse
+types". These custom types are also shown in the statistical overview. The
+custom excuse types are also shown in the legend under the students overview
+table.
+
+
+All lessons
+-----------
+
+For the head teacher or the coordinators of certain grades,
+this menu item gives the possibility to see all lessons of a learning group in a list.
+By means of a filter, the list can be specified to certain entries.
+This makes it possible to call up all lessons with missing entries and
+to send a request for completion of the data to the teachers concerned via a button.
diff --git a/docs/user/21_lesson.rst b/docs/user/21_lesson.rst
new file mode 100644
index 0000000000000000000000000000000000000000..6db6108bcf19442c42ea63e067846c58b2292186
--- /dev/null
+++ b/docs/user/21_lesson.rst
@@ -0,0 +1,74 @@
+Viewing and managing lessons
+============================
+
+The lesson documentation can be called up in different ways:
+
+1. **Via 'Current lesson'**: During the current lesson, this is the quickest way to access the lesson documentation.
+2. **Via 'Weekly overview'**: This menu item shows all lessons of the current week. Individual lessons can be clicked on to access the lesson documentation.
+3. **'My Overview'**: This menu item shows teachers a list of all hours worked in the last weeks. Individual lessons can be called up directly.
+
+The lesson documentation consists of four main parts accessible via tabs.
+The data can be entered, changed and saved via the relevant forms.
+In addition, navigation to the previous or next lesson is possible.
+
+
+Tab 'Lesson Documentation'
+--------------------------
+
+The lesson documentation is a strictly non-personal information about the contents
+of the lesson. It contains the topic, describing what contents were taught, and an
+optional homework, describing what tasks students got for the next lesson.
+
+Everything entered here should be considered public knowledge.
+
+.. warning::
+   Never add any personal information to the lesson documentation.
+
+.. image:: ../_static/lesson_documentation.png
+  :width: 100%
+  :alt: Lesson documentation in lesson overview
+
+If enabled in the preferences, lesson documentation is carried over to adjacent
+lessons. So if one subject is held in a double or triple lesson, only one needs
+to be filled in.
+
+Tab 'Personal Notes'
+--------------------
+
+Personal notes are specific to single students, and contain information about
+absences, tardiness, any extra marks defined in the system, and a free text comment.
+
+This information can never be viewed by other students. It is visible to any
+teacher in the class by default, and might also be visible to the concerned
+student.
+
+.. image:: ../_static/lesson_personal_notes.png
+  :width: 100%
+  :alt: Personal notes in lesson overview
+
+Behaviour of absences and tardiness
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When a student is marked as absent, this information is carried over to all future
+lessons on the same day, meaning that for any teacher holding lessons in the class
+after the one that marked them as absent will automatically see them as absent.
+
+Likewise, if a student returns and is marked as not absent, this is carried over
+to all future lessons.
+
+Tab 'Previous lesson'
+---------------------
+
+This tab shows information about the previous lesson in the same group and subject
+for reference.
+
+Tab 'More'
+----------
+
+This tab contains several special items not mentioned before:
+
+* **Changes**: Alsijil tracks all changes made to class register entries. This list shows a log of all these changes.
+
+.. image:: ../_static/lesson_version_history.png
+  :width: 100%
+  :alt: Change history of the lesson
diff --git a/docs/user/25_group_roles.rst b/docs/user/25_group_roles.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ad388845fb19d7d0f0a0cc7f22957c3023023753
--- /dev/null
+++ b/docs/user/25_group_roles.rst
@@ -0,0 +1,9 @@
+Assigning group roles
+=====================
+
+This menu item enables the assignment of a previously defined group role to a specific person,
+e.g. for ventilation services or class representatives.
+
+.. image:: ../_static/assign_group_role.png
+  :width: 100%
+  :alt: Form for assigning a group role to a person
diff --git a/docs/user/40_export.rst b/docs/user/40_export.rst
new file mode 100644
index 0000000000000000000000000000000000000000..cdb2f2f23e550a5f27f6c4f6b339aa1dd74d78a5
--- /dev/null
+++ b/docs/user/40_export.rst
@@ -0,0 +1,14 @@
+(Archive) printout
+==================
+
+Via the menu item *My Groups*, extensive documentation can be generated for each group.
+This class register will be generated as a printable PDF file.
+
+It contains a list of the lessons taught staggered according to timetable periods,
+a collection of all the students' personal notes as well as all lesson contents.
+
+An alternative path to printing a class register is via the weekly view.
+There, the relevant group can be selected via the filter to print the class book.
+
+.. note::
+   This mechanism can be used for archival purposes required by law.
diff --git a/poetry.lock b/poetry.lock
deleted file mode 100644
index 2a54bb6b4af524188e43f5fa8a85de73c51f4351..0000000000000000000000000000000000000000
--- a/poetry.lock
+++ /dev/null
@@ -1,3900 +0,0 @@
-[[package]]
-name = "alabaster"
-version = "0.7.12"
-description = "A configurable sidebar-enabled Sphinx theme"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "aleksis-app-chronos"
-version = "2.0rc3+20210927103610.5167a6f0"
-description = "AlekSIS (School Information System) — App Χρόνος (digital timetables)"
-category = "main"
-optional = false
-python-versions = ">=3.9,<4.0"
-
-[package.dependencies]
-aleksis-core = ">=2.0rc,<3.0"
-calendarweek = ">=0.5.0,<0.6.0"
-
-[package.source]
-type = "legacy"
-url = "https://edugit.org/api/v4/projects/461/packages/pypi/simple"
-reference = "gitlab"
-
-[[package]]
-name = "aleksis-builddeps"
-version = "4"
-description = "AlekSIS (School Information System) — Build/Dev dependencies for apps"
-category = "dev"
-optional = false
-python-versions = ">=3.6,<4.0"
-
-[package.dependencies]
-black = ">=19.10b0,<20.0"
-curlylint = ">=0.12.0,<0.13.0"
-django-stubs = ">=1.1,<2.0"
-flake8 = ">=3.7.9,<4.0.0"
-flake8-bandit = ">=2.1.2,<3.0.0"
-flake8-black = ">=0.2.0,<0.3.0"
-flake8-builtins = ">=1.4.1,<2.0.0"
-flake8-django = ">=1.0.0,<2.0.0"
-flake8-docstrings = ">=1.5.0,<2.0.0"
-flake8-fixme = ">=1.1.1,<2.0.0"
-flake8-isort = ">=4.0.0,<5.0.0"
-flake8-mypy = ">=17.8.0,<18.0.0"
-flake8-rst-docstrings = ">=0.2.0,<0.3.0"
-freezegun = ">=1.1.0,<2.0.0"
-isort = ">=5.0.0,<6.0.0"
-pytest = ">=6.0,<7.0"
-pytest-cov = ">=2.8.1,<3.0.0"
-pytest-django = ">=4.1,<5.0"
-pytest-django-testing-postgresql = ">=0.1,<0.2"
-pytest-sugar = ">=0.9.2,<0.10.0"
-safety = ">=1.8.5,<2.0.0"
-selenium = ">=3.141.0,<4.0.0"
-sphinx = ">=3.0,<4.0"
-sphinx-autodoc-typehints = ">=1.7,<2.0"
-sphinx_materialdesign_theme = ">=0.1.11,<0.2.0"
-sphinxcontrib-django = ">=0.5.0,<0.6.0"
-
-[package.source]
-type = "legacy"
-url = "https://edugit.org/api/v4/projects/461/packages/pypi/simple"
-reference = "gitlab"
-
-[[package]]
-name = "aleksis-core"
-version = "2.1.dev0+20211028143753.e5b47dd7"
-description = "AlekSIS (School Information System) — Core"
-category = "main"
-optional = false
-python-versions = ">=3.9,<4.0"
-
-[package.dependencies]
-bs4 = ">=0.0.1,<0.0.2"
-calendarweek = ">=0.5.0,<0.6.0"
-Celery = {version = ">=5.0.0,<6.0.0", extras = ["django", "redis"]}
-celery-haystack-ng = ">=0.20,<0.21"
-celery-progress = ">=0.1.0,<0.2.0"
-colour = ">=0.1.5,<0.2.0"
-Django = ">=3.2.5,<4.0.0"
-django-allauth = ">=0.45.0,<0.46.0"
-django-any-js = ">=1.1,<2.0"
-django-bleach = ">=0.8.0,<0.9.0"
-django-cachalot = ">=2.3.2,<3.0.0"
-django-cache-memoize = ">=0.1.6,<0.2.0"
-django-celery-beat = ">=2.2.0,<3.0.0"
-django-celery-email = ">=3.0.0,<4.0.0"
-django-celery-results = ">=2.0.1,<3.0.0"
-django-ckeditor = ">=6.0.0,<7.0.0"
-django-cleanup = ">=5.1.0,<6.0.0"
-django-colorfield = ">=0.4.0,<0.5.0"
-django-dbbackup = ">=3.3.0,<4.0.0"
-django-debug-toolbar = ">=3.2,<4.0"
-django-dynamic-preferences = ">=1.11,<2.0"
-django-extensions = ">=3.1.1,<4.0.0"
-django-favicon-plus-reloaded = ">=1.1.2,<2.0.0"
-django-filter = ">=2.2.0,<3.0.0"
-django-guardian = ">=2.2.0,<3.0.0"
-django-haystack = "3.0"
-django-health-check = ">=3.12.1,<4.0.0"
-django-impersonate = ">=1.4,<2.0"
-django-ipware = ">=4.0,<5.0"
-django-js-reverse = ">=0.9.1,<0.10.0"
-django-jsonstore = ">=0.5.0,<0.6.0"
-django-maintenance-mode = ">=0.16.0,<0.17.0"
-django-material = ">=1.6.0,<2.0.0"
-django-menu-generator-ng = ">=1.2.3,<2.0.0"
-django-model-utils = ">=4.0.0,<5.0.0"
-django-oauth-toolkit = ">=1.5.0,<2.0.0"
-django-phonenumber-field = {version = ">=5.2,<6.0", extras = ["phonenumbers"]}
-django-polymorphic = ">=3.0.0,<4.0.0"
-django-prometheus = ">=2.1.0,<3.0.0"
-django-redis = ">=5.0.0,<6.0.0"
-django-reversion = ">=4.0.0,<5.0.0"
-django-sass-processor = "1.0"
-django_select2 = ">=7.1,<8.0"
-django-tables2 = ">=2.1,<3.0"
-django-templated-email = ">=3.0.0,<4.0.0"
-django-titofisto = ">=0.1.0,<0.2.0"
-django-two-factor-auth = {version = ">=1.12.1,<2.0.0", extras = ["call", "phonenumbers", "sms", "yubikey"]}
-django-uwsgi-ng = ">=1.1.0,<2.0.0"
-django_widget_tweaks = ">=1.4.5,<2.0.0"
-django-yarnpkg = ">=6.0,<7.0"
-djangorestframework = ">=3.12.4,<4.0.0"
-dynaconf = {version = ">=3.1,<4.0", extras = ["ini", "toml", "yaml"]}
-haystack-redis = ">=0.0.1,<0.0.2"
-html2text = ">=2020.0.0,<2021.0.0"
-ipython = ">=7.20.0,<8.0.0"
-libsass = ">=0.21.0,<0.22.0"
-license-expression = ">=1.2,<2.0"
-psutil = ">=5.7.0,<6.0.0"
-psycopg2 = ">=2.8,<3.0"
-python-gnupg = ">=0.4.7,<0.5.0"
-rules = ">=2.2,<3.0"
-spdx-license-list = ">=0.5.0,<0.6.0"
-Whoosh = ">=2.7.4,<3.0.0"
-
-[package.extras]
-s3 = ["boto3 (>=1.17.33,<2.0.0)", "django-storages (>=1.11.1,<2.0.0)"]
-ldap = ["django-auth-ldap (>=2.2,<3.0)"]
-
-[package.source]
-type = "legacy"
-url = "https://edugit.org/api/v4/projects/461/packages/pypi/simple"
-reference = "gitlab"
-
-[[package]]
-name = "amqp"
-version = "5.0.6"
-description = "Low-level AMQP client for Python (fork of amqplib)."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-vine = "5.0.0"
-
-[[package]]
-name = "appdirs"
-version = "1.4.4"
-description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "appnope"
-version = "0.1.2"
-description = "Disable App Nap on macOS >= 10.9"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "asgiref"
-version = "3.4.1"
-description = "ASGI specs, helper code, and adapters"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.extras]
-tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"]
-
-[[package]]
-name = "asn1crypto"
-version = "1.4.0"
-description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "atomicwrites"
-version = "1.4.0"
-description = "Atomic file writes."
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "attrs"
-version = "21.2.0"
-description = "Classes Without Boilerplate"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[package.extras]
-dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"]
-docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
-tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
-tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
-
-[[package]]
-name = "babel"
-version = "2.9.1"
-description = "Internationalization utilities"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.dependencies]
-pytz = ">=2015.7"
-
-[[package]]
-name = "backcall"
-version = "0.2.0"
-description = "Specifications for callback functions passed in to an API"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "bandit"
-version = "1.7.0"
-description = "Security oriented static analyser for python code."
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""}
-GitPython = ">=1.0.1"
-PyYAML = ">=5.3.1"
-six = ">=1.10.0"
-stevedore = ">=1.20.0"
-
-[[package]]
-name = "beautifulsoup4"
-version = "4.10.0"
-description = "Screen-scraping library"
-category = "main"
-optional = false
-python-versions = ">3.0.0"
-
-[package.dependencies]
-soupsieve = ">1.2"
-
-[package.extras]
-html5lib = ["html5lib"]
-lxml = ["lxml"]
-
-[[package]]
-name = "billiard"
-version = "3.6.4.0"
-description = "Python multiprocessing fork with improvements and bugfixes"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "black"
-version = "19.10b0"
-description = "The uncompromising code formatter."
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-appdirs = "*"
-attrs = ">=18.1.0"
-click = ">=6.5"
-pathspec = ">=0.6,<1"
-regex = "*"
-toml = ">=0.9.4"
-typed-ast = ">=1.4.0"
-
-[package.extras]
-d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
-
-[[package]]
-name = "bleach"
-version = "4.1.0"
-description = "An easy safelist-based HTML-sanitizing tool."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-packaging = "*"
-six = ">=1.9.0"
-webencodings = "*"
-
-[[package]]
-name = "boolean.py"
-version = "3.8"
-description = "Define boolean algebras, create and parse boolean expressions and create custom boolean DSL."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "bs4"
-version = "0.0.1"
-description = "Dummy package for Beautiful Soup"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-beautifulsoup4 = "*"
-
-[[package]]
-name = "calendarweek"
-version = "0.5.0"
-description = "Utilities for working with calendar weeks in Python and Django"
-category = "main"
-optional = false
-python-versions = ">=3.7,<4.0"
-
-[package.extras]
-django = ["Django (>=2.2,<4.0)"]
-
-[[package]]
-name = "celery"
-version = "5.1.2"
-description = "Distributed Task Queue."
-category = "main"
-optional = false
-python-versions = ">=3.6,"
-
-[package.dependencies]
-billiard = ">=3.6.4.0,<4.0"
-click = ">=7.0,<8.0"
-click-didyoumean = ">=0.0.3"
-click-plugins = ">=1.1.1"
-click-repl = ">=0.1.6"
-Django = {version = ">=1.11", optional = true, markers = "extra == \"django\""}
-kombu = ">=5.1.0,<6.0"
-pytz = ">0.0-dev"
-redis = {version = ">=3.2.0", optional = true, markers = "extra == \"redis\""}
-vine = ">=5.0.0,<6.0"
-
-[package.extras]
-arangodb = ["pyArango (>=1.3.2)"]
-auth = ["cryptography"]
-azureblockblob = ["azure-storage-blob (==12.6.0)"]
-brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"]
-cassandra = ["cassandra-driver (<3.21.0)"]
-consul = ["python-consul2"]
-cosmosdbsql = ["pydocumentdb (==2.3.2)"]
-couchbase = ["couchbase (>=3.0.0)"]
-couchdb = ["pycouchdb"]
-django = ["Django (>=1.11)"]
-dynamodb = ["boto3 (>=1.9.178)"]
-elasticsearch = ["elasticsearch"]
-eventlet = ["eventlet (>=0.26.1)"]
-gevent = ["gevent (>=1.0.0)"]
-librabbitmq = ["librabbitmq (>=1.5.0)"]
-memcache = ["pylibmc"]
-mongodb = ["pymongo[srv] (>=3.3.0)"]
-msgpack = ["msgpack"]
-pymemcache = ["python-memcached"]
-pyro = ["pyro4"]
-pytest = ["pytest-celery"]
-redis = ["redis (>=3.2.0)"]
-s3 = ["boto3 (>=1.9.125)"]
-slmq = ["softlayer-messaging (>=1.0.3)"]
-solar = ["ephem"]
-sqlalchemy = ["sqlalchemy"]
-sqs = ["boto3 (>=1.9.125)", "pycurl (==7.43.0.5)"]
-tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"]
-yaml = ["PyYAML (>=3.10)"]
-zookeeper = ["kazoo (>=1.3.1)"]
-zstd = ["zstandard"]
-
-[[package]]
-name = "celery-haystack-ng"
-version = "0.20.post2"
-description = "An app for integrating Celery with Haystack"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-celery = ">=4.0"
-django-appconf = ">=0.4.1"
-django-haystack = ">=2.0"
-
-[[package]]
-name = "celery-progress"
-version = "0.1.1"
-description = "Drop in, configurable, dependency-free progress bars for your Django/Celery applications."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.extras]
-rabbitmq = ["channels-rabbitmq"]
-redis = ["channels-redis"]
-websockets = ["channels"]
-
-[[package]]
-name = "certifi"
-version = "2021.10.8"
-description = "Python package for providing Mozilla's CA Bundle."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "cffi"
-version = "1.15.0"
-description = "Foreign Function Interface for Python calling C code."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-pycparser = "*"
-
-[[package]]
-name = "charset-normalizer"
-version = "2.0.7"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-category = "main"
-optional = false
-python-versions = ">=3.5.0"
-
-[package.extras]
-unicode_backport = ["unicodedata2"]
-
-[[package]]
-name = "click"
-version = "7.1.2"
-description = "Composable command line interface toolkit"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "click-didyoumean"
-version = "0.3.0"
-description = "Enables git-like *did-you-mean* feature in click"
-category = "main"
-optional = false
-python-versions = ">=3.6.2,<4.0.0"
-
-[package.dependencies]
-click = ">=7"
-
-[[package]]
-name = "click-plugins"
-version = "1.1.1"
-description = "An extension module for click to enable registering CLI commands via setuptools entry-points."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-click = ">=4.0"
-
-[package.extras]
-dev = ["pytest (>=3.6)", "pytest-cov", "wheel", "coveralls"]
-
-[[package]]
-name = "click-repl"
-version = "0.2.0"
-description = "REPL plugin for Click"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-click = "*"
-prompt-toolkit = "*"
-six = "*"
-
-[[package]]
-name = "colorama"
-version = "0.4.4"
-description = "Cross-platform colored terminal text."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "colour"
-version = "0.1.5"
-description = "converts and manipulates various color representation (HSL, RVB, web, X11, ...)"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.extras]
-test = ["nose"]
-
-[[package]]
-name = "configobj"
-version = "5.0.6"
-description = "Config file reading, writing and validation."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-six = "*"
-
-[[package]]
-name = "coverage"
-version = "6.0.2"
-description = "Code coverage measurement for Python"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.extras]
-toml = ["tomli"]
-
-[[package]]
-name = "cryptography"
-version = "35.0.0"
-description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-cffi = ">=1.12"
-
-[package.extras]
-docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
-docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"]
-pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
-sdist = ["setuptools_rust (>=0.11.4)"]
-ssh = ["bcrypt (>=3.1.5)"]
-test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
-
-[[package]]
-name = "curlylint"
-version = "0.12.2"
-description = "{{ 🎀}} Experimental HTML templates linting for Jinja, Nunjucks, Django templates, Twig, Liquid"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-attrs = ">=17.2.0"
-click = ">=6.5"
-parsy = "1.1.0"
-pathspec = ">=0.6,<1"
-toml = ">=0.9.4"
-
-[package.extras]
-dev = ["black (==19.10b0)", "flake8 (==3.8.4)", "mypy (==0.812)", "pytest (==6.2.2)", "coverage (==5.4)"]
-
-[[package]]
-name = "decorator"
-version = "5.1.0"
-description = "Decorators for Humans"
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "defusedxml"
-version = "0.7.1"
-description = "XML bomb protection for Python stdlib modules"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "deprecated"
-version = "1.2.13"
-description = "Python @deprecated decorator to deprecate old python classes, functions or methods."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.dependencies]
-wrapt = ">=1.10,<2"
-
-[package.extras]
-dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"]
-
-[[package]]
-name = "dj-database-url"
-version = "0.5.0"
-description = "Use Database URLs in your Django Application."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "django"
-version = "3.2.8"
-description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-asgiref = ">=3.3.2,<4"
-pytz = "*"
-sqlparse = ">=0.2.2"
-
-[package.extras]
-argon2 = ["argon2-cffi (>=19.1.0)"]
-bcrypt = ["bcrypt"]
-
-[[package]]
-name = "django-allauth"
-version = "0.45.0"
-description = "Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=2.0"
-pyjwt = {version = ">=1.7", extras = ["crypto"]}
-python3-openid = ">=3.0.8"
-requests = "*"
-requests-oauthlib = ">=0.3.0"
-
-[[package]]
-name = "django-any-js"
-version = "1.1"
-description = "Include JavaScript/CSS libraries with readable template tags"
-category = "main"
-optional = false
-python-versions = ">=3.7,<4.0"
-
-[package.dependencies]
-Django = ">=2.2,<4.0"
-
-[[package]]
-name = "django-appconf"
-version = "1.0.5"
-description = "A helper class for handling configuration defaults of packaged apps gracefully."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-django = "*"
-
-[[package]]
-name = "django-bleach"
-version = "0.8.0"
-description = "Easily use bleach with Django models and templates"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-bleach = ">=1.5.0"
-Django = ">=1.11"
-
-[[package]]
-name = "django-cachalot"
-version = "2.4.3"
-description = "Caches your Django ORM queries and automatically invalidates them."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=2.2,<3.3"
-
-[[package]]
-name = "django-cache-memoize"
-version = "0.1.10"
-description = "Django utility for a memoization decorator that uses the Django cache framework."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.extras]
-dev = ["flake8", "tox", "twine", "therapist", "black"]
-
-[[package]]
-name = "django-celery-beat"
-version = "2.2.1"
-description = "Database-backed Periodic Tasks."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-celery = ">=5.0,<6.0"
-Django = ">=2.2,<4.0"
-django-timezone-field = ">=4.1.0,<5.0"
-python-crontab = ">=2.3.4"
-
-[[package]]
-name = "django-celery-email"
-version = "3.0.0"
-description = "An async Django email backend using celery"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-celery = ">=4.0"
-django = ">=2.2"
-django-appconf = "*"
-
-[[package]]
-name = "django-celery-results"
-version = "2.2.0"
-description = "Celery result backends for Django."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-celery = ">=5.0,<6.0"
-
-[[package]]
-name = "django-ckeditor"
-version = "6.1.0"
-description = "Django admin CKEditor integration."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django-js-asset = ">=1.2.2"
-
-[[package]]
-name = "django-cleanup"
-version = "5.2.0"
-description = "Deletes old files."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "django-colorfield"
-version = "0.4.5"
-description = "simple color field for your models with a nice color-picker in the admin-interface."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "django-dbbackup"
-version = "3.3.0"
-description = "Management commands to help backup and restore a project database and media"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=1.5"
-pytz = "*"
-six = "*"
-
-[[package]]
-name = "django-debug-toolbar"
-version = "3.2.2"
-description = "A configurable set of panels that display various debug information about the current request/response."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-Django = ">=2.2"
-sqlparse = ">=0.2.0"
-
-[[package]]
-name = "django-dynamic-preferences"
-version = "1.11.0"
-description = "Dynamic global and instance settings for your django project"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django = ">=1.11"
-persisting-theory = ">=0.2.1"
-six = "*"
-
-[[package]]
-name = "django-extensions"
-version = "3.1.3"
-description = "Extensions for Django"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-Django = ">=2.2"
-
-[[package]]
-name = "django-favicon-plus-reloaded"
-version = "1.1.3"
-description = "simple Django app which allows you to upload a image and it renders a wide variety for html link tags to display the favicon"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django = "*"
-pillow = "*"
-
-[[package]]
-name = "django-filter"
-version = "2.4.0"
-description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-Django = ">=2.2"
-
-[[package]]
-name = "django-formtools"
-version = "2.3"
-description = "A set of high-level abstractions for Django forms"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-Django = ">=2.2"
-
-[[package]]
-name = "django-guardian"
-version = "2.4.0"
-description = "Implementation of per object permissions for Django."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-Django = ">=2.2"
-
-[[package]]
-name = "django-haystack"
-version = "3.0"
-description = "Pluggable search for Django."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=2.2"
-
-[[package]]
-name = "django-health-check"
-version = "3.16.4"
-description = "Run checks on services like databases, queue servers, celery processes, etc."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django = ">=2.2"
-
-[[package]]
-name = "django-impersonate"
-version = "1.7.3"
-description = "Django app to allow superusers to impersonate other users."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "django-ipware"
-version = "4.0.0"
-description = "A Django application to retrieve user's IP address"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
-
-[[package]]
-name = "django-js-asset"
-version = "1.2.2"
-description = "script tag with additional attributes for django.forms.Media"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "django-js-reverse"
-version = "0.9.1"
-description = "Javascript url handling for Django that doesn't hurt."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=1.5"
-
-[[package]]
-name = "django-jsonstore"
-version = "0.5.0"
-description = "Expose JSONField data as a virtual django model fields."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=1.11"
-six = "*"
-
-[[package]]
-name = "django-maintenance-mode"
-version = "0.16.1"
-description = "django-maintenance-mode shows a 503 error page when maintenance-mode is on."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "django-material"
-version = "1.9.0"
-description = "Material design for django forms and admin"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-six = "*"
-
-[[package]]
-name = "django-menu-generator-ng"
-version = "1.2.3"
-description = "A straightforward menu generator for Django"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "django-model-utils"
-version = "4.2.0"
-description = "Django model mixins and utilities"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=2.0.1"
-
-[[package]]
-name = "django-oauth-toolkit"
-version = "1.5.0"
-description = "OAuth2 Provider for Django"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django = ">=2.2"
-jwcrypto = ">=0.8.0"
-oauthlib = ">=3.1.0"
-requests = ">=2.13.0"
-six = "*"
-
-[[package]]
-name = "django-otp"
-version = "1.1.1"
-description = "A pluggable framework for adding two-factor authentication to Django using one-time passwords."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django = ">=2.2"
-
-[package.extras]
-qrcode = ["qrcode"]
-
-[[package]]
-name = "django-otp-yubikey"
-version = "1.0.0.post1"
-description = "A django-otp plugin that verifies YubiKey OTP tokens."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django-otp = ">=1.0.0"
-YubiOTP = ">=0.2.2"
-
-[[package]]
-name = "django-phonenumber-field"
-version = "5.2.0"
-description = "An international phone number field for django models."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-Django = ">=2.2"
-phonenumbers = {version = ">=7.0.2", optional = true, markers = "extra == \"phonenumbers\""}
-
-[package.extras]
-phonenumbers = ["phonenumbers (>=7.0.2)"]
-phonenumberslite = ["phonenumberslite (>=7.0.2)"]
-
-[[package]]
-name = "django-polymorphic"
-version = "3.0.0"
-description = "Seamless polymorphic inheritance for Django models"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=2.1"
-
-[[package]]
-name = "django-prometheus"
-version = "2.1.0"
-description = "Django middlewares to monitor your application with Prometheus.io."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-prometheus-client = ">=0.7"
-
-[[package]]
-name = "django-redis"
-version = "5.0.0"
-description = "Full featured redis cache backend for Django."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-Django = ">=2.2"
-redis = ">=3.0.0"
-
-[[package]]
-name = "django-render-block"
-version = "0.8.1"
-description = "Render a particular block from a template to a string."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-django = ">=2.2"
-
-[[package]]
-name = "django-reversion"
-version = "4.0.0"
-description = "An extension to the Django web framework that provides version control for model instances."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-django = ">=2.0"
-
-[[package]]
-name = "django-sass-processor"
-version = "1.0.0"
-description = "SASS processor to compile SCSS files into *.css, while rendering, or offline."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.extras]
-management_command = ["django-compressor (>=2.4)"]
-
-[[package]]
-name = "django-select2"
-version = "7.7.3"
-description = "Select2 option fields for Django"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django = ">=2.2"
-django-appconf = ">=0.6.0"
-
-[package.extras]
-test = ["pytest", "pytest-cov", "pytest-django", "selenium"]
-
-[[package]]
-name = "django-stubs"
-version = "1.9.0"
-description = "Mypy stubs for Django"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-django = "*"
-django-stubs-ext = ">=0.3.0"
-mypy = ">=0.910"
-toml = "*"
-types-pytz = "*"
-types-PyYAML = "*"
-typing-extensions = "*"
-
-[[package]]
-name = "django-stubs-ext"
-version = "0.3.1"
-description = "Monkey-patching and extensions for django-stubs"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-django = "*"
-typing-extensions = "*"
-
-[[package]]
-name = "django-tables2"
-version = "2.4.1"
-description = "Table/data-grid framework for Django"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=1.11"
-
-[package.extras]
-tablib = ["tablib"]
-
-[[package]]
-name = "django-templated-email"
-version = "3.0.0"
-description = "A Django oriented templated / transaction email abstraction"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django-render-block = ">=0.5"
-
-[[package]]
-name = "django-timezone-field"
-version = "4.2.1"
-description = "A Django app providing database and form fields for pytz timezone objects."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-django = ">=2.2"
-pytz = "*"
-
-[package.extras]
-rest_framework = ["djangorestframework (>=3.0.0)"]
-
-[[package]]
-name = "django-titofisto"
-version = "0.1.2.post1"
-description = "Django Time-Token File Storage"
-category = "main"
-optional = false
-python-versions = ">=3.9,<4.0"
-
-[package.dependencies]
-Django = ">2.2,<4.0"
-
-[[package]]
-name = "django-two-factor-auth"
-version = "1.13.1"
-description = "Complete Two-Factor Authentication for Django"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Django = ">=2.2"
-django-formtools = "*"
-django-otp = ">=0.8.0"
-django-otp-yubikey = {version = "*", optional = true, markers = "extra == \"yubikey\""}
-django-phonenumber-field = ">=1.1.0,<6"
-phonenumbers = {version = ">=7.0.9,<8.99", optional = true, markers = "extra == \"phonenumbers\""}
-qrcode = ">=4.0.0,<6.99"
-twilio = {version = ">=6.0", optional = true, markers = "extra == \"call\""}
-
-[package.extras]
-call = ["twilio (>=6.0)"]
-phonenumbers = ["phonenumbers (>=7.0.9,<8.99)"]
-phonenumberslite = ["phonenumberslite (>=7.0.9,<8.99)"]
-sms = ["twilio (>=6.0)"]
-yubikey = ["django-otp-yubikey"]
-
-[[package]]
-name = "django-uwsgi-ng"
-version = "1.1.2"
-description = "uWSGI stuff for Django projects"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.extras]
-uwsgi = ["uwsgi"]
-
-[[package]]
-name = "django-widget-tweaks"
-version = "1.4.9"
-description = "Tweak the form field rendering in templates, not in python-level form definitions."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "django-yarnpkg"
-version = "6.0.1"
-description = "Integrate django with yarnpkg"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django = "*"
-six = "*"
-
-[[package]]
-name = "djangorestframework"
-version = "3.12.4"
-description = "Web APIs for Django, made easy."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-django = ">=2.2"
-
-[[package]]
-name = "docutils"
-version = "0.16"
-description = "Docutils -- Python Documentation Utilities"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "dparse"
-version = "0.5.1"
-description = "A parser for Python dependency files"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-packaging = "*"
-pyyaml = "*"
-toml = "*"
-
-[package.extras]
-pipenv = ["pipenv"]
-
-[[package]]
-name = "dynaconf"
-version = "3.1.7"
-description = "The dynamic configurator for your Python Project"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-configobj = {version = "*", optional = true, markers = "extra == \"ini\""}
-"ruamel.yaml" = {version = "*", optional = true, markers = "extra == \"yaml\""}
-toml = {version = "*", optional = true, markers = "extra == \"toml\""}
-
-[package.extras]
-all = ["redis", "ruamel.yaml", "configobj", "hvac"]
-configobj = ["configobj"]
-ini = ["configobj"]
-redis = ["redis"]
-toml = ["toml"]
-vault = ["hvac"]
-yaml = ["ruamel.yaml"]
-
-[[package]]
-name = "flake8"
-version = "3.9.2"
-description = "the modular source code checker: pep8 pyflakes and co"
-category = "dev"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
-
-[package.dependencies]
-mccabe = ">=0.6.0,<0.7.0"
-pycodestyle = ">=2.7.0,<2.8.0"
-pyflakes = ">=2.3.0,<2.4.0"
-
-[[package]]
-name = "flake8-bandit"
-version = "2.1.2"
-description = "Automated security testing with bandit and flake8."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-bandit = "*"
-flake8 = "*"
-flake8-polyfill = "*"
-pycodestyle = "*"
-
-[[package]]
-name = "flake8-black"
-version = "0.2.3"
-description = "flake8 plugin to call black as a code style validator"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-black = "*"
-flake8 = ">=3.0.0"
-toml = "*"
-
-[[package]]
-name = "flake8-builtins"
-version = "1.5.3"
-description = "Check for python builtins being used as variables or parameters."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-flake8 = "*"
-
-[package.extras]
-test = ["coverage", "coveralls", "mock", "pytest", "pytest-cov"]
-
-[[package]]
-name = "flake8-django"
-version = "1.1.2"
-description = "Plugin to catch bad style specific to Django Projects."
-category = "dev"
-optional = false
-python-versions = ">=3.6,<4.0"
-
-[package.dependencies]
-flake8 = ">=3.8.4,<4.0.0"
-
-[[package]]
-name = "flake8-docstrings"
-version = "1.6.0"
-description = "Extension for flake8 which uses pydocstyle to check docstrings"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-flake8 = ">=3"
-pydocstyle = ">=2.1"
-
-[[package]]
-name = "flake8-fixme"
-version = "1.1.1"
-description = "Check for FIXME, TODO and other temporary developer notes. Plugin for flake8."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "flake8-isort"
-version = "4.1.1"
-description = "flake8 plugin that integrates isort ."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-flake8 = ">=3.2.1,<5"
-isort = ">=4.3.5,<6"
-testfixtures = ">=6.8.0,<7"
-
-[package.extras]
-test = ["pytest-cov"]
-
-[[package]]
-name = "flake8-mypy"
-version = "17.8.0"
-description = "A plugin for flake8 integrating mypy."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-attrs = "*"
-flake8 = ">=3.0.0"
-mypy = "*"
-
-[[package]]
-name = "flake8-polyfill"
-version = "1.0.2"
-description = "Polyfill package for Flake8 plugins"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-flake8 = "*"
-
-[[package]]
-name = "flake8-rst-docstrings"
-version = "0.2.3"
-description = "Python docstring reStructuredText (RST) validator"
-category = "dev"
-optional = false
-python-versions = ">=3.3"
-
-[package.dependencies]
-flake8 = ">=3.0.0"
-pygments = "*"
-restructuredtext-lint = "*"
-
-[[package]]
-name = "freezegun"
-version = "1.1.0"
-description = "Let your Python tests travel through time"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-python-dateutil = ">=2.7"
-
-[[package]]
-name = "gitdb"
-version = "4.0.9"
-description = "Git Object Database"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-smmap = ">=3.0.1,<6"
-
-[[package]]
-name = "gitpython"
-version = "3.1.24"
-description = "GitPython is a python library used to interact with Git repositories"
-category = "dev"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-gitdb = ">=4.0.1,<5"
-typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""}
-
-[[package]]
-name = "haystack-redis"
-version = "0.0.1"
-description = "Use redis as a persistence layer for Whoosh and Haystack"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-django-haystack = "*"
-redis = "*"
-whoosh = "*"
-
-[[package]]
-name = "html2text"
-version = "2020.1.16"
-description = "Turn HTML into equivalent Markdown-structured text."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "idna"
-version = "3.3"
-description = "Internationalized Domain Names in Applications (IDNA)"
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "imagesize"
-version = "1.2.0"
-description = "Getting image size from png/jpeg/jpeg2000/gif file"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "iniconfig"
-version = "1.1.1"
-description = "iniconfig: brain-dead simple config-ini parsing"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "ipython"
-version = "7.28.0"
-description = "IPython: Productive Interactive Computing"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-appnope = {version = "*", markers = "sys_platform == \"darwin\""}
-backcall = "*"
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-decorator = "*"
-jedi = ">=0.16"
-matplotlib-inline = "*"
-pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
-pickleshare = "*"
-prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0"
-pygments = "*"
-traitlets = ">=4.2"
-
-[package.extras]
-all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"]
-doc = ["Sphinx (>=1.3)"]
-kernel = ["ipykernel"]
-nbconvert = ["nbconvert"]
-nbformat = ["nbformat"]
-notebook = ["notebook", "ipywidgets"]
-parallel = ["ipyparallel"]
-qtconsole = ["qtconsole"]
-test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"]
-
-[[package]]
-name = "isort"
-version = "5.9.3"
-description = "A Python utility / library to sort Python imports."
-category = "dev"
-optional = false
-python-versions = ">=3.6.1,<4.0"
-
-[package.extras]
-pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
-requirements_deprecated_finder = ["pipreqs", "pip-api"]
-colors = ["colorama (>=0.4.3,<0.5.0)"]
-plugins = ["setuptools"]
-
-[[package]]
-name = "jedi"
-version = "0.18.0"
-description = "An autocompletion tool for Python that can be used for text editors."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-parso = ">=0.8.0,<0.9.0"
-
-[package.extras]
-qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
-testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"]
-
-[[package]]
-name = "jinja2"
-version = "3.0.2"
-description = "A very fast and expressive template engine."
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-MarkupSafe = ">=2.0"
-
-[package.extras]
-i18n = ["Babel (>=2.7)"]
-
-[[package]]
-name = "jwcrypto"
-version = "1.0"
-description = "Implementation of JOSE Web standards"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-cryptography = ">=2.3"
-deprecated = "*"
-
-[[package]]
-name = "kombu"
-version = "5.1.0"
-description = "Messaging library for Python."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-amqp = ">=5.0.6,<6.0.0"
-vine = "*"
-
-[package.extras]
-azureservicebus = ["azure-servicebus (>=7.0.0)"]
-azurestoragequeues = ["azure-storage-queue"]
-consul = ["python-consul (>=0.6.0)"]
-librabbitmq = ["librabbitmq (>=1.5.2)"]
-mongodb = ["pymongo (>=3.3.0)"]
-msgpack = ["msgpack"]
-pyro = ["pyro4"]
-qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"]
-redis = ["redis (>=3.3.11)"]
-slmq = ["softlayer-messaging (>=1.0.3)"]
-sqlalchemy = ["sqlalchemy"]
-sqs = ["boto3 (>=1.4.4)", "pycurl (==7.43.0.2)", "urllib3 (<1.26)"]
-yaml = ["PyYAML (>=3.10)"]
-zookeeper = ["kazoo (>=1.3.1)"]
-
-[[package]]
-name = "libsass"
-version = "0.21.0"
-description = "Sass for Python: A straightforward binding of libsass for Python."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-six = "*"
-
-[[package]]
-name = "license-expression"
-version = "1.2"
-description = "license-expression is small utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-"boolean.py" = ">=3.6,<4.0.0"
-
-[[package]]
-name = "markupsafe"
-version = "2.0.1"
-description = "Safely add untrusted strings to HTML/XML markup."
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "matplotlib-inline"
-version = "0.1.3"
-description = "Inline Matplotlib backend for Jupyter"
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-traitlets = "*"
-
-[[package]]
-name = "mccabe"
-version = "0.6.1"
-description = "McCabe checker, plugin for flake8"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "mypy"
-version = "0.910"
-description = "Optional static typing for Python"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-mypy-extensions = ">=0.4.3,<0.5.0"
-toml = "*"
-typing-extensions = ">=3.7.4"
-
-[package.extras]
-dmypy = ["psutil (>=4.0)"]
-python2 = ["typed-ast (>=1.4.0,<1.5.0)"]
-
-[[package]]
-name = "mypy-extensions"
-version = "0.4.3"
-description = "Experimental type system extensions for programs checked with the mypy typechecker."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "oauthlib"
-version = "3.1.1"
-description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.extras]
-rsa = ["cryptography (>=3.0.0,<4)"]
-signals = ["blinker (>=1.4.0)"]
-signedtoken = ["cryptography (>=3.0.0,<4)", "pyjwt (>=2.0.0,<3)"]
-
-[[package]]
-name = "packaging"
-version = "21.2"
-description = "Core utilities for Python packages"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-pyparsing = ">=2.0.2,<3"
-
-[[package]]
-name = "parso"
-version = "0.8.2"
-description = "A Python Parser"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.extras]
-qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
-testing = ["docopt", "pytest (<6.0.0)"]
-
-[[package]]
-name = "parsy"
-version = "1.1.0"
-description = "easy-to-use parser combinators, for parsing in pure Python"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pathspec"
-version = "0.9.0"
-description = "Utility library for gitignore style pattern matching of file paths."
-category = "dev"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
-
-[[package]]
-name = "pbr"
-version = "5.6.0"
-description = "Python Build Reasonableness"
-category = "dev"
-optional = false
-python-versions = ">=2.6"
-
-[[package]]
-name = "persisting-theory"
-version = "0.2.1"
-description = "Registries that can autodiscover values accross your project apps"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pexpect"
-version = "4.8.0"
-description = "Pexpect allows easy control of interactive console applications."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-ptyprocess = ">=0.5"
-
-[[package]]
-name = "pg8000"
-version = "1.22.0"
-description = "PostgreSQL interface library"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-scramp = ">=1.4.1"
-
-[[package]]
-name = "phonenumbers"
-version = "8.12.36"
-description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pickleshare"
-version = "0.7.5"
-description = "Tiny 'shelve'-like database with concurrency support"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pillow"
-version = "8.4.0"
-description = "Python Imaging Library (Fork)"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "pluggy"
-version = "1.0.0"
-description = "plugin and hook calling mechanisms for python"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-testing = ["pytest", "pytest-benchmark"]
-
-[[package]]
-name = "prometheus-client"
-version = "0.11.0"
-description = "Python client for the Prometheus monitoring system."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.extras]
-twisted = ["twisted"]
-
-[[package]]
-name = "prompt-toolkit"
-version = "3.0.21"
-description = "Library for building powerful interactive command lines in Python"
-category = "main"
-optional = false
-python-versions = ">=3.6.2"
-
-[package.dependencies]
-wcwidth = "*"
-
-[[package]]
-name = "psutil"
-version = "5.8.0"
-description = "Cross-platform lib for process and system monitoring in Python."
-category = "main"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.extras]
-test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"]
-
-[[package]]
-name = "psycopg2"
-version = "2.9.1"
-description = "psycopg2 - Python-PostgreSQL Database Adapter"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "ptyprocess"
-version = "0.7.0"
-description = "Run a subprocess in a pseudo terminal"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "py"
-version = "1.10.0"
-description = "library with cross-python path, ini-parsing, io, code, log facilities"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "pycodestyle"
-version = "2.7.0"
-description = "Python style guide checker"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "pycparser"
-version = "2.20"
-description = "C parser in Python"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "pycryptodome"
-version = "3.11.0"
-description = "Cryptographic library for Python"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "pydocstyle"
-version = "6.1.1"
-description = "Python docstring style checker"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-snowballstemmer = "*"
-
-[package.extras]
-toml = ["toml"]
-
-[[package]]
-name = "pyflakes"
-version = "2.3.1"
-description = "passive checker of Python programs"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "pygments"
-version = "2.10.0"
-description = "Pygments is a syntax highlighting package written in Python."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "pyjwt"
-version = "2.3.0"
-description = "JSON Web Token implementation in Python"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-cryptography = {version = ">=3.3.1", optional = true, markers = "extra == \"crypto\""}
-
-[package.extras]
-crypto = ["cryptography (>=3.3.1)"]
-dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"]
-docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
-tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"]
-
-[[package]]
-name = "pyparsing"
-version = "2.4.7"
-description = "Python parsing module"
-category = "main"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
-
-[[package]]
-name = "pytest"
-version = "6.2.5"
-description = "pytest: simple powerful testing with Python"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
-attrs = ">=19.2.0"
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-iniconfig = "*"
-packaging = "*"
-pluggy = ">=0.12,<2.0"
-py = ">=1.8.2"
-toml = "*"
-
-[package.extras]
-testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
-
-[[package]]
-name = "pytest-cov"
-version = "2.12.1"
-description = "Pytest plugin for measuring coverage."
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[package.dependencies]
-coverage = ">=5.2.1"
-pytest = ">=4.6"
-toml = "*"
-
-[package.extras]
-testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"]
-
-[[package]]
-name = "pytest-django"
-version = "4.4.0"
-description = "A Django plugin for pytest."
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-pytest = ">=5.4.0"
-
-[package.extras]
-docs = ["sphinx", "sphinx-rtd-theme"]
-testing = ["django", "django-configurations (>=2.0)"]
-
-[[package]]
-name = "pytest-django-testing-postgresql"
-version = "0.1.post0"
-description = "Use a temporary PostgreSQL database with pytest-django"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-dj-database-url = "*"
-"testing.postgresql" = "*"
-
-[[package]]
-name = "pytest-sugar"
-version = "0.9.4"
-description = "pytest-sugar is a plugin for pytest that changes the default look and feel of pytest (e.g. progressbar, show tests that fail instantly)."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-packaging = ">=14.1"
-pytest = ">=2.9"
-termcolor = ">=1.1.0"
-
-[[package]]
-name = "python-crontab"
-version = "2.6.0"
-description = "Python Crontab API"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-python-dateutil = "*"
-
-[package.extras]
-cron-description = ["cron-descriptor"]
-cron-schedule = ["croniter"]
-
-[[package]]
-name = "python-dateutil"
-version = "2.8.2"
-description = "Extensions to the standard Python datetime module"
-category = "main"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
-
-[package.dependencies]
-six = ">=1.5"
-
-[[package]]
-name = "python-gnupg"
-version = "0.4.7"
-description = "A wrapper for the Gnu Privacy Guard (GPG or GnuPG)"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "python3-openid"
-version = "3.2.0"
-description = "OpenID support for modern servers and consumers."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-defusedxml = "*"
-
-[package.extras]
-mysql = ["mysql-connector-python"]
-postgresql = ["psycopg2"]
-
-[[package]]
-name = "pytz"
-version = "2021.3"
-description = "World timezone definitions, modern and historical"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pyyaml"
-version = "6.0"
-description = "YAML parser and emitter for Python"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "qrcode"
-version = "6.1"
-description = "QR Code image generator"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
-six = "*"
-
-[package.extras]
-dev = ["tox", "pytest", "mock"]
-maintainer = ["zest.releaser"]
-pil = ["pillow"]
-test = ["pytest", "pytest-cov", "mock"]
-
-[[package]]
-name = "redis"
-version = "3.5.3"
-description = "Python client for Redis key-value store"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[package.extras]
-hiredis = ["hiredis (>=0.1.3)"]
-
-[[package]]
-name = "regex"
-version = "2021.10.23"
-description = "Alternative regular expression module, to replace re."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "requests"
-version = "2.26.0"
-description = "Python HTTP for Humans."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
-idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
-urllib3 = ">=1.21.1,<1.27"
-
-[package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
-use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
-
-[[package]]
-name = "requests-oauthlib"
-version = "1.3.0"
-description = "OAuthlib authentication support for Requests."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.dependencies]
-oauthlib = ">=3.0.0"
-requests = ">=2.0.0"
-
-[package.extras]
-rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
-
-[[package]]
-name = "restructuredtext-lint"
-version = "1.3.2"
-description = "reStructuredText linter"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-docutils = ">=0.11,<1.0"
-
-[[package]]
-name = "ruamel.yaml"
-version = "0.17.16"
-description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
-category = "main"
-optional = false
-python-versions = ">=3"
-
-[package.dependencies]
-"ruamel.yaml.clib" = {version = ">=0.1.2", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.10\""}
-
-[package.extras]
-docs = ["ryd"]
-jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
-
-[[package]]
-name = "ruamel.yaml.clib"
-version = "0.2.6"
-description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "rules"
-version = "2.2"
-description = "Awesome Django authorization, without the database"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "safety"
-version = "1.10.3"
-description = "Checks installed dependencies for known vulnerabilities."
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-Click = ">=6.0"
-dparse = ">=0.5.1"
-packaging = "*"
-requests = "*"
-
-[[package]]
-name = "scramp"
-version = "1.4.1"
-description = "An implementation of the SCRAM protocol."
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-asn1crypto = ">=1.4.0"
-
-[[package]]
-name = "selenium"
-version = "3.141.0"
-description = "Python bindings for Selenium"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-urllib3 = "*"
-
-[[package]]
-name = "six"
-version = "1.16.0"
-description = "Python 2 and 3 compatibility utilities"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
-
-[[package]]
-name = "smmap"
-version = "5.0.0"
-description = "A pure Python implementation of a sliding window memory map manager"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "snowballstemmer"
-version = "2.1.0"
-description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "soupsieve"
-version = "2.2.1"
-description = "A modern CSS selector implementation for Beautiful Soup."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "spdx-license-list"
-version = "0.5.2"
-description = "A simple tool/library for working with SPDX license definitions."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "sphinx"
-version = "3.5.4"
-description = "Python documentation generator"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-alabaster = ">=0.7,<0.8"
-babel = ">=1.3"
-colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""}
-docutils = ">=0.12,<0.17"
-imagesize = "*"
-Jinja2 = ">=2.3"
-packaging = "*"
-Pygments = ">=2.0"
-requests = ">=2.5.0"
-snowballstemmer = ">=1.1"
-sphinxcontrib-applehelp = "*"
-sphinxcontrib-devhelp = "*"
-sphinxcontrib-htmlhelp = "*"
-sphinxcontrib-jsmath = "*"
-sphinxcontrib-qthelp = "*"
-sphinxcontrib-serializinghtml = "*"
-
-[package.extras]
-docs = ["sphinxcontrib-websupport"]
-lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.800)", "docutils-stubs"]
-test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"]
-
-[[package]]
-name = "sphinx-autodoc-typehints"
-version = "1.12.0"
-description = "Type hints (PEP 484) support for the Sphinx autodoc extension"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-Sphinx = ">=3.0"
-
-[package.extras]
-test = ["pytest (>=3.1.0)", "typing-extensions (>=3.5)", "sphobjinv (>=2.0)", "Sphinx (>=3.2.0)", "dataclasses"]
-type_comments = ["typed-ast (>=1.4.0)"]
-
-[[package]]
-name = "sphinx-materialdesign-theme"
-version = "0.1.11"
-description = "Sphinx Material Design Theme"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "sphinxcontrib-applehelp"
-version = "1.0.2"
-description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
-test = ["pytest"]
-
-[[package]]
-name = "sphinxcontrib-devhelp"
-version = "1.0.2"
-description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
-test = ["pytest"]
-
-[[package]]
-name = "sphinxcontrib-django"
-version = "0.5.1"
-description = "Improve the Sphinx autodoc for Django classes."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "sphinxcontrib-htmlhelp"
-version = "2.0.0"
-description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
-test = ["pytest", "html5lib"]
-
-[[package]]
-name = "sphinxcontrib-jsmath"
-version = "1.0.1"
-description = "A sphinx extension which renders display math in HTML via JavaScript"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.extras]
-test = ["pytest", "flake8", "mypy"]
-
-[[package]]
-name = "sphinxcontrib-qthelp"
-version = "1.0.3"
-description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
-test = ["pytest"]
-
-[[package]]
-name = "sphinxcontrib-serializinghtml"
-version = "1.1.5"
-description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
-test = ["pytest"]
-
-[[package]]
-name = "sqlparse"
-version = "0.4.2"
-description = "A non-validating SQL parser."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "stevedore"
-version = "3.5.0"
-description = "Manage dynamic plugins for Python applications"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-pbr = ">=2.0.0,<2.1.0 || >2.1.0"
-
-[[package]]
-name = "termcolor"
-version = "1.1.0"
-description = "ANSII Color formatting for output in terminal."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "testfixtures"
-version = "6.18.3"
-description = "A collection of helpers and mock objects for unit tests and doc tests."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.extras]
-build = ["setuptools-git", "wheel", "twine"]
-docs = ["sphinx", "zope.component", "sybil", "twisted", "mock", "django (<2)", "django"]
-test = ["pytest (>=3.6)", "pytest-cov", "pytest-django", "zope.component", "sybil", "twisted", "mock", "django (<2)", "django"]
-
-[[package]]
-name = "testing.common.database"
-version = "2.0.3"
-description = "utilities for testing.* packages"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.extras]
-testing = ["nose"]
-
-[[package]]
-name = "testing.postgresql"
-version = "1.3.0"
-description = "automatically setups a postgresql instance in a temporary directory, and destroys it after testing"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-pg8000 = ">=1.10"
-"testing.common.database" = "*"
-
-[package.extras]
-testing = ["sqlalchemy", "nose", "psycopg2"]
-
-[[package]]
-name = "toml"
-version = "0.10.2"
-description = "Python Library for Tom's Obvious, Minimal Language"
-category = "main"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
-
-[[package]]
-name = "traitlets"
-version = "5.1.1"
-description = "Traitlets Python configuration system"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-test = ["pytest"]
-
-[[package]]
-name = "twilio"
-version = "7.2.0"
-description = "Twilio API client and TwiML generator"
-category = "main"
-optional = false
-python-versions = ">=3.6.0"
-
-[package.dependencies]
-PyJWT = ">=2.0.0,<3.0.0"
-pytz = "*"
-requests = ">=2.0.0"
-
-[[package]]
-name = "typed-ast"
-version = "1.4.3"
-description = "a fork of Python 2 and 3 ast modules with type comment support"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "types-pytz"
-version = "2021.3.0"
-description = "Typing stubs for pytz"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "types-pyyaml"
-version = "6.0.0"
-description = "Typing stubs for PyYAML"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "typing-extensions"
-version = "3.10.0.2"
-description = "Backported and Experimental Type Hints for Python 3.5+"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "urllib3"
-version = "1.26.7"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
-
-[package.extras]
-brotli = ["brotlipy (>=0.6.0)"]
-secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
-socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
-
-[[package]]
-name = "vine"
-version = "5.0.0"
-description = "Promises, promises, promises."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "wcwidth"
-version = "0.2.5"
-description = "Measures the displayed width of unicode strings in a terminal"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "webencodings"
-version = "0.5.1"
-description = "Character encoding aliases for legacy web content"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "whoosh"
-version = "2.7.4"
-description = "Fast, pure-Python full text indexing, search, and spell checking library."
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "wrapt"
-version = "1.13.2"
-description = "Module for decorators, wrappers and monkey patching."
-category = "main"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
-
-[[package]]
-name = "yubiotp"
-version = "1.0.0.post1"
-description = "A library for verifying YubiKey OTP tokens, both locally and through a Yubico web service."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-pycryptodome = "*"
-
-[metadata]
-lock-version = "1.1"
-python-versions = "^3.9"
-content-hash = "b51e585754841d7d9a71da22ad79fff4df9b115c0d74ce208d35ee633755f560"
-
-[metadata.files]
-alabaster = [
-    {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"},
-    {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"},
-]
-aleksis-app-chronos = [
-    {file = "AlekSIS-App-Chronos-2.0rc3+20210927103610.5167a6f0.tar.gz", hash = "sha256:239fc3014c1b190bce81a65d4c57155d63519a02aab4bff22531afb08ce6bd51"},
-    {file = "AlekSIS_App_Chronos-2.0rc3+20210927103610.5167a6f0-py3-none-any.whl", hash = "sha256:1c9468eb0e45b609c3e744a975e9933b1d648273a2d7408286a8cd675b3d17e3"},
-]
-aleksis-builddeps = [
-    {file = "AlekSIS-Builddeps-4.tar.gz", hash = "sha256:aaaa22965228b9b9b7de812e3e7fa9cbfdbf8635bb22d6f3a201dc0cc6d8d307"},
-    {file = "AlekSIS_Builddeps-4-py3-none-any.whl", hash = "sha256:02a93e503f5810e6c93a8bc829bc8cbda735ccbf78b91954d2f6507dfea3d01f"},
-]
-aleksis-core = [
-    {file = "AlekSIS-Core-2.1.dev0+20211028143753.e5b47dd7.tar.gz", hash = "sha256:0e942af4186475bd5d8d0dc4ec21417734a45351f2edeef9848355b650e2bf9b"},
-    {file = "AlekSIS_Core-2.1.dev0+20211028143753.e5b47dd7-py3-none-any.whl", hash = "sha256:3bd5d1f7e39fea2287e1ad8ef3161f39f032aec65d21fd19efc789c1198baecc"},
-]
-amqp = [
-    {file = "amqp-5.0.6-py3-none-any.whl", hash = "sha256:493a2ac6788ce270a2f6a765b017299f60c1998f5a8617908ee9be082f7300fb"},
-    {file = "amqp-5.0.6.tar.gz", hash = "sha256:03e16e94f2b34c31f8bf1206d8ddd3ccaa4c315f7f6a1879b7b1210d229568c2"},
-]
-appdirs = [
-    {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
-    {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
-]
-appnope = [
-    {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"},
-    {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"},
-]
-asgiref = [
-    {file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"},
-    {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"},
-]
-asn1crypto = [
-    {file = "asn1crypto-1.4.0-py2.py3-none-any.whl", hash = "sha256:4bcdf33c861c7d40bdcd74d8e4dd7661aac320fcdf40b9a3f95b4ee12fde2fa8"},
-    {file = "asn1crypto-1.4.0.tar.gz", hash = "sha256:f4f6e119474e58e04a2b1af817eb585b4fd72bdd89b998624712b5c99be7641c"},
-]
-atomicwrites = [
-    {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
-    {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
-]
-attrs = [
-    {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
-    {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
-]
-babel = [
-    {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"},
-    {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"},
-]
-backcall = [
-    {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
-    {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
-]
-bandit = [
-    {file = "bandit-1.7.0-py3-none-any.whl", hash = "sha256:216be4d044209fa06cf2a3e51b319769a51be8318140659719aa7a115c35ed07"},
-    {file = "bandit-1.7.0.tar.gz", hash = "sha256:8a4c7415254d75df8ff3c3b15cfe9042ecee628a1e40b44c15a98890fbfc2608"},
-]
-beautifulsoup4 = [
-    {file = "beautifulsoup4-4.10.0-py3-none-any.whl", hash = "sha256:9a315ce70049920ea4572a4055bc4bd700c940521d36fc858205ad4fcde149bf"},
-    {file = "beautifulsoup4-4.10.0.tar.gz", hash = "sha256:c23ad23c521d818955a4151a67d81580319d4bf548d3d49f4223ae041ff98891"},
-]
-billiard = [
-    {file = "billiard-3.6.4.0-py3-none-any.whl", hash = "sha256:87103ea78fa6ab4d5c751c4909bcff74617d985de7fa8b672cf8618afd5a875b"},
-    {file = "billiard-3.6.4.0.tar.gz", hash = "sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547"},
-]
-black = [
-    {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"},
-    {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"},
-]
-bleach = [
-    {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"},
-    {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"},
-]
-"boolean.py" = [
-    {file = "boolean.py-3.8-py2.py3-none-any.whl", hash = "sha256:d75da0fd0354425fa64f6bbc6cec6ae1485d0eec3447b73187ff8cbf9b572e26"},
-    {file = "boolean.py-3.8.tar.gz", hash = "sha256:cc24e20f985d60cd4a3a5a1c0956dd12611159d32a75081dabd0c9ab981acaa4"},
-]
-bs4 = [
-    {file = "bs4-0.0.1.tar.gz", hash = "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"},
-]
-calendarweek = [
-    {file = "calendarweek-0.5.0-py3-none-any.whl", hash = "sha256:f2003e6e0264d3d1320fc99ae6d70e60174c2664e5640c6aa31ad38e229d942d"},
-    {file = "calendarweek-0.5.0.tar.gz", hash = "sha256:32f5c8663799a2f5a0b8909976c7a3ae77397acd7e7c31d1456ece5b452988a5"},
-]
-celery = [
-    {file = "celery-5.1.2-py3-none-any.whl", hash = "sha256:9dab2170b4038f7bf10ef2861dbf486ddf1d20592290a1040f7b7a1259705d42"},
-    {file = "celery-5.1.2.tar.gz", hash = "sha256:8d9a3de9162965e97f8e8cc584c67aad83b3f7a267584fa47701ed11c3e0d4b0"},
-]
-celery-haystack-ng = [
-    {file = "celery-haystack-ng-0.20.post2.tar.gz", hash = "sha256:d2e077851f13dddc36fc86134c7c8a937e46ae75e576eb8e77e03b03977fc7bb"},
-    {file = "celery_haystack_ng-0.20.post2-py2.py3-none-any.whl", hash = "sha256:a13e00f2c29411b06c6cdf59ad6a90b6c158e3384e7ec6d6d64f6a69e8ff299a"},
-]
-celery-progress = [
-    {file = "celery-progress-0.1.1.tar.gz", hash = "sha256:b2622d1b410a763412810f0293153c984f4a0220b76769bd701b5b45e583ddad"},
-    {file = "celery_progress-0.1.1-py3-none-any.whl", hash = "sha256:36a1e58b4408c9bf6aa63908204b50960b005db8e13f3c94ce6f8d6a2a4d4a6c"},
-]
-certifi = [
-    {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
-    {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
-]
-cffi = [
-    {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"},
-    {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"},
-    {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"},
-    {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"},
-    {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"},
-    {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"},
-    {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"},
-    {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"},
-    {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"},
-    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"},
-    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"},
-    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"},
-    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"},
-    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"},
-    {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"},
-    {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"},
-    {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"},
-    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"},
-    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"},
-    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"},
-    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"},
-    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"},
-    {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"},
-    {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"},
-    {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"},
-    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"},
-    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"},
-    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"},
-    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"},
-    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"},
-    {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"},
-    {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"},
-    {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"},
-    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"},
-    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"},
-    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"},
-    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"},
-    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"},
-    {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"},
-    {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"},
-    {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"},
-    {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"},
-    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"},
-    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"},
-    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"},
-    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"},
-    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"},
-    {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"},
-    {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"},
-    {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"},
-]
-charset-normalizer = [
-    {file = "charset-normalizer-2.0.7.tar.gz", hash = "sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0"},
-    {file = "charset_normalizer-2.0.7-py3-none-any.whl", hash = "sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b"},
-]
-click = [
-    {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
-    {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
-]
-click-didyoumean = [
-    {file = "click-didyoumean-0.3.0.tar.gz", hash = "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"},
-    {file = "click_didyoumean-0.3.0-py3-none-any.whl", hash = "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667"},
-]
-click-plugins = [
-    {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"},
-    {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"},
-]
-click-repl = [
-    {file = "click-repl-0.2.0.tar.gz", hash = "sha256:cd12f68d745bf6151210790540b4cb064c7b13e571bc64b6957d98d120dacfd8"},
-    {file = "click_repl-0.2.0-py3-none-any.whl", hash = "sha256:94b3fbbc9406a236f176e0506524b2937e4b23b6f4c0c0b2a0a83f8a64e9194b"},
-]
-colorama = [
-    {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
-    {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
-]
-colour = [
-    {file = "colour-0.1.5-py2.py3-none-any.whl", hash = "sha256:33f6db9d564fadc16e59921a56999b79571160ce09916303d35346dddc17978c"},
-    {file = "colour-0.1.5.tar.gz", hash = "sha256:af20120fefd2afede8b001fbef2ea9da70ad7d49fafdb6489025dae8745c3aee"},
-]
-configobj = [
-    {file = "configobj-5.0.6.tar.gz", hash = "sha256:a2f5650770e1c87fb335af19a9b7eb73fc05ccf22144eb68db7d00cd2bcb0902"},
-]
-coverage = [
-    {file = "coverage-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1549e1d08ce38259de2bc3e9a0d5f3642ff4a8f500ffc1b2df73fd621a6cdfc0"},
-    {file = "coverage-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcae10fccb27ca2a5f456bf64d84110a5a74144be3136a5e598f9d9fb48c0caa"},
-    {file = "coverage-6.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:53a294dc53cfb39c74758edaa6305193fb4258a30b1f6af24b360a6c8bd0ffa7"},
-    {file = "coverage-6.0.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8251b37be1f2cd9c0e5ccd9ae0380909c24d2a5ed2162a41fcdbafaf59a85ebd"},
-    {file = "coverage-6.0.2-cp310-cp310-win32.whl", hash = "sha256:db42baa892cba723326284490283a68d4de516bfb5aaba369b4e3b2787a778b7"},
-    {file = "coverage-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:bbffde2a68398682623d9dd8c0ca3f46fda074709b26fcf08ae7a4c431a6ab2d"},
-    {file = "coverage-6.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:60e51a3dd55540bec686d7fff61b05048ca31e804c1f32cbb44533e6372d9cc3"},
-    {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a6a9409223a27d5ef3cca57dd7cd4dfcb64aadf2fad5c3b787830ac9223e01a"},
-    {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4b34ae4f51bbfa5f96b758b55a163d502be3dcb24f505d0227858c2b3f94f5b9"},
-    {file = "coverage-6.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3bbda1b550e70fa6ac40533d3f23acd4f4e9cb4e6e77251ce77fdf41b3309fb2"},
-    {file = "coverage-6.0.2-cp36-cp36m-win32.whl", hash = "sha256:4e28d2a195c533b58fc94a12826f4431726d8eb029ac21d874345f943530c122"},
-    {file = "coverage-6.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a82d79586a0a4f5fd1cf153e647464ced402938fbccb3ffc358c7babd4da1dd9"},
-    {file = "coverage-6.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3be1206dc09fb6298de3fce70593e27436862331a85daee36270b6d0e1c251c4"},
-    {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cd3828bbe1a40070c11fe16a51df733fd2f0cb0d745fb83b7b5c1f05967df7"},
-    {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d036dc1ed8e1388e995833c62325df3f996675779541f682677efc6af71e96cc"},
-    {file = "coverage-6.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:04560539c19ec26995ecfb3d9307ff154fbb9a172cb57e3b3cfc4ced673103d1"},
-    {file = "coverage-6.0.2-cp37-cp37m-win32.whl", hash = "sha256:e4fb7ced4d9dec77d6cf533acfbf8e1415fe799430366affb18d69ee8a3c6330"},
-    {file = "coverage-6.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:77b1da5767ed2f44611bc9bc019bc93c03fa495728ec389759b6e9e5039ac6b1"},
-    {file = "coverage-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:61b598cbdbaae22d9e34e3f675997194342f866bb1d781da5d0be54783dce1ff"},
-    {file = "coverage-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36e9040a43d2017f2787b28d365a4bb33fcd792c7ff46a047a04094dc0e2a30d"},
-    {file = "coverage-6.0.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9f1627e162e3864a596486774876415a7410021f4b67fd2d9efdf93ade681afc"},
-    {file = "coverage-6.0.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e7a0b42db2a47ecb488cde14e0f6c7679a2c5a9f44814393b162ff6397fcdfbb"},
-    {file = "coverage-6.0.2-cp38-cp38-win32.whl", hash = "sha256:a1b73c7c4d2a42b9d37dd43199c5711d91424ff3c6c22681bc132db4a4afec6f"},
-    {file = "coverage-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:1db67c497688fd4ba85b373b37cc52c50d437fd7267520ecd77bddbd89ea22c9"},
-    {file = "coverage-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f184bf38e74f152eed7f87e345b51f3ab0b703842f447c22efe35e59942c24"},
-    {file = "coverage-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1cf1deb3d5544bd942356364a2fdc8959bad2b6cf6eb17f47d301ea34ae822"},
-    {file = "coverage-6.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ad9b8c1206ae41d46ec7380b78ba735ebb77758a650643e841dd3894966c31d0"},
-    {file = "coverage-6.0.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:381d773d896cc7f8ba4ff3b92dee4ed740fb88dfe33b6e42efc5e8ab6dfa1cfe"},
-    {file = "coverage-6.0.2-cp39-cp39-win32.whl", hash = "sha256:424c44f65e8be58b54e2b0bd1515e434b940679624b1b72726147cfc6a9fc7ce"},
-    {file = "coverage-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:abbff240f77347d17306d3201e14431519bf64495648ca5a49571f988f88dee9"},
-    {file = "coverage-6.0.2-pp36-none-any.whl", hash = "sha256:7092eab374346121805fb637572483270324407bf150c30a3b161fc0c4ca5164"},
-    {file = "coverage-6.0.2-pp37-none-any.whl", hash = "sha256:30922626ce6f7a5a30bdba984ad21021529d3d05a68b4f71ea3b16bda35b8895"},
-    {file = "coverage-6.0.2.tar.gz", hash = "sha256:6807947a09510dc31fa86f43595bf3a14017cd60bf633cc746d52141bfa6b149"},
-]
-cryptography = [
-    {file = "cryptography-35.0.0-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:d57e0cdc1b44b6cdf8af1d01807db06886f10177469312fbde8f44ccbb284bc9"},
-    {file = "cryptography-35.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:ced40344e811d6abba00295ced98c01aecf0c2de39481792d87af4fa58b7b4d6"},
-    {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:54b2605e5475944e2213258e0ab8696f4f357a31371e538ef21e8d61c843c28d"},
-    {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7b7ceeff114c31f285528ba8b390d3e9cfa2da17b56f11d366769a807f17cbaa"},
-    {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d69645f535f4b2c722cfb07a8eab916265545b3475fdb34e0be2f4ee8b0b15e"},
-    {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2d0e0acc20ede0f06ef7aa58546eee96d2592c00f450c9acb89c5879b61992"},
-    {file = "cryptography-35.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:07bb7fbfb5de0980590ddfc7f13081520def06dc9ed214000ad4372fb4e3c7f6"},
-    {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7eba2cebca600a7806b893cb1d541a6e910afa87e97acf2021a22b32da1df52d"},
-    {file = "cryptography-35.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:18d90f4711bf63e2fb21e8c8e51ed8189438e6b35a6d996201ebd98a26abbbe6"},
-    {file = "cryptography-35.0.0-cp36-abi3-win32.whl", hash = "sha256:c10c797ac89c746e488d2ee92bd4abd593615694ee17b2500578b63cad6b93a8"},
-    {file = "cryptography-35.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:7075b304cd567694dc692ffc9747f3e9cb393cc4aa4fb7b9f3abd6f5c4e43588"},
-    {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a688ebcd08250eab5bb5bca318cc05a8c66de5e4171a65ca51db6bd753ff8953"},
-    {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99915d6ab265c22873f1b4d6ea5ef462ef797b4140be4c9d8b179915e0985c6"},
-    {file = "cryptography-35.0.0-pp36-pypy36_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:928185a6d1ccdb816e883f56ebe92e975a262d31cc536429041921f8cb5a62fd"},
-    {file = "cryptography-35.0.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ebeddd119f526bcf323a89f853afb12e225902a24d29b55fe18dd6fcb2838a76"},
-    {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:22a38e96118a4ce3b97509443feace1d1011d0571fae81fc3ad35f25ba3ea999"},
-    {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb80e8a1f91e4b7ef8b33041591e6d89b2b8e122d787e87eeb2b08da71bb16ad"},
-    {file = "cryptography-35.0.0-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:abb5a361d2585bb95012a19ed9b2c8f412c5d723a9836418fab7aaa0243e67d2"},
-    {file = "cryptography-35.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:1ed82abf16df40a60942a8c211251ae72858b25b7421ce2497c2eb7a1cee817c"},
-    {file = "cryptography-35.0.0.tar.gz", hash = "sha256:9933f28f70d0517686bd7de36166dda42094eac49415459d9bdf5e7df3e0086d"},
-]
-curlylint = [
-    {file = "curlylint-0.12.2-py3-none-any.whl", hash = "sha256:98bc15609ce858387dd70a28c7ddda96e82d0f1cb8bf51b8902532ce0fc1a97e"},
-    {file = "curlylint-0.12.2.tar.gz", hash = "sha256:76b557cf8d007bd92df2dae61a02e65f8aa2ff3e05c6398b1314d92692fbb0d8"},
-]
-decorator = [
-    {file = "decorator-5.1.0-py3-none-any.whl", hash = "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374"},
-    {file = "decorator-5.1.0.tar.gz", hash = "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7"},
-]
-defusedxml = [
-    {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
-    {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
-]
-deprecated = [
-    {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"},
-    {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"},
-]
-dj-database-url = [
-    {file = "dj-database-url-0.5.0.tar.gz", hash = "sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163"},
-    {file = "dj_database_url-0.5.0-py2.py3-none-any.whl", hash = "sha256:851785365761ebe4994a921b433062309eb882fedd318e1b0fcecc607ed02da9"},
-]
-django = [
-    {file = "Django-3.2.8-py3-none-any.whl", hash = "sha256:42573831292029639b798fe4d3812996bfe4ff3275f04566da90764daec011a5"},
-    {file = "Django-3.2.8.tar.gz", hash = "sha256:f6d2c4069c9b9bfac03bedff927ea1f9e0d29e34525cec8a68fd28eb2a8df7af"},
-]
-django-allauth = [
-    {file = "django-allauth-0.45.0.tar.gz", hash = "sha256:6d46be0e1480316ccd45476db3aefb39db70e038d2a543112d314b76bb999a4e"},
-]
-django-any-js = [
-    {file = "django-any-js-1.1.tar.gz", hash = "sha256:2972946902ba049f73bf8bb87e0a0118f77a8c9dca89438f193598bff758422f"},
-    {file = "django_any_js-1.1-py3-none-any.whl", hash = "sha256:1499934e293bbcaad29b8edaaefca87dda79eb3df1faeaaea67b80e2866ae1f8"},
-]
-django-appconf = [
-    {file = "django-appconf-1.0.5.tar.gz", hash = "sha256:be3db0be6c81fa84742000b89a81c016d70ae66a7ccb620cdef592b1f1a6aaa4"},
-    {file = "django_appconf-1.0.5-py3-none-any.whl", hash = "sha256:ae9f864ee1958c815a965ed63b3fba4874eec13de10236ba063a788f9a17389d"},
-]
-django-bleach = [
-    {file = "django-bleach-0.8.0.tar.gz", hash = "sha256:42a83ad8a3306e081facb7ef405883035ea23a35204aea7c2502391f3911f821"},
-    {file = "django_bleach-0.8.0-py2.py3-none-any.whl", hash = "sha256:2c978b4a7516a9e166fa1d8eba950dcfadcd6b68c80971b527fd36f03050f4c2"},
-]
-django-cachalot = [
-    {file = "django-cachalot-2.4.3.tar.gz", hash = "sha256:2c81390f53d8c2e0ae6f266cff170b5681dad2416e09266ca7ca25f50e892a53"},
-    {file = "django_cachalot-2.4.3-py3-none-any.whl", hash = "sha256:d56ffa280da8317019959801703659616adcf60e1bf6513bd7e154b0b0851014"},
-]
-django-cache-memoize = [
-    {file = "django-cache-memoize-0.1.10.tar.gz", hash = "sha256:63e8faa245a41c0dbad843807e9f21a6e59eba8e6e50df310fdf6485a6749843"},
-    {file = "django_cache_memoize-0.1.10-py3-none-any.whl", hash = "sha256:676299313079cde9242ae84db0160e80b1d44e8dd6bc9b1f4f1247e11b30c9e0"},
-]
-django-celery-beat = [
-    {file = "django-celery-beat-2.2.1.tar.gz", hash = "sha256:97ae5eb309541551bdb07bf60cc57cadacf42a74287560ced2d2c06298620234"},
-    {file = "django_celery_beat-2.2.1-py2.py3-none-any.whl", hash = "sha256:ab43049634fd18dc037927d7c2c7d5f67f95283a20ebbda55f42f8606412e66c"},
-]
-django-celery-email = [
-    {file = "django-celery-email-3.0.0.tar.gz", hash = "sha256:5546cbba80952cc3b8a0ffa4206ce90a4a996a7ffd1c385a2bdb65903ca18ece"},
-    {file = "django_celery_email-3.0.0-py2.py3-none-any.whl", hash = "sha256:0f72da39cb2ea83c69440566e87f27cd72f68f247f98ce99fb29889fcf329406"},
-]
-django-celery-results = [
-    {file = "django_celery_results-2.2.0-py2.py3-none-any.whl", hash = "sha256:d5f83fad9091e52cd6dbb3ca80632153ad14b6cdac4d73258e040f92717237cb"},
-    {file = "django_celery_results-2.2.0.tar.gz", hash = "sha256:cc0285090a306f97f1d4b7929ed98af0475bf6db2568976b3387de4fbe812edc"},
-]
-django-ckeditor = [
-    {file = "django-ckeditor-6.1.0.tar.gz", hash = "sha256:f0d108f67a81a04e26d8de11255fe314f51026eaf8eb0534a807512ae3c21620"},
-    {file = "django_ckeditor-6.1.0-py2.py3-none-any.whl", hash = "sha256:346b26b9d60dc8a88524d0eaaf406f4e91a4b3c22d208ae87aa032bf500b251c"},
-]
-django-cleanup = [
-    {file = "django-cleanup-5.2.0.tar.gz", hash = "sha256:909d10ff574f5ce1a40fa63bd5c94c9ed866fd7ae770994c46cdf66c3db3e846"},
-    {file = "django_cleanup-5.2.0-py2.py3-none-any.whl", hash = "sha256:193cf69de54b9fc0a0f4547edbb3a63bbe01728cb029f9f4b7912098cc1bced7"},
-]
-django-colorfield = [
-    {file = "django-colorfield-0.4.5.tar.gz", hash = "sha256:66d7cb628d05c0eb09e25b0923e36bf6fbd3e339c568a199e66b34463119ca13"},
-    {file = "django_colorfield-0.4.5-py3-none-any.whl", hash = "sha256:579128d008b2d15e4df64f102b1ad58432de1b6f1017221c316d630e5c62960a"},
-]
-django-dbbackup = [
-    {file = "django-dbbackup-3.3.0.tar.gz", hash = "sha256:bb109735cae98b64ad084e5b461b7aca2d7b39992f10c9ed9435e3ebb6fb76c8"},
-]
-django-debug-toolbar = [
-    {file = "django-debug-toolbar-3.2.2.tar.gz", hash = "sha256:8c5b13795d4040008ee69ba82dcdd259c49db346cf7d0de6e561a49d191f0860"},
-    {file = "django_debug_toolbar-3.2.2-py3-none-any.whl", hash = "sha256:d7bab7573fab35b0fd029163371b7182f5826c13da69734beb675c761d06a4d3"},
-]
-django-dynamic-preferences = [
-    {file = "django-dynamic-preferences-1.11.0.tar.gz", hash = "sha256:f214c938b5872a17647e2b2ccfd9ad00a90a3c6c4aa83fa65d3c5c446e7a66c7"},
-    {file = "django_dynamic_preferences-1.11.0-py2.py3-none-any.whl", hash = "sha256:31aecebcbfcfb970b78cfa3e5f8cc9f77638efe8e7c90f205a48b01c45ee5002"},
-]
-django-extensions = [
-    {file = "django-extensions-3.1.3.tar.gz", hash = "sha256:5f0fea7bf131ca303090352577a9e7f8bfbf5489bd9d9c8aea9401db28db34a0"},
-    {file = "django_extensions-3.1.3-py3-none-any.whl", hash = "sha256:50de8977794a66a91575dd40f87d5053608f679561731845edbd325ceeb387e3"},
-]
-django-favicon-plus-reloaded = [
-    {file = "django-favicon-plus-reloaded-1.1.3.tar.gz", hash = "sha256:36c2a1cefc201df8bd132492e2440ccdc3d9ceb8e421b2ca181a4704ebacd190"},
-    {file = "django_favicon_plus_reloaded-1.1.3-py3-none-any.whl", hash = "sha256:a60b438360e82bf7075b856ff6a80bae20c825373a58deac627810e478c42be3"},
-]
-django-filter = [
-    {file = "django-filter-2.4.0.tar.gz", hash = "sha256:84e9d5bb93f237e451db814ed422a3a625751cbc9968b484ecc74964a8696b06"},
-    {file = "django_filter-2.4.0-py3-none-any.whl", hash = "sha256:e00d32cebdb3d54273c48f4f878f898dced8d5dfaad009438fe61ebdf535ace1"},
-]
-django-formtools = [
-    {file = "django-formtools-2.3.tar.gz", hash = "sha256:9663b6eca64777b68d6d4142efad8597fe9a685924673b25aa8a1dcff4db00c3"},
-    {file = "django_formtools-2.3-py3-none-any.whl", hash = "sha256:4699937e19ee041d803943714fe0c1c7ad4cab802600eb64bbf4cdd0a1bfe7d9"},
-]
-django-guardian = [
-    {file = "django-guardian-2.4.0.tar.gz", hash = "sha256:c58a68ae76922d33e6bdc0e69af1892097838de56e93e78a8361090bcd9f89a0"},
-    {file = "django_guardian-2.4.0-py3-none-any.whl", hash = "sha256:440ca61358427e575323648b25f8384739e54c38b3d655c81d75e0cd0d61b697"},
-]
-django-haystack = [
-    {file = "django-haystack-3.0.tar.gz", hash = "sha256:d490f920afa85471dd1fa5000bc8eff4b704daacbe09aee1a64e75cbc426f3be"},
-]
-django-health-check = [
-    {file = "django-health-check-3.16.4.tar.gz", hash = "sha256:334bcbbb9273a6dbd9c928e78474306e623dfb38cc442281cb9fd230a20a7fdb"},
-    {file = "django_health_check-3.16.4-py2.py3-none-any.whl", hash = "sha256:86a8869d67e72394a1dd73e37819a7d2cfd915588b96927fda611d7451fd4735"},
-]
-django-impersonate = [
-    {file = "django-impersonate-1.7.3.tar.gz", hash = "sha256:282003957577c7143fe31e5861f8fffdf6fe0c25557aedb28fcf8b11474eaa23"},
-]
-django-ipware = [
-    {file = "django-ipware-4.0.0.tar.gz", hash = "sha256:1294f916f3b3475e40e1b0ec1bd320aa2397978eae672721c81cbc2ed517e9ee"},
-    {file = "django_ipware-4.0.0-py2.py3-none-any.whl", hash = "sha256:116bd0d7940f09bf7ffd465943992e23d87e772a9d6c0d3a57b74040589a383b"},
-]
-django-js-asset = [
-    {file = "django-js-asset-1.2.2.tar.gz", hash = "sha256:c163ae80d2e0b22d8fb598047cd0dcef31f81830e127cfecae278ad574167260"},
-    {file = "django_js_asset-1.2.2-py2.py3-none-any.whl", hash = "sha256:8ec12017f26eec524cab436c64ae73033368a372970af4cf42d9354fcb166bdd"},
-]
-django-js-reverse = [
-    {file = "django-js-reverse-0.9.1.tar.gz", hash = "sha256:2a392d169f44e30b883c30dfcfd917a14167ce8fe196c99d2385b31c90d77aa0"},
-    {file = "django_js_reverse-0.9.1-py2.py3-none-any.whl", hash = "sha256:8134c2ab6307c945edfa90671ca65e85d6c1754d48566bdd6464be259cc80c30"},
-]
-django-jsonstore = [
-    {file = "django-jsonstore-0.5.0.tar.gz", hash = "sha256:896dc10b08f59807eda1c6cebf43cd26e50d0db29d13495c027dc31e464be3c3"},
-    {file = "django_jsonstore-0.5.0-py2-none-any.whl", hash = "sha256:9630c1fb43ae9f8e32733c5cf7d4c3775ba6f08532f517c64025053352d72844"},
-]
-django-maintenance-mode = [
-    {file = "django-maintenance-mode-0.16.1.tar.gz", hash = "sha256:da1f77f431ab5c55913459adb3c259e091f783ffc72de701690826aaaccce4ca"},
-    {file = "django_maintenance_mode-0.16.1-py3-none-any.whl", hash = "sha256:1bfac0b34429a9f6dbb0db169fb753f49f24ca155ae148d7526ff395303c158d"},
-]
-django-material = [
-    {file = "django-material-1.9.0.tar.gz", hash = "sha256:5a7144d1029b4a2bfee2e5d0d8d00f30742dd7e3f868b3787d8cd61e54f26437"},
-    {file = "django_material-1.9.0-py2.py3-none-any.whl", hash = "sha256:816513170771bcb2540b5ce314fbef1a906906220587a9cb9521e61092a6f610"},
-]
-django-menu-generator-ng = [
-    {file = "django-menu-generator-ng-1.2.3.tar.gz", hash = "sha256:0c21a094b094add909655728b6b2d4a8baa5a2047da8f649be52589bea0e3ba2"},
-]
-django-model-utils = [
-    {file = "django-model-utils-4.2.0.tar.gz", hash = "sha256:e7a95e102f9c9653427eadab980d5d59e1dea972913b9c9e01ac37f86bba0ddf"},
-    {file = "django_model_utils-4.2.0-py3-none-any.whl", hash = "sha256:a768a25c80514e0ad4e4a6f9c02c44498985f36c5dfdea47b5b1e8cf994beba6"},
-]
-django-oauth-toolkit = [
-    {file = "django-oauth-toolkit-1.5.0.tar.gz", hash = "sha256:650e5ef2244d1d8db8f507137e0d1e8b8aad1f4086a4a610526e8851f9a38308"},
-    {file = "django_oauth_toolkit-1.5.0-py3-none-any.whl", hash = "sha256:b2e346a7c1e222774bfb370f21b556b92b408395b4c23914e2d1b241b2e5376a"},
-]
-django-otp = [
-    {file = "django-otp-1.1.1.tar.gz", hash = "sha256:4c90cdaed683d736b0efafc034a3c6b410e1be2a53c24da287165b1f371d8776"},
-    {file = "django_otp-1.1.1-py3-none-any.whl", hash = "sha256:0c03a471db9e876f3671314bc9a65bd56a5c3c108ee0562c473701310bba4a77"},
-]
-django-otp-yubikey = [
-    {file = "django-otp-yubikey-1.0.0.post1.tar.gz", hash = "sha256:1da060257611d06e681848b7923fd788d878a79e8c358a373374deab13a085af"},
-    {file = "django_otp_yubikey-1.0.0.post1-py2.py3-none-any.whl", hash = "sha256:613c96be211c1267400a5a78ae63f212c722f82dffb9daef3c8b1df370abb9be"},
-]
-django-phonenumber-field = [
-    {file = "django-phonenumber-field-5.2.0.tar.gz", hash = "sha256:52b2e5970133ec5ab701218b802f7ab237229854dc95fd239b7e9e77dc43731d"},
-    {file = "django_phonenumber_field-5.2.0-py3-none-any.whl", hash = "sha256:5547fb2b2cc690a306ba77a5038419afc8fa8298a486fb7895008e9067cc7e75"},
-]
-django-polymorphic = [
-    {file = "django-polymorphic-3.0.0.tar.gz", hash = "sha256:9d886f19f031d26bb1391c055ed9be06fb226a04a4cec1842b372c58873b3caa"},
-    {file = "django_polymorphic-3.0.0-py2.py3-none-any.whl", hash = "sha256:73b75eb44ea302bd32820f8661e469509d245ce7f7ff09cd2ad149e5c42034ff"},
-]
-django-prometheus = [
-    {file = "django-prometheus-2.1.0.tar.gz", hash = "sha256:dd3f8da1399140fbef5c00d1526a23d1ade286b144281c325f8e409a781643f2"},
-    {file = "django_prometheus-2.1.0-py2.py3-none-any.whl", hash = "sha256:c338d6efde1ca336e90c540b5e87afe9287d7bcc82d651a778f302b0be17a933"},
-]
-django-redis = [
-    {file = "django-redis-5.0.0.tar.gz", hash = "sha256:048f665bbe27f8ff2edebae6aa9c534ab137f1e8fa7234147ef470df3f3aa9b8"},
-    {file = "django_redis-5.0.0-py3-none-any.whl", hash = "sha256:97739ca9de3f964c51412d1d7d8aecdfd86737bb197fce6e1ff12620c63c97ee"},
-]
-django-render-block = [
-    {file = "django-render-block-0.8.1.tar.gz", hash = "sha256:edbc5d444cc50f3eb3387cf17f6f1014bf19d6018f680861cdeae9e0306003fa"},
-    {file = "django_render_block-0.8.1-py3-none-any.whl", hash = "sha256:903969efd0949f750c5fe71affe6e6b1ea66d03005c102a67fda36d5b9f4e1e1"},
-]
-django-reversion = [
-    {file = "django-reversion-4.0.0.tar.gz", hash = "sha256:ad6d714b4b9b824e22b88d47201cc0f74b5c4294c8d4e1f8d7ac7c3631ef3188"},
-    {file = "django_reversion-4.0.0-py3-none-any.whl", hash = "sha256:f059c654e38c0dd8dccd7f0990aa2f6d9ad22dab55c5e095f9596aeda8079dcd"},
-]
-django-sass-processor = [
-    {file = "django-sass-processor-1.0.0.tar.gz", hash = "sha256:cb90efee38cd7b0fe727c78d8993ad7804de33f40328200dfc1a481307ef0466"},
-]
-django-select2 = [
-    {file = "django-select2-7.7.3.tar.gz", hash = "sha256:063d29df5598ec6549a4d49cc4beb85d585987a4e470224592034aff2d4f0a3f"},
-    {file = "django_select2-7.7.3-py2.py3-none-any.whl", hash = "sha256:7bf5b35595624a3318f46d69f639e38dafb123fa4a6f82d63a6a1ac6d532317d"},
-]
-django-stubs = [
-    {file = "django-stubs-1.9.0.tar.gz", hash = "sha256:664843091636a917faf5256d028476559dc360fdef9050b6df87ab61b21607bf"},
-    {file = "django_stubs-1.9.0-py3-none-any.whl", hash = "sha256:59c9f81af64d214b1954eaf90f037778c8d2b9c2de946a3cda177fefcf588fbd"},
-]
-django-stubs-ext = [
-    {file = "django-stubs-ext-0.3.1.tar.gz", hash = "sha256:783c198d7e39a41be0b90fd843fa2770243a642922af679be4b19e03b82c8c28"},
-    {file = "django_stubs_ext-0.3.1-py3-none-any.whl", hash = "sha256:a51a3e9e844d4e1cacaaedbb33bf3def78a3956eed5d9575a640bd97ccd99cec"},
-]
-django-tables2 = [
-    {file = "django-tables2-2.4.1.tar.gz", hash = "sha256:6c72dd208358539e789e4c0efd7d151e43283a4aa4093a35f44c43489e7ddeaa"},
-    {file = "django_tables2-2.4.1-py2.py3-none-any.whl", hash = "sha256:50762bf3d7c61a4eb70e763c3e278650d7266bb78d0497fc8fafcf4e507c9a64"},
-]
-django-templated-email = [
-    {file = "django-templated-email-3.0.0.tar.gz", hash = "sha256:49d61840ec551e640adaf341146e94d6f9058ae01df964480850bf988046e5eb"},
-    {file = "django_templated_email-3.0.0-py3-none-any.whl", hash = "sha256:bf1b68ffe6c8794c0c50e2ce20e3a166c6d511b3879abbd3cf059a3fc2fe2e60"},
-]
-django-timezone-field = [
-    {file = "django-timezone-field-4.2.1.tar.gz", hash = "sha256:97780cde658daa5094ae515bb55ca97c1352928ab554041207ad515dee3fe971"},
-    {file = "django_timezone_field-4.2.1-py3-none-any.whl", hash = "sha256:6dc782e31036a58da35b553bd00c70f112d794700025270d8a6a4c1d2e5b26c6"},
-]
-django-titofisto = [
-    {file = "django-titofisto-0.1.2.post1.tar.gz", hash = "sha256:e3b0783142d075aadda1c041061f84affdbe767ffaeebd0f615359723339c208"},
-    {file = "django_titofisto-0.1.2.post1-py3-none-any.whl", hash = "sha256:abebb5db39562bde9999ffd4afe67d43eefae37c8a7ec7abbe611420e6f8aca0"},
-]
-django-two-factor-auth = [
-    {file = "django-two-factor-auth-1.13.1.tar.gz", hash = "sha256:a20e03d256fd9fd668988545f052cedcc47e5a981888562e5e27d0bb83deae89"},
-    {file = "django_two_factor_auth-1.13.1-py2.py3-none-any.whl", hash = "sha256:d270d4288731233621a9462a89a8dfed2dcb86fa354125c816a89772d55f9e29"},
-]
-django-uwsgi-ng = [
-    {file = "django-uwsgi-ng-1.1.2.tar.gz", hash = "sha256:1df2ffa642f7a831bd8d7f7e459f7b0821113b37174ccf4bf977e4467d45d9b3"},
-    {file = "django_uwsgi_ng-1.1.2-py3-none-any.whl", hash = "sha256:8b1a489a1ed9e56da0efadfa86ec306b532e5cd953fe34b234aaefc26898c649"},
-]
-django-widget-tweaks = [
-    {file = "django-widget-tweaks-1.4.9.tar.gz", hash = "sha256:19bcb66a4a9e68493ced04e7124882d753c5be517ed001556f9e35a40147f545"},
-    {file = "django_widget_tweaks-1.4.9-py2.py3-none-any.whl", hash = "sha256:d6c64fbf92cd2df9031f597c1374982233c05a1190d295c39d1c57ce007569c7"},
-]
-django-yarnpkg = [
-    {file = "django-yarnpkg-6.0.1.tar.gz", hash = "sha256:aa059347b246c6f242401581d2c129bdcb45aa726be59fe2f288762a9843348a"},
-]
-djangorestframework = [
-    {file = "djangorestframework-3.12.4-py3-none-any.whl", hash = "sha256:6d1d59f623a5ad0509fe0d6bfe93cbdfe17b8116ebc8eda86d45f6e16e819aaf"},
-    {file = "djangorestframework-3.12.4.tar.gz", hash = "sha256:f747949a8ddac876e879190df194b925c177cdeb725a099db1460872f7c0a7f2"},
-]
-docutils = [
-    {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"},
-    {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"},
-]
-dparse = [
-    {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"},
-    {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"},
-]
-dynaconf = [
-    {file = "dynaconf-3.1.7-py2.py3-none-any.whl", hash = "sha256:f52fe5db7622da56a552275e8f64e4df46e3b4ae11158831b042e8ba2f6d1c96"},
-    {file = "dynaconf-3.1.7.tar.gz", hash = "sha256:e9d80b46ba4d9372f2f40c812594c963f74178140c0b596e57f2881001fc4d35"},
-]
-flake8 = [
-    {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
-    {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"},
-]
-flake8-bandit = [
-    {file = "flake8_bandit-2.1.2.tar.gz", hash = "sha256:687fc8da2e4a239b206af2e54a90093572a60d0954f3054e23690739b0b0de3b"},
-]
-flake8-black = [
-    {file = "flake8-black-0.2.3.tar.gz", hash = "sha256:c199844bc1b559d91195ebe8620216f21ed67f2cc1ff6884294c91a0d2492684"},
-    {file = "flake8_black-0.2.3-py3-none-any.whl", hash = "sha256:cc080ba5b3773b69ba102b6617a00cc4ecbad8914109690cfda4d565ea435d96"},
-]
-flake8-builtins = [
-    {file = "flake8-builtins-1.5.3.tar.gz", hash = "sha256:09998853b2405e98e61d2ff3027c47033adbdc17f9fe44ca58443d876eb00f3b"},
-    {file = "flake8_builtins-1.5.3-py2.py3-none-any.whl", hash = "sha256:7706babee43879320376861897e5d1468e396a40b8918ed7bccf70e5f90b8687"},
-]
-flake8-django = [
-    {file = "flake8-django-1.1.2.tar.gz", hash = "sha256:b4314abb5bacda450d2eae564a0604447111b1b98188e46bca41682ad2ab59d6"},
-    {file = "flake8_django-1.1.2-py3-none-any.whl", hash = "sha256:f8bfdbe8352c2c5f3788c2a2f6652dd2604af24af07a5aa112206d63ae228fdc"},
-]
-flake8-docstrings = [
-    {file = "flake8-docstrings-1.6.0.tar.gz", hash = "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b"},
-    {file = "flake8_docstrings-1.6.0-py2.py3-none-any.whl", hash = "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde"},
-]
-flake8-fixme = [
-    {file = "flake8-fixme-1.1.1.tar.gz", hash = "sha256:50cade07d27a4c30d4f12351478df87339e67640c83041b664724bda6d16f33a"},
-    {file = "flake8_fixme-1.1.1-py2.py3-none-any.whl", hash = "sha256:226a6f2ef916730899f29ac140bed5d4a17e5aba79f00a0e3ae1eff1997cb1ac"},
-]
-flake8-isort = [
-    {file = "flake8-isort-4.1.1.tar.gz", hash = "sha256:d814304ab70e6e58859bc5c3e221e2e6e71c958e7005239202fee19c24f82717"},
-    {file = "flake8_isort-4.1.1-py3-none-any.whl", hash = "sha256:c4e8b6dcb7be9b71a02e6e5d4196cefcef0f3447be51e82730fb336fff164949"},
-]
-flake8-mypy = [
-    {file = "flake8-mypy-17.8.0.tar.gz", hash = "sha256:47120db63aff631ee1f84bac6fe8e64731dc66da3efc1c51f85e15ade4a3ba18"},
-    {file = "flake8_mypy-17.8.0-py35.py36-none-any.whl", hash = "sha256:cff009f4250e8391bf48990093cff85802778c345c8449d6498b62efefeebcbc"},
-]
-flake8-polyfill = [
-    {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"},
-    {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"},
-]
-flake8-rst-docstrings = [
-    {file = "flake8-rst-docstrings-0.2.3.tar.gz", hash = "sha256:3045794e1c8467fba33aaea5c246b8369efc9c44ef8b0b20199bb6df7a4bd47b"},
-    {file = "flake8_rst_docstrings-0.2.3-py3-none-any.whl", hash = "sha256:565bbb391d7e4d0042924102221e9857ad72929cdd305b26501736ec22c1451a"},
-]
-freezegun = [
-    {file = "freezegun-1.1.0-py2.py3-none-any.whl", hash = "sha256:2ae695f7eb96c62529f03a038461afe3c692db3465e215355e1bb4b0ab408712"},
-    {file = "freezegun-1.1.0.tar.gz", hash = "sha256:177f9dd59861d871e27a484c3332f35a6e3f5d14626f2bf91be37891f18927f3"},
-]
-gitdb = [
-    {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"},
-    {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"},
-]
-gitpython = [
-    {file = "GitPython-3.1.24-py3-none-any.whl", hash = "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647"},
-    {file = "GitPython-3.1.24.tar.gz", hash = "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5"},
-]
-haystack-redis = [
-    {file = "haystack-redis-0.0.1.tar.gz", hash = "sha256:ccfea88bdc1387c9f7f6f19e9bc062a3612039ef94cfd3e78cf59a96ddd269b2"},
-    {file = "haystack_redis-0.0.1-py3-none-any.whl", hash = "sha256:4fdeee5a9d8daadb1fed4584fd2ffbb25b1ed2315dacb97b53093756d6b54467"},
-]
-html2text = [
-    {file = "html2text-2020.1.16-py3-none-any.whl", hash = "sha256:c7c629882da0cf377d66f073329ccf34a12ed2adf0169b9285ae4e63ef54c82b"},
-    {file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"},
-]
-idna = [
-    {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
-    {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
-]
-imagesize = [
-    {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"},
-    {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"},
-]
-iniconfig = [
-    {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
-    {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
-]
-ipython = [
-    {file = "ipython-7.28.0-py3-none-any.whl", hash = "sha256:f16148f9163e1e526f1008d7c8d966d9c15600ca20d1a754287cf96d00ba6f1d"},
-    {file = "ipython-7.28.0.tar.gz", hash = "sha256:2097be5c814d1b974aea57673176a924c4c8c9583890e7a5f082f547b9975b11"},
-]
-isort = [
-    {file = "isort-5.9.3-py3-none-any.whl", hash = "sha256:e17d6e2b81095c9db0a03a8025a957f334d6ea30b26f9ec70805411e5c7c81f2"},
-    {file = "isort-5.9.3.tar.gz", hash = "sha256:9c2ea1e62d871267b78307fe511c0838ba0da28698c5732d54e2790bf3ba9899"},
-]
-jedi = [
-    {file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"},
-    {file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"},
-]
-jinja2 = [
-    {file = "Jinja2-3.0.2-py3-none-any.whl", hash = "sha256:8569982d3f0889eed11dd620c706d39b60c36d6d25843961f33f77fb6bc6b20c"},
-    {file = "Jinja2-3.0.2.tar.gz", hash = "sha256:827a0e32839ab1600d4eb1c4c33ec5a8edfbc5cb42dafa13b81f182f97784b45"},
-]
-jwcrypto = [
-    {file = "jwcrypto-1.0-py2.py3-none-any.whl", hash = "sha256:db93a656d9a7a35dda5a68deb5c9f301f4e60507d8aef1559e0637b9ac497137"},
-    {file = "jwcrypto-1.0.tar.gz", hash = "sha256:f88816eb0a41b8f006af978ced5f171f33782525006cdb055b536a40f4d46ac9"},
-]
-kombu = [
-    {file = "kombu-5.1.0-py3-none-any.whl", hash = "sha256:e2dedd8a86c9077c350555153825a31e456a0dc20c15d5751f00137ec9c75f0a"},
-    {file = "kombu-5.1.0.tar.gz", hash = "sha256:01481d99f4606f6939cdc9b637264ed353ee9e3e4f62cfb582324142c41a572d"},
-]
-libsass = [
-    {file = "libsass-0.21.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:06c8776417fe930714bdc930a3d7e795ae3d72be6ac883ff72a1b8f7c49e5ffb"},
-    {file = "libsass-0.21.0-cp27-cp27m-win32.whl", hash = "sha256:a005f298f64624f313a3ac618ab03f844c71d84ae4f4a4aec4b68d2a4ffe75eb"},
-    {file = "libsass-0.21.0-cp27-cp27m-win_amd64.whl", hash = "sha256:6b984510ed94993708c0d697b4fef2d118929bbfffc3b90037be0f5ccadf55e7"},
-    {file = "libsass-0.21.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e25dd9047a9392d3c59a0b869e0404f2b325a03871ee45285ee33b3664f5613"},
-    {file = "libsass-0.21.0-cp36-abi3-macosx_10_14_x86_64.whl", hash = "sha256:12f39712de38689a8b785b7db41d3ba2ea1d46f9379d81ea4595802d91fa6529"},
-    {file = "libsass-0.21.0-cp36-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e2b1a7d093f2e76dc694c17c0c285e846d0b0deb0e8b21dc852ba1a3a4e2f1d6"},
-    {file = "libsass-0.21.0-cp36-abi3-win32.whl", hash = "sha256:abc29357ee540849faf1383e1746d40d69ed5cb6d4c346df276b258f5aa8977a"},
-    {file = "libsass-0.21.0-cp36-abi3-win_amd64.whl", hash = "sha256:659ae41af8708681fa3ec73f47b9735a6725e71c3b66ff570bfce78952f2314e"},
-    {file = "libsass-0.21.0.tar.gz", hash = "sha256:d5ba529d9ce668be9380563279f3ffe988f27bc5b299c5a28453df2e0b0fbaf2"},
-]
-license-expression = [
-    {file = "license-expression-1.2.tar.gz", hash = "sha256:7960e1dfdf20d127e75ead931476f2b5c7556df05b117a73880b22ade17d1abc"},
-    {file = "license_expression-1.2-py2.py3-none-any.whl", hash = "sha256:6d97906380cecfc758a77f6d38c6760f2afade7e83d2b8295e234fe21f486fb8"},
-]
-markupsafe = [
-    {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"},
-    {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"},
-    {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"},
-    {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"},
-    {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"},
-    {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"},
-    {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"},
-    {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"},
-    {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"},
-    {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"},
-    {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"},
-    {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"},
-]
-matplotlib-inline = [
-    {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"},
-    {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"},
-]
-mccabe = [
-    {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
-    {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
-]
-mypy = [
-    {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
-    {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
-    {file = "mypy-0.910-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9"},
-    {file = "mypy-0.910-cp35-cp35m-win_amd64.whl", hash = "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e"},
-    {file = "mypy-0.910-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921"},
-    {file = "mypy-0.910-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6"},
-    {file = "mypy-0.910-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212"},
-    {file = "mypy-0.910-cp36-cp36m-win_amd64.whl", hash = "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885"},
-    {file = "mypy-0.910-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0"},
-    {file = "mypy-0.910-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de"},
-    {file = "mypy-0.910-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703"},
-    {file = "mypy-0.910-cp37-cp37m-win_amd64.whl", hash = "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a"},
-    {file = "mypy-0.910-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504"},
-    {file = "mypy-0.910-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9"},
-    {file = "mypy-0.910-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072"},
-    {file = "mypy-0.910-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811"},
-    {file = "mypy-0.910-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e"},
-    {file = "mypy-0.910-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b"},
-    {file = "mypy-0.910-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2"},
-    {file = "mypy-0.910-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97"},
-    {file = "mypy-0.910-cp39-cp39-win_amd64.whl", hash = "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8"},
-    {file = "mypy-0.910-py3-none-any.whl", hash = "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"},
-    {file = "mypy-0.910.tar.gz", hash = "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"},
-]
-mypy-extensions = [
-    {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
-    {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
-]
-oauthlib = [
-    {file = "oauthlib-3.1.1-py2.py3-none-any.whl", hash = "sha256:42bf6354c2ed8c6acb54d971fce6f88193d97297e18602a3a886603f9d7730cc"},
-    {file = "oauthlib-3.1.1.tar.gz", hash = "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3"},
-]
-packaging = [
-    {file = "packaging-21.2-py3-none-any.whl", hash = "sha256:14317396d1e8cdb122989b916fa2c7e9ca8e2be9e8060a6eff75b6b7b4d8a7e0"},
-    {file = "packaging-21.2.tar.gz", hash = "sha256:096d689d78ca690e4cd8a89568ba06d07ca097e3306a4381635073ca91479966"},
-]
-parso = [
-    {file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"},
-    {file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"},
-]
-parsy = [
-    {file = "parsy-1.1.0-py3-none-any.whl", hash = "sha256:25bd5cea2954950ebbfdf71f8bdaf7fd45a5df5325fd36a1064be2204d9d4c94"},
-    {file = "parsy-1.1.0.tar.gz", hash = "sha256:36173ba01a5372c7a1b32352cc73a279a49198f52252adf1c8c1ed41d1f94e8d"},
-]
-pathspec = [
-    {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
-    {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
-]
-pbr = [
-    {file = "pbr-5.6.0-py2.py3-none-any.whl", hash = "sha256:c68c661ac5cc81058ac94247278eeda6d2e6aecb3e227b0387c30d277e7ef8d4"},
-    {file = "pbr-5.6.0.tar.gz", hash = "sha256:42df03e7797b796625b1029c0400279c7c34fd7df24a7d7818a1abb5b38710dd"},
-]
-persisting-theory = [
-    {file = "persisting-theory-0.2.1.tar.gz", hash = "sha256:00ff7dcc8f481ff75c770ca5797d968e8725b6df1f77fe0cf7d20fa1e5790c0a"},
-]
-pexpect = [
-    {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
-    {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
-]
-pg8000 = [
-    {file = "pg8000-1.22.0-py3-none-any.whl", hash = "sha256:a0e82542f4a56b2139c41ff09c1aeff294c10b6500bb6c57890c0c1c551cbc03"},
-    {file = "pg8000-1.22.0.tar.gz", hash = "sha256:c5172252fc92142ec104cd5e7231be4580a1a0a814403707bafbf7bb8383a29a"},
-]
-phonenumbers = [
-    {file = "phonenumbers-8.12.36-py2.py3-none-any.whl", hash = "sha256:fa91fff1cefee6873c78f08c767f341a7658c849ffb74b605cb38cefef0e76fa"},
-    {file = "phonenumbers-8.12.36.tar.gz", hash = "sha256:e29717fcf86d68082fc6e42ca07e52bff863b6e0b354edd1644ba15c35ef213d"},
-]
-pickleshare = [
-    {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
-    {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
-]
-pillow = [
-    {file = "Pillow-8.4.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:81f8d5c81e483a9442d72d182e1fb6dcb9723f289a57e8030811bac9ea3fef8d"},
-    {file = "Pillow-8.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f97cfb1e5a392d75dd8b9fd274d205404729923840ca94ca45a0af57e13dbe6"},
-    {file = "Pillow-8.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb9fc393f3c61f9054e1ed26e6fe912c7321af2f41ff49d3f83d05bacf22cc78"},
-    {file = "Pillow-8.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d82cdb63100ef5eedb8391732375e6d05993b765f72cb34311fab92103314649"},
-    {file = "Pillow-8.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62cc1afda735a8d109007164714e73771b499768b9bb5afcbbee9d0ff374b43f"},
-    {file = "Pillow-8.4.0-cp310-cp310-win32.whl", hash = "sha256:e3dacecfbeec9a33e932f00c6cd7996e62f53ad46fbe677577394aaa90ee419a"},
-    {file = "Pillow-8.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:620582db2a85b2df5f8a82ddeb52116560d7e5e6b055095f04ad828d1b0baa39"},
-    {file = "Pillow-8.4.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:1bc723b434fbc4ab50bb68e11e93ce5fb69866ad621e3c2c9bdb0cd70e345f55"},
-    {file = "Pillow-8.4.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72cbcfd54df6caf85cc35264c77ede902452d6df41166010262374155947460c"},
-    {file = "Pillow-8.4.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70ad9e5c6cb9b8487280a02c0ad8a51581dcbbe8484ce058477692a27c151c0a"},
-    {file = "Pillow-8.4.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25a49dc2e2f74e65efaa32b153527fc5ac98508d502fa46e74fa4fd678ed6645"},
-    {file = "Pillow-8.4.0-cp36-cp36m-win32.whl", hash = "sha256:93ce9e955cc95959df98505e4608ad98281fff037350d8c2671c9aa86bcf10a9"},
-    {file = "Pillow-8.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2e4440b8f00f504ee4b53fe30f4e381aae30b0568193be305256b1462216feff"},
-    {file = "Pillow-8.4.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8c803ac3c28bbc53763e6825746f05cc407b20e4a69d0122e526a582e3b5e153"},
-    {file = "Pillow-8.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8a17b5d948f4ceeceb66384727dde11b240736fddeda54ca740b9b8b1556b29"},
-    {file = "Pillow-8.4.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1394a6ad5abc838c5cd8a92c5a07535648cdf6d09e8e2d6df916dfa9ea86ead8"},
-    {file = "Pillow-8.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:792e5c12376594bfcb986ebf3855aa4b7c225754e9a9521298e460e92fb4a488"},
-    {file = "Pillow-8.4.0-cp37-cp37m-win32.whl", hash = "sha256:d99ec152570e4196772e7a8e4ba5320d2d27bf22fdf11743dd882936ed64305b"},
-    {file = "Pillow-8.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:7b7017b61bbcdd7f6363aeceb881e23c46583739cb69a3ab39cb384f6ec82e5b"},
-    {file = "Pillow-8.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d89363f02658e253dbd171f7c3716a5d340a24ee82d38aab9183f7fdf0cdca49"},
-    {file = "Pillow-8.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0a0956fdc5defc34462bb1c765ee88d933239f9a94bc37d132004775241a7585"},
-    {file = "Pillow-8.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b7bb9de00197fb4261825c15551adf7605cf14a80badf1761d61e59da347779"},
-    {file = "Pillow-8.4.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72b9e656e340447f827885b8d7a15fc8c4e68d410dc2297ef6787eec0f0ea409"},
-    {file = "Pillow-8.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5a4532a12314149d8b4e4ad8ff09dde7427731fcfa5917ff16d0291f13609df"},
-    {file = "Pillow-8.4.0-cp38-cp38-win32.whl", hash = "sha256:82aafa8d5eb68c8463b6e9baeb4f19043bb31fefc03eb7b216b51e6a9981ae09"},
-    {file = "Pillow-8.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:066f3999cb3b070a95c3652712cffa1a748cd02d60ad7b4e485c3748a04d9d76"},
-    {file = "Pillow-8.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:5503c86916d27c2e101b7f71c2ae2cddba01a2cf55b8395b0255fd33fa4d1f1a"},
-    {file = "Pillow-8.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4acc0985ddf39d1bc969a9220b51d94ed51695d455c228d8ac29fcdb25810e6e"},
-    {file = "Pillow-8.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b052a619a8bfcf26bd8b3f48f45283f9e977890263e4571f2393ed8898d331b"},
-    {file = "Pillow-8.4.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:493cb4e415f44cd601fcec11c99836f707bb714ab03f5ed46ac25713baf0ff20"},
-    {file = "Pillow-8.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8831cb7332eda5dc89b21a7bce7ef6ad305548820595033a4b03cf3091235ed"},
-    {file = "Pillow-8.4.0-cp39-cp39-win32.whl", hash = "sha256:5e9ac5f66616b87d4da618a20ab0a38324dbe88d8a39b55be8964eb520021e02"},
-    {file = "Pillow-8.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:3eb1ce5f65908556c2d8685a8f0a6e989d887ec4057326f6c22b24e8a172c66b"},
-    {file = "Pillow-8.4.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ddc4d832a0f0b4c52fff973a0d44b6c99839a9d016fe4e6a1cb8f3eea96479c2"},
-    {file = "Pillow-8.4.0-pp36-pypy36_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a3e5ddc44c14042f0844b8cf7d2cd455f6cc80fd7f5eefbe657292cf601d9ad"},
-    {file = "Pillow-8.4.0-pp36-pypy36_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c70e94281588ef053ae8998039610dbd71bc509e4acbc77ab59d7d2937b10698"},
-    {file = "Pillow-8.4.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:3862b7256046fcd950618ed22d1d60b842e3a40a48236a5498746f21189afbbc"},
-    {file = "Pillow-8.4.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4901622493f88b1a29bd30ec1a2f683782e57c3c16a2dbc7f2595ba01f639df"},
-    {file = "Pillow-8.4.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c471a734240653a0ec91dec0996696eea227eafe72a33bd06c92697728046b"},
-    {file = "Pillow-8.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc"},
-    {file = "Pillow-8.4.0.tar.gz", hash = "sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed"},
-]
-pluggy = [
-    {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
-    {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
-]
-prometheus-client = [
-    {file = "prometheus_client-0.11.0-py2.py3-none-any.whl", hash = "sha256:b014bc76815eb1399da8ce5fc84b7717a3e63652b0c0f8804092c9363acab1b2"},
-    {file = "prometheus_client-0.11.0.tar.gz", hash = "sha256:3a8baade6cb80bcfe43297e33e7623f3118d660d41387593758e2fb1ea173a86"},
-]
-prompt-toolkit = [
-    {file = "prompt_toolkit-3.0.21-py3-none-any.whl", hash = "sha256:62b3d3ea5a3ccee94dc1aac018279cf64866a76837156ebe159b981c42dd20a8"},
-    {file = "prompt_toolkit-3.0.21.tar.gz", hash = "sha256:27f13ff4e4850fe8f860b77414c7880f67c6158076a7b099062cc8570f1562e5"},
-]
-psutil = [
-    {file = "psutil-5.8.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64"},
-    {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c"},
-    {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df"},
-    {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131"},
-    {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60"},
-    {file = "psutil-5.8.0-cp27-none-win32.whl", hash = "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876"},
-    {file = "psutil-5.8.0-cp27-none-win_amd64.whl", hash = "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65"},
-    {file = "psutil-5.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8"},
-    {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6"},
-    {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac"},
-    {file = "psutil-5.8.0-cp36-cp36m-win32.whl", hash = "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2"},
-    {file = "psutil-5.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d"},
-    {file = "psutil-5.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935"},
-    {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d"},
-    {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023"},
-    {file = "psutil-5.8.0-cp37-cp37m-win32.whl", hash = "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394"},
-    {file = "psutil-5.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563"},
-    {file = "psutil-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef"},
-    {file = "psutil-5.8.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28"},
-    {file = "psutil-5.8.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b"},
-    {file = "psutil-5.8.0-cp38-cp38-win32.whl", hash = "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d"},
-    {file = "psutil-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d"},
-    {file = "psutil-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7"},
-    {file = "psutil-5.8.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4"},
-    {file = "psutil-5.8.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b"},
-    {file = "psutil-5.8.0-cp39-cp39-win32.whl", hash = "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0"},
-    {file = "psutil-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3"},
-    {file = "psutil-5.8.0.tar.gz", hash = "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6"},
-]
-psycopg2 = [
-    {file = "psycopg2-2.9.1-cp36-cp36m-win32.whl", hash = "sha256:7f91312f065df517187134cce8e395ab37f5b601a42446bdc0f0d51773621854"},
-    {file = "psycopg2-2.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:830c8e8dddab6b6716a4bf73a09910c7954a92f40cf1d1e702fb93c8a919cc56"},
-    {file = "psycopg2-2.9.1-cp37-cp37m-win32.whl", hash = "sha256:89409d369f4882c47f7ea20c42c5046879ce22c1e4ea20ef3b00a4dfc0a7f188"},
-    {file = "psycopg2-2.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7640e1e4d72444ef012e275e7b53204d7fab341fb22bc76057ede22fe6860b25"},
-    {file = "psycopg2-2.9.1-cp38-cp38-win32.whl", hash = "sha256:079d97fc22de90da1d370c90583659a9f9a6ee4007355f5825e5f1c70dffc1fa"},
-    {file = "psycopg2-2.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:2c992196719fadda59f72d44603ee1a2fdcc67de097eea38d41c7ad9ad246e62"},
-    {file = "psycopg2-2.9.1-cp39-cp39-win32.whl", hash = "sha256:2087013c159a73e09713294a44d0c8008204d06326006b7f652bef5ace66eebb"},
-    {file = "psycopg2-2.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:bf35a25f1aaa8a3781195595577fcbb59934856ee46b4f252f56ad12b8043bcf"},
-    {file = "psycopg2-2.9.1.tar.gz", hash = "sha256:de5303a6f1d0a7a34b9d40e4d3bef684ccc44a49bbe3eb85e3c0bffb4a131b7c"},
-]
-ptyprocess = [
-    {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
-    {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
-]
-py = [
-    {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"},
-    {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"},
-]
-pycodestyle = [
-    {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
-    {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
-]
-pycparser = [
-    {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
-    {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
-]
-pycryptodome = [
-    {file = "pycryptodome-3.11.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ffd0cac13ff41f2d15ed39dc6ba1d2ad88dd2905d656c33d8235852f5d6151fd"},
-    {file = "pycryptodome-3.11.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:ead516e03dfe062aefeafe4a29445a6449b0fc43bc8cb30194b2754917a63798"},
-    {file = "pycryptodome-3.11.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4ce6b09547bf2c7cede3a017f79502eaed3e819c13cdb3cb357aea1b004e4cc6"},
-    {file = "pycryptodome-3.11.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:014c758af7fa38cab85b357a496b76f4fc9dda1f731eb28358d66fef7ad4a3e1"},
-    {file = "pycryptodome-3.11.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a843350d08c3d22f6c09c2f17f020d8dcfa59496165d7425a3fba0045543dda7"},
-    {file = "pycryptodome-3.11.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:53989477044be41fa4a63da09d5038c2a34b2f4554cfea2e3933b17186ee9e19"},
-    {file = "pycryptodome-3.11.0-cp27-cp27m-win32.whl", hash = "sha256:f9bad2220b80b4ed74f089db012ab5ab5419143a33fad6c8aedcc2a9341eac70"},
-    {file = "pycryptodome-3.11.0-cp27-cp27m-win_amd64.whl", hash = "sha256:3c7ed5b07274535979c730daf5817db5e983ea80b04c22579eee8da4ca3ae4f8"},
-    {file = "pycryptodome-3.11.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:8f3a60926be78422e662b0d0b18351b426ce27657101c8a50bad80300de6a701"},
-    {file = "pycryptodome-3.11.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:fce7e22d96030b35345637c563246c24d4513bd3b413e1c40293114837ab8912"},
-    {file = "pycryptodome-3.11.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:bc3c61ff92efdcc14af4a7b81da71d849c9acee51d8fd8ac9841a7620140d6c6"},
-    {file = "pycryptodome-3.11.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:b33c9b3d1327d821e28e9cc3a6512c14f8b17570ddb4cfb9a52247ed0fcc5d8b"},
-    {file = "pycryptodome-3.11.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:75e78360d1dd6d02eb288fd8275bb4d147d6e3f5337935c096d11dba1fa84748"},
-    {file = "pycryptodome-3.11.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:621a90147a5e255fdc2a0fec2d56626b76b5d72ea9e60164c9a5a8976d45b0c9"},
-    {file = "pycryptodome-3.11.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:0ca7a6b4fc1f9fafe990b95c8cda89099797e2cfbf40e55607f2f2f5a3355dcb"},
-    {file = "pycryptodome-3.11.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:b59bf823cfafde8ef1105d8984f26d1694dff165adb7198b12e3e068d7999b15"},
-    {file = "pycryptodome-3.11.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:ce81b9c6aaa0f920e2ab05eb2b9f4ccd102e3016b2f37125593b16a83a4b0cc2"},
-    {file = "pycryptodome-3.11.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:ae29fcd56152f417bfba50a36a56a7a5f9fb74ff80bab98704cac704de6568ab"},
-    {file = "pycryptodome-3.11.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:ae31cb874f6f0cedbed457c6374e7e54d7ed45c1a4e11a65a9c80968da90a650"},
-    {file = "pycryptodome-3.11.0-cp35-abi3-win32.whl", hash = "sha256:6db1f9fa1f52226621905f004278ce7bd90c8f5363ffd5d7ab3755363d98549a"},
-    {file = "pycryptodome-3.11.0-cp35-abi3-win_amd64.whl", hash = "sha256:d7e5f6f692421e5219aa3b545eb0cffd832cd589a4b9dcd4a5eb4260e2c0d68a"},
-    {file = "pycryptodome-3.11.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:da796e9221dda61a0019d01742337eb8a322de8598b678a4344ca0a436380315"},
-    {file = "pycryptodome-3.11.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:ed45ef92d21db33685b789de2c015e9d9a18a74760a8df1fc152faee88cdf741"},
-    {file = "pycryptodome-3.11.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:4169ed515742425ff21e4bd3fabbb6994ffb64434472fb72230019bdfa36b939"},
-    {file = "pycryptodome-3.11.0-pp27-pypy_73-win32.whl", hash = "sha256:f19edd42368e9057c39492947bb99570dc927123e210008f2af7cf9b505c6892"},
-    {file = "pycryptodome-3.11.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:06162fcfed2f9deee8383fd59eaeabc7b7ffc3af50d3fad4000032deb8f700b0"},
-    {file = "pycryptodome-3.11.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:6eda8a3157c91ba60b26a07bedd6c44ab8bda6cd79b6b5ea9744ba62c39b7b1e"},
-    {file = "pycryptodome-3.11.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:7ff701fc283412e651eaab4319b3cd4eaa0827e94569cd37ee9075d5c05fe655"},
-    {file = "pycryptodome-3.11.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:2a4bcc8a9977fee0979079cd33a9e9f0d3ddba5660d35ffe874cf84f1dd399d2"},
-    {file = "pycryptodome-3.11.0.tar.gz", hash = "sha256:428096bbf7a77e207f418dfd4d7c284df8ade81d2dc80f010e92753a3e406ad0"},
-]
-pydocstyle = [
-    {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"},
-    {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"},
-]
-pyflakes = [
-    {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
-    {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
-]
-pygments = [
-    {file = "Pygments-2.10.0-py3-none-any.whl", hash = "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380"},
-    {file = "Pygments-2.10.0.tar.gz", hash = "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"},
-]
-pyjwt = [
-    {file = "PyJWT-2.3.0-py3-none-any.whl", hash = "sha256:e0c4bb8d9f0af0c7f5b1ec4c5036309617d03d56932877f2f7a0beeb5318322f"},
-    {file = "PyJWT-2.3.0.tar.gz", hash = "sha256:b888b4d56f06f6dcd777210c334e69c737be74755d3e5e9ee3fe67dc18a0ee41"},
-]
-pyparsing = [
-    {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
-    {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
-]
-pytest = [
-    {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
-    {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
-]
-pytest-cov = [
-    {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"},
-    {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"},
-]
-pytest-django = [
-    {file = "pytest-django-4.4.0.tar.gz", hash = "sha256:b5171e3798bf7e3fc5ea7072fe87324db67a4dd9f1192b037fed4cc3c1b7f455"},
-    {file = "pytest_django-4.4.0-py3-none-any.whl", hash = "sha256:65783e78382456528bd9d79a35843adde9e6a47347b20464eb2c885cb0f1f606"},
-]
-pytest-django-testing-postgresql = [
-    {file = "pytest-django-testing-postgresql-0.1.post0.tar.gz", hash = "sha256:78b0c58930084cb4393407b2e5a2a3b8734c627b841ecef7d62d39bbfb8e8a45"},
-    {file = "pytest_django_testing_postgresql-0.1.post0-py3-none-any.whl", hash = "sha256:78e52e3d1b0ef5f906d5d69247dd6ac7dfb10d840bd81abab92f3f8c30872cd3"},
-]
-pytest-sugar = [
-    {file = "pytest-sugar-0.9.4.tar.gz", hash = "sha256:b1b2186b0a72aada6859bea2a5764145e3aaa2c1cfbb23c3a19b5f7b697563d3"},
-]
-python-crontab = [
-    {file = "python-crontab-2.6.0.tar.gz", hash = "sha256:1e35ed7a3cdc3100545b43e196d34754e6551e7f95e4caebbe0e1c0ca41c2f1b"},
-]
-python-dateutil = [
-    {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
-    {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
-]
-python-gnupg = [
-    {file = "python-gnupg-0.4.7.tar.gz", hash = "sha256:2061f56b1942c29b92727bf9aecbd3cea3893acc9cccbdc7eb4604285efe4ac7"},
-    {file = "python_gnupg-0.4.7-py2.py3-none-any.whl", hash = "sha256:3ff5b1bf5e397de6e1fe41a7c0f403dad4e242ac92b345f440eaecfb72a7ebae"},
-]
-python3-openid = [
-    {file = "python3-openid-3.2.0.tar.gz", hash = "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf"},
-    {file = "python3_openid-3.2.0-py3-none-any.whl", hash = "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b"},
-]
-pytz = [
-    {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
-    {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
-]
-pyyaml = [
-    {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
-    {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
-    {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
-    {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
-    {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
-    {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
-    {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
-    {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
-    {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
-    {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
-    {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
-    {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
-    {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
-    {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
-    {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
-    {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
-    {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
-    {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
-]
-qrcode = [
-    {file = "qrcode-6.1-py2.py3-none-any.whl", hash = "sha256:3996ee560fc39532910603704c82980ff6d4d5d629f9c3f25f34174ce8606cf5"},
-    {file = "qrcode-6.1.tar.gz", hash = "sha256:505253854f607f2abf4d16092c61d4e9d511a3b4392e60bff957a68592b04369"},
-]
-redis = [
-    {file = "redis-3.5.3-py2.py3-none-any.whl", hash = "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24"},
-    {file = "redis-3.5.3.tar.gz", hash = "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2"},
-]
-regex = [
-    {file = "regex-2021.10.23-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:45b65d6a275a478ac2cbd7fdbf7cc93c1982d613de4574b56fd6972ceadb8395"},
-    {file = "regex-2021.10.23-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74d071dbe4b53c602edd87a7476ab23015a991374ddb228d941929ad7c8c922e"},
-    {file = "regex-2021.10.23-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:34d870f9f27f2161709054d73646fc9aca49480617a65533fc2b4611c518e455"},
-    {file = "regex-2021.10.23-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fb698037c35109d3c2e30f2beb499e5ebae6e4bb8ff2e60c50b9a805a716f79"},
-    {file = "regex-2021.10.23-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb46b542133999580ffb691baf67410306833ee1e4f58ed06b6a7aaf4e046952"},
-    {file = "regex-2021.10.23-cp310-cp310-win32.whl", hash = "sha256:5e9c9e0ce92f27cef79e28e877c6b6988c48b16942258f3bc55d39b5f911df4f"},
-    {file = "regex-2021.10.23-cp310-cp310-win_amd64.whl", hash = "sha256:ab7c5684ff3538b67df3f93d66bd3369b749087871ae3786e70ef39e601345b0"},
-    {file = "regex-2021.10.23-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:de557502c3bec8e634246588a94e82f1ee1b9dfcfdc453267c4fb652ff531570"},
-    {file = "regex-2021.10.23-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee684f139c91e69fe09b8e83d18b4d63bf87d9440c1eb2eeb52ee851883b1b29"},
-    {file = "regex-2021.10.23-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5095a411c8479e715784a0c9236568ae72509450ee2226b649083730f3fadfc6"},
-    {file = "regex-2021.10.23-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b568809dca44cb75c8ebb260844ea98252c8c88396f9d203f5094e50a70355f"},
-    {file = "regex-2021.10.23-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eb672217f7bd640411cfc69756ce721d00ae600814708d35c930930f18e8029f"},
-    {file = "regex-2021.10.23-cp36-cp36m-win32.whl", hash = "sha256:a7a986c45d1099a5de766a15de7bee3840b1e0e1a344430926af08e5297cf666"},
-    {file = "regex-2021.10.23-cp36-cp36m-win_amd64.whl", hash = "sha256:6d7722136c6ed75caf84e1788df36397efdc5dbadab95e59c2bba82d4d808a4c"},
-    {file = "regex-2021.10.23-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9f665677e46c5a4d288ece12fdedf4f4204a422bb28ff05f0e6b08b7447796d1"},
-    {file = "regex-2021.10.23-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:450dc27483548214314640c89a0f275dbc557968ed088da40bde7ef8fb52829e"},
-    {file = "regex-2021.10.23-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:129472cd06062fb13e7b4670a102951a3e655e9b91634432cfbdb7810af9d710"},
-    {file = "regex-2021.10.23-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a940ca7e7189d23da2bfbb38973832813eab6bd83f3bf89a977668c2f813deae"},
-    {file = "regex-2021.10.23-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:530fc2bbb3dc1ebb17f70f7b234f90a1dd43b1b489ea38cea7be95fb21cdb5c7"},
-    {file = "regex-2021.10.23-cp37-cp37m-win32.whl", hash = "sha256:ded0c4a3eee56b57fcb2315e40812b173cafe79d2f992d50015f4387445737fa"},
-    {file = "regex-2021.10.23-cp37-cp37m-win_amd64.whl", hash = "sha256:391703a2abf8013d95bae39145d26b4e21531ab82e22f26cd3a181ee2644c234"},
-    {file = "regex-2021.10.23-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be04739a27be55631069b348dda0c81d8ea9822b5da10b8019b789e42d1fe452"},
-    {file = "regex-2021.10.23-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13ec99df95003f56edcd307db44f06fbeb708c4ccdcf940478067dd62353181e"},
-    {file = "regex-2021.10.23-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d1cdcda6bd16268316d5db1038965acf948f2a6f43acc2e0b1641ceab443623"},
-    {file = "regex-2021.10.23-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c186691a7995ef1db61205e00545bf161fb7b59cdb8c1201c89b333141c438a"},
-    {file = "regex-2021.10.23-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b20f544cbbeffe171911f6ce90388ad36fe3fad26b7c7a35d4762817e9ea69c"},
-    {file = "regex-2021.10.23-cp38-cp38-win32.whl", hash = "sha256:c0938ddd60cc04e8f1faf7a14a166ac939aac703745bfcd8e8f20322a7373019"},
-    {file = "regex-2021.10.23-cp38-cp38-win_amd64.whl", hash = "sha256:56f0c81c44638dfd0e2367df1a331b4ddf2e771366c4b9c5d9a473de75e3e1c7"},
-    {file = "regex-2021.10.23-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80bb5d2e92b2258188e7dcae5b188c7bf868eafdf800ea6edd0fbfc029984a88"},
-    {file = "regex-2021.10.23-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1dae12321b31059a1a72aaa0e6ba30156fe7e633355e445451e4021b8e122b6"},
-    {file = "regex-2021.10.23-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1f2b59c28afc53973d22e7bc18428721ee8ca6079becf1b36571c42627321c65"},
-    {file = "regex-2021.10.23-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d134757a37d8640f3c0abb41f5e68b7cf66c644f54ef1cb0573b7ea1c63e1509"},
-    {file = "regex-2021.10.23-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0dcc0e71118be8c69252c207630faf13ca5e1b8583d57012aae191e7d6d28b84"},
-    {file = "regex-2021.10.23-cp39-cp39-win32.whl", hash = "sha256:a30513828180264294953cecd942202dfda64e85195ae36c265daf4052af0464"},
-    {file = "regex-2021.10.23-cp39-cp39-win_amd64.whl", hash = "sha256:0f7552429dd39f70057ac5d0e897e5bfe211629652399a21671e53f2a9693a4e"},
-    {file = "regex-2021.10.23.tar.gz", hash = "sha256:f3f9a91d3cc5e5b0ddf1043c0ae5fa4852f18a1c0050318baf5fc7930ecc1f9c"},
-]
-requests = [
-    {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"},
-    {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"},
-]
-requests-oauthlib = [
-    {file = "requests-oauthlib-1.3.0.tar.gz", hash = "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"},
-    {file = "requests_oauthlib-1.3.0-py2.py3-none-any.whl", hash = "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d"},
-    {file = "requests_oauthlib-1.3.0-py3.7.egg", hash = "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc"},
-]
-restructuredtext-lint = [
-    {file = "restructuredtext_lint-1.3.2.tar.gz", hash = "sha256:d3b10a1fe2ecac537e51ae6d151b223b78de9fafdd50e5eb6b08c243df173c80"},
-]
-"ruamel.yaml" = [
-    {file = "ruamel.yaml-0.17.16-py3-none-any.whl", hash = "sha256:ea21da1198c4b41b8e7a259301cc9710d3b972bf8ba52f06218478e6802dd1f1"},
-    {file = "ruamel.yaml-0.17.16.tar.gz", hash = "sha256:1a771fc92d3823682b7f0893ad56cb5a5c87c48e62b5399d6f42c8759a583b33"},
-]
-"ruamel.yaml.clib" = [
-    {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:cfdb9389d888c5b74af297e51ce357b800dd844898af9d4a547ffc143fa56751"},
-    {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7b2927e92feb51d830f531de4ccb11b320255ee95e791022555971c466af4527"},
-    {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win32.whl", hash = "sha256:ada3f400d9923a190ea8b59c8f60680c4ef8a4b0dfae134d2f2ff68429adfab5"},
-    {file = "ruamel.yaml.clib-0.2.6-cp35-cp35m-win_amd64.whl", hash = "sha256:de9c6b8a1ba52919ae919f3ae96abb72b994dd0350226e28f3686cb4f142165c"},
-    {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d67f273097c368265a7b81e152e07fb90ed395df6e552b9fa858c6d2c9f42502"},
-    {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:72a2b8b2ff0a627496aad76f37a652bcef400fd861721744201ef1b45199ab78"},
-    {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win32.whl", hash = "sha256:9efef4aab5353387b07f6b22ace0867032b900d8e91674b5d8ea9150db5cae94"},
-    {file = "ruamel.yaml.clib-0.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:846fc8336443106fe23f9b6d6b8c14a53d38cef9a375149d61f99d78782ea468"},
-    {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0847201b767447fc33b9c235780d3aa90357d20dd6108b92be544427bea197dd"},
-    {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:78988ed190206672da0f5d50c61afef8f67daa718d614377dcd5e3ed85ab4a99"},
-    {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win32.whl", hash = "sha256:a49e0161897901d1ac9c4a79984b8410f450565bbad64dbfcbf76152743a0cdb"},
-    {file = "ruamel.yaml.clib-0.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bf75d28fa071645c529b5474a550a44686821decebdd00e21127ef1fd566eabe"},
-    {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a32f8d81ea0c6173ab1b3da956869114cae53ba1e9f72374032e33ba3118c233"},
-    {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7f7ecb53ae6848f959db6ae93bdff1740e651809780822270eab111500842a84"},
-    {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win32.whl", hash = "sha256:89221ec6d6026f8ae859c09b9718799fea22c0e8da8b766b0b2c9a9ba2db326b"},
-    {file = "ruamel.yaml.clib-0.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:31ea73e564a7b5fbbe8188ab8b334393e06d997914a4e184975348f204790277"},
-    {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc6a613d6c74eef5a14a214d433d06291526145431c3b964f5e16529b1842bed"},
-    {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1866cf2c284a03b9524a5cc00daca56d80057c5ce3cdc86a52020f4c720856f0"},
-    {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win32.whl", hash = "sha256:3fb9575a5acd13031c57a62cc7823e5d2ff8bc3835ba4d94b921b4e6ee664104"},
-    {file = "ruamel.yaml.clib-0.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:825d5fccef6da42f3c8eccd4281af399f21c02b32d98e113dbc631ea6a6ecbc7"},
-    {file = "ruamel.yaml.clib-0.2.6.tar.gz", hash = "sha256:4ff604ce439abb20794f05613c374759ce10e3595d1867764dd1ae675b85acbd"},
-]
-rules = [
-    {file = "rules-2.2.tar.gz", hash = "sha256:9bae429f9d4f91a375402990da1541f9e093b0ac077221d57124d06eeeca4405"},
-]
-safety = [
-    {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"},
-    {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"},
-]
-scramp = [
-    {file = "scramp-1.4.1-py3-none-any.whl", hash = "sha256:93c9cc2ffe54a451e02981c07a5a23cbd830701102789939cfb4ff91efd6ca8c"},
-    {file = "scramp-1.4.1.tar.gz", hash = "sha256:f964801077be9be2a1416ffe255d2d78834b3d9d5c8ce5d28f76a856f209f70e"},
-]
-selenium = [
-    {file = "selenium-3.141.0-py2.py3-none-any.whl", hash = "sha256:2d7131d7bc5a5b99a2d9b04aaf2612c411b03b8ca1b1ee8d3de5845a9be2cb3c"},
-    {file = "selenium-3.141.0.tar.gz", hash = "sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d"},
-]
-six = [
-    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
-    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
-]
-smmap = [
-    {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"},
-    {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"},
-]
-snowballstemmer = [
-    {file = "snowballstemmer-2.1.0-py2.py3-none-any.whl", hash = "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2"},
-    {file = "snowballstemmer-2.1.0.tar.gz", hash = "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914"},
-]
-soupsieve = [
-    {file = "soupsieve-2.2.1-py3-none-any.whl", hash = "sha256:c2c1c2d44f158cdbddab7824a9af8c4f83c76b1e23e049479aa432feb6c4c23b"},
-    {file = "soupsieve-2.2.1.tar.gz", hash = "sha256:052774848f448cf19c7e959adf5566904d525f33a3f8b6ba6f6f8f26ec7de0cc"},
-]
-spdx-license-list = [
-    {file = "spdx_license_list-0.5.2-py3-none-any.whl", hash = "sha256:1b338470c7b403dbecceca563a316382c7977516128ca6c1e8f7078e3ed6e7b0"},
-    {file = "spdx_license_list-0.5.2.tar.gz", hash = "sha256:952996f72ab807972dc2278bb9b91e5294767211e51f09aad9c0e2ff5b82a31b"},
-]
-sphinx = [
-    {file = "Sphinx-3.5.4-py3-none-any.whl", hash = "sha256:2320d4e994a191f4b4be27da514e46b3d6b420f2ff895d064f52415d342461e8"},
-    {file = "Sphinx-3.5.4.tar.gz", hash = "sha256:19010b7b9fa0dc7756a6e105b2aacd3a80f798af3c25c273be64d7beeb482cb1"},
-]
-sphinx-autodoc-typehints = [
-    {file = "sphinx-autodoc-typehints-1.12.0.tar.gz", hash = "sha256:193617d9dbe0847281b1399d369e74e34cd959c82e02c7efde077fca908a9f52"},
-    {file = "sphinx_autodoc_typehints-1.12.0-py3-none-any.whl", hash = "sha256:5e81776ec422dd168d688ab60f034fccfafbcd94329e9537712c93003bddc04a"},
-]
-sphinx-materialdesign-theme = [
-    {file = "sphinx_materialdesign_theme-0.1.11.tar.gz", hash = "sha256:6e9dae4c6e5ba23c0657a94c1cf65f64be9c8bc1594a6fb41815f7daa3326aa9"},
-]
-sphinxcontrib-applehelp = [
-    {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"},
-    {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"},
-]
-sphinxcontrib-devhelp = [
-    {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
-    {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
-]
-sphinxcontrib-django = [
-    {file = "sphinxcontrib-django-0.5.1.tar.gz", hash = "sha256:3b48a9067d8db4713d47e3a4160af10288d02d448c866d1b44b001adbe74cc1e"},
-    {file = "sphinxcontrib_django-0.5.1-py2.py3-none-any.whl", hash = "sha256:73ef7fdbf2ed6d4f35b7ae709032bd5ac493d93cedd0624ea7b51bf5fce41267"},
-]
-sphinxcontrib-htmlhelp = [
-    {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"},
-    {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"},
-]
-sphinxcontrib-jsmath = [
-    {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
-    {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
-]
-sphinxcontrib-qthelp = [
-    {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
-    {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
-]
-sphinxcontrib-serializinghtml = [
-    {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
-    {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
-]
-sqlparse = [
-    {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"},
-    {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"},
-]
-stevedore = [
-    {file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"},
-    {file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"},
-]
-termcolor = [
-    {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"},
-]
-testfixtures = [
-    {file = "testfixtures-6.18.3-py2.py3-none-any.whl", hash = "sha256:6ddb7f56a123e1a9339f130a200359092bd0a6455e31838d6c477e8729bb7763"},
-    {file = "testfixtures-6.18.3.tar.gz", hash = "sha256:2600100ae96ffd082334b378e355550fef8b4a529a6fa4c34f47130905c7426d"},
-]
-"testing.common.database" = [
-    {file = "testing.common.database-2.0.3-py2.py3-none-any.whl", hash = "sha256:e3ed492bf480a87f271f74c53b262caf5d85c8bc09989a8f534fa2283ec52492"},
-    {file = "testing.common.database-2.0.3.tar.gz", hash = "sha256:965d80b2985315325dc358c3061b174a712f4d4d5bf6a80b58b11f9a1dd86d73"},
-]
-"testing.postgresql" = [
-    {file = "testing.postgresql-1.3.0-py2.py3-none-any.whl", hash = "sha256:1b41daeb98dfc8cd4a584bb91e8f5f4ab182993870f95257afe5f1ba6151a598"},
-    {file = "testing.postgresql-1.3.0.tar.gz", hash = "sha256:8e1a69760369a7a8ffe63a66b6d95a5cd82db2fb976e4a8f85ffd24fbfc447d8"},
-]
-toml = [
-    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
-    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
-]
-traitlets = [
-    {file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"},
-    {file = "traitlets-5.1.1.tar.gz", hash = "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7"},
-]
-twilio = [
-    {file = "twilio-7.2.0.tar.gz", hash = "sha256:f99643641c193fcd09b58f20ef65a78937e5c426319530a42c325b3abd80e739"},
-]
-typed-ast = [
-    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"},
-    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"},
-    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"},
-    {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"},
-    {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"},
-    {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"},
-    {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"},
-    {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"},
-    {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"},
-    {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"},
-    {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"},
-    {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"},
-    {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"},
-    {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"},
-    {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"},
-    {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"},
-    {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"},
-    {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"},
-    {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"},
-    {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"},
-]
-types-pytz = [
-    {file = "types-pytz-2021.3.0.tar.gz", hash = "sha256:86a61967834dceeaaf98b6902ed8357efdd262bb8afcaf4bc8ccecf748592778"},
-    {file = "types_pytz-2021.3.0-py3-none-any.whl", hash = "sha256:b5027e5de50a4c978cd60ca16849d934d44c44ebd7d29cf13ada009efaa9feef"},
-]
-types-pyyaml = [
-    {file = "types-PyYAML-6.0.0.tar.gz", hash = "sha256:3d3591ddfc488fc30be3c506a0c0fe54da968fe98d8b76ab12e59d455330ffca"},
-    {file = "types_PyYAML-6.0.0-py3-none-any.whl", hash = "sha256:746f23d351245d176d7bc89eef79e2ee94b4e7306f7d23bfefb3dc946c0fb58d"},
-]
-typing-extensions = [
-    {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"},
-    {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"},
-    {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"},
-]
-urllib3 = [
-    {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
-    {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"},
-]
-vine = [
-    {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"},
-    {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"},
-]
-wcwidth = [
-    {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
-    {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
-]
-webencodings = [
-    {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
-    {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
-]
-whoosh = [
-    {file = "Whoosh-2.7.4-py2.py3-none-any.whl", hash = "sha256:aa39c3c3426e3fd107dcb4bde64ca1e276a65a889d9085a6e4b54ba82420a852"},
-    {file = "Whoosh-2.7.4.tar.gz", hash = "sha256:7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83"},
-    {file = "Whoosh-2.7.4.zip", hash = "sha256:e0857375f63e9041e03fedd5b7541f97cf78917ac1b6b06c1fcc9b45375dda69"},
-]
-wrapt = [
-    {file = "wrapt-1.13.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3de7b4d3066cc610054e7aa2c005645e308df2f92be730aae3a47d42e910566a"},
-    {file = "wrapt-1.13.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:8164069f775c698d15582bf6320a4f308c50d048c1c10cf7d7a341feaccf5df7"},
-    {file = "wrapt-1.13.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9adee1891253670575028279de8365c3a02d3489a74a66d774c321472939a0b1"},
-    {file = "wrapt-1.13.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:a70d876c9aba12d3bd7f8f1b05b419322c6789beb717044eea2c8690d35cb91b"},
-    {file = "wrapt-1.13.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3f87042623530bcffea038f824b63084180513c21e2e977291a9a7e65a66f13b"},
-    {file = "wrapt-1.13.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e634136f700a21e1fcead0c137f433dde928979538c14907640607d43537d468"},
-    {file = "wrapt-1.13.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3e33c138d1e3620b1e0cc6fd21e46c266393ed5dae0d595b7ed5a6b73ed57aa0"},
-    {file = "wrapt-1.13.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:283e402e5357e104ac1e3fba5791220648e9af6fb14ad7d9cc059091af2b31d2"},
-    {file = "wrapt-1.13.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ccb34ce599cab7f36a4c90318697ead18312c67a9a76327b3f4f902af8f68ea1"},
-    {file = "wrapt-1.13.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:fbad5ba74c46517e6488149514b2e2348d40df88cd6b52a83855b7a8bf04723f"},
-    {file = "wrapt-1.13.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:724ed2bc9c91a2b9026e5adce310fa60c6e7c8760b03391445730b9789b9d108"},
-    {file = "wrapt-1.13.2-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:83f2793ec6f3ef513ad8d5b9586f5ee6081cad132e6eae2ecb7eac1cc3decae0"},
-    {file = "wrapt-1.13.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:0473d1558b93e314e84313cc611f6c86be779369f9d3734302bf185a4d2625b1"},
-    {file = "wrapt-1.13.2-cp35-cp35m-win32.whl", hash = "sha256:15eee0e6fd07f48af2f66d0e6f2ff1916ffe9732d464d5e2390695296872cad9"},
-    {file = "wrapt-1.13.2-cp35-cp35m-win_amd64.whl", hash = "sha256:bc85d17d90201afd88e3d25421da805e4e135012b5d1f149e4de2981394b2a52"},
-    {file = "wrapt-1.13.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6ee5f8734820c21b9b8bf705e99faba87f21566d20626568eeb0d62cbeaf23c"},
-    {file = "wrapt-1.13.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:53c6706a1bcfb6436f1625511b95b812798a6d2ccc51359cd791e33722b5ea32"},
-    {file = "wrapt-1.13.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fbe6aebc9559fed7ea27de51c2bf5c25ba2a4156cf0017556f72883f2496ee9a"},
-    {file = "wrapt-1.13.2-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:0582180566e7a13030f896c2f1ac6a56134ab5f3c3f4c5538086f758b1caf3f2"},
-    {file = "wrapt-1.13.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:bff0a59387a0a2951cb869251257b6553663329a1b5525b5226cab8c88dcbe7e"},
-    {file = "wrapt-1.13.2-cp36-cp36m-win32.whl", hash = "sha256:df3eae297a5f1594d1feb790338120f717dac1fa7d6feed7b411f87e0f2401c7"},
-    {file = "wrapt-1.13.2-cp36-cp36m-win_amd64.whl", hash = "sha256:1eb657ed84f4d3e6ad648483c8a80a0cf0a78922ef94caa87d327e2e1ad49b48"},
-    {file = "wrapt-1.13.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0cdedf681db878416c05e1831ec69691b0e6577ac7dca9d4f815632e3549580"},
-    {file = "wrapt-1.13.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:87ee3c73bdfb4367b26c57259995935501829f00c7b3eed373e2ad19ec21e4e4"},
-    {file = "wrapt-1.13.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3e0d16eedc242d01a6f8cf0623e9cdc3b869329da3f97a15961d8864111d8cf0"},
-    {file = "wrapt-1.13.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:8318088860968c07e741537030b1abdd8908ee2c71fbe4facdaade624a09e006"},
-    {file = "wrapt-1.13.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d90520616fce71c05dedeac3a0fe9991605f0acacd276e5f821842e454485a70"},
-    {file = "wrapt-1.13.2-cp37-cp37m-win32.whl", hash = "sha256:22142afab65daffc95863d78effcbd31c19a8003eca73de59f321ee77f73cadb"},
-    {file = "wrapt-1.13.2-cp37-cp37m-win_amd64.whl", hash = "sha256:d0d717e10f952df7ea41200c507cc7e24458f4c45b56c36ad418d2e79dacd1d4"},
-    {file = "wrapt-1.13.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:593cb049ce1c391e0288523b30426c4430b26e74c7e6f6e2844bd99ac7ecc831"},
-    {file = "wrapt-1.13.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:8860c8011a6961a651b1b9f46fdbc589ab63b0a50d645f7d92659618a3655867"},
-    {file = "wrapt-1.13.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ada5e29e59e2feb710589ca1c79fd989b1dd94d27079dc1d199ec954a6ecc724"},
-    {file = "wrapt-1.13.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:fdede980273aeca591ad354608778365a3a310e0ecdd7a3587b38bc5be9b1808"},
-    {file = "wrapt-1.13.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:af9480de8e63c5f959a092047aaf3d7077422ded84695b3398f5d49254af3e90"},
-    {file = "wrapt-1.13.2-cp38-cp38-win32.whl", hash = "sha256:c65e623ea7556e39c4f0818200a046cbba7575a6b570ff36122c276fdd30ab0a"},
-    {file = "wrapt-1.13.2-cp38-cp38-win_amd64.whl", hash = "sha256:b20703356cae1799080d0ad15085dc3213c1ac3f45e95afb9f12769b98231528"},
-    {file = "wrapt-1.13.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c5c4cf188b5643a97e87e2110bbd4f5bc491d54a5b90633837b34d5df6a03fe"},
-    {file = "wrapt-1.13.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:82223f72eba6f63eafca87a0f614495ae5aa0126fe54947e2b8c023969e9f2d7"},
-    {file = "wrapt-1.13.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81a4cf257263b299263472d669692785f9c647e7dca01c18286b8f116dbf6b38"},
-    {file = "wrapt-1.13.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:728e2d9b7a99dd955d3426f237b940fc74017c4a39b125fec913f575619ddfe9"},
-    {file = "wrapt-1.13.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7574de567dcd4858a2ffdf403088d6df8738b0e1eabea220553abf7c9048f59e"},
-    {file = "wrapt-1.13.2-cp39-cp39-win32.whl", hash = "sha256:c7ac2c7a8e34bd06710605b21dd1f3576764443d68e069d2afba9b116014d072"},
-    {file = "wrapt-1.13.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e6d1a8eeef415d7fb29fe017de0e48f45e45efd2d1bfda28fc50b7b330859ef"},
-    {file = "wrapt-1.13.2.tar.gz", hash = "sha256:dca56cc5963a5fd7c2aa8607017753f534ee514e09103a6c55d2db70b50e7447"},
-]
-yubiotp = [
-    {file = "YubiOTP-1.0.0.post1-py2.py3-none-any.whl", hash = "sha256:7ad57011866e0bc6c6d179ffbc3926fcc0e82d410178a6d01ba4da0f88332878"},
-    {file = "YubiOTP-1.0.0.post1.tar.gz", hash = "sha256:c13825f7b76a69afb92f19521f4dea9f5031d70f45123b505dc2e0ac03132065"},
-]
diff --git a/pyproject.toml b/pyproject.toml
index 7c6901b62ff728fe123f52aeac0e7d5254289931..5aaa12748af26819e63ebf590ca55c59d9e2a64e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,11 +1,18 @@
 [tool.poetry]
 name = "AlekSIS-App-Alsijil"
-version = "2.0b0"
+version = "2.0.2.dev0"
 packages = [
     { include = "aleksis" }
 ]
 readme = "README.rst"
-include = ["CHANGELOG.rst", "LICENCE.rst", "aleksis/**/*.mo"]
+include = [
+    { path = "aleksis/**/*.mo", format = ["sdist", "wheel"] },
+    { path = "*.rst", format = "sdist" },
+    { path = "docs/*", format = "sdist" },
+    { path = "docs/**/*", format = "sdist" },
+    { path = "conftest.py", format = "sdist" },
+    { path = "tox.ini", format = "sdist" }
+]
 
 description = "AlekSIS (School Information System) — App كتاب السجل (class register and school records)"
 authors = [
@@ -41,8 +48,8 @@ secondary = true
 
 [tool.poetry.dependencies]
 python = "^3.9"
-aleksis-core = "^2.0rc"
-aleksis-app-chronos = "^2.0rc"
+aleksis-core = "^2.7"
+aleksis-app-chronos = "^2.2"
 
 [tool.poetry.dev-dependencies]
 aleksis-builddeps = "*"
diff --git a/tox.ini b/tox.ini
index 2aed3362cf7e62c15839c37ec5fb191dcd1a2f4d..749e0606f4f02fcbd1649627219b15850cbc0a90 100644
--- a/tox.ini
+++ b/tox.ini
@@ -47,6 +47,11 @@ commands =
     poetry run isort aleksis/
     poetry run black aleksis/
 
+[testenv:makemessages]
+commands =
+    poetry run aleksis-admin makemessages --no-wrap -e html,txt,py,email -i static -l ar -l de_DE -l fr -l nb_NO -l tr_TR -l la -l uk -l ru
+    poetry run aleksis-admin makemessages --no-wrap -d djangojs -i **/node_modules -l ar -l de_DE -l fr -l nb_NO -l tr_TR -l la -l uk -l ru
+
 [flake8]
 max_line_length = 100
 exclude = migrations,tests