diff --git a/.jshintrc b/.jshintrc index 42c7dbc103..85f5d2013a 100644 --- a/.jshintrc +++ b/.jshintrc @@ -109,10 +109,10 @@ // The parameter "predef" should remain empty for this configuration file // to remain as general as possible. "predef": [ - // jQuery globals - "jQuery", "$", - - // Underscore.js globals + // JavaScript global libraries + "Backbone", + "jQuery", + "$", "_", // RequireJS globals diff --git a/AUTHORS b/AUTHORS index 7abc50cea7..54fea9d57d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -271,3 +271,5 @@ Dmitry Viskov Brian Jacobel Sigberto Alarcon Sofiya Semenova +Alisan Tang + diff --git a/cms/celery.py b/cms/celery.py index d3a44fc6d8..e35bf4d7c1 100644 --- a/cms/celery.py +++ b/cms/celery.py @@ -5,12 +5,10 @@ and auto discover tasks in all installed django apps. Taken from: http://celery.readthedocs.org/en/latest/django/first-steps-with-django.html """ from __future__ import absolute_import - import os - from celery import Celery - from django.conf import settings +from openedx.core.lib.celery.routers import AlternateEnvironmentRouter # set the default Django settings module for the 'celery' program. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings') @@ -21,3 +19,18 @@ APP = Celery('proj') # pickle the object when using Windows. APP.config_from_object('django.conf:settings') APP.autodiscover_tasks(lambda: settings.INSTALLED_APPS) + + +class Router(AlternateEnvironmentRouter): + """ + An implementation of AlternateEnvironmentRouter, for routing tasks to non-cms queues. + """ + + @property + def alternate_env_tasks(self): + """ + Defines alternate environment tasks, as a dict of form { task_name: alternate_queue } + """ + return { + 'openedx.core.djangoapps.content.block_structure.tasks.update_course_in_cache': 'lms', + } diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index 4382c05764..0f87ced3f1 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -735,6 +735,29 @@ class MiscCourseTests(ContentStoreTestCase): # Remove tempdir shutil.rmtree(root_dir) + @mock.patch( + 'lms.djangoapps.ccx.modulestore.CCXModulestoreWrapper.get_item', + mock.Mock(return_value=mock.Mock(children=[])) + ) + def test_export_with_orphan_vertical(self): + """ + Tests that, export does not fail when a parent xblock does not have draft child xblock + information but the draft child xblock has parent information. + """ + # Make an existing unit a draft + self.store.convert_to_draft(self.problem.location, self.user.id) + root_dir = path(mkdtemp_clean()) + export_course_to_xml(self.store, None, self.course.id, root_dir, 'test_export') + + # Verify that problem is exported in the drafts. This is expected because we are + # mocking get_item to for drafts. Expect no draft is exported. + # Specifically get_item is used in `xmodule.modulestore.xml_exporter._export_drafts` + export_draft_dir = OSFS(root_dir / 'test_export/drafts') + self.assertEqual(len(export_draft_dir.listdir()), 0) + + # Remove tempdir + shutil.rmtree(root_dir) + def test_assets_overwrite(self): """ Tests that assets will similar 'displayname' will be overwritten during export """ content_store = contentstore() @@ -977,7 +1000,7 @@ class MiscCourseTests(ContentStoreTestCase): 3) computing thumbnail location of asset 4) deleting the asset from the course """ - asset_key = self.course.id.make_asset_key('asset', 'sample_static.txt') + asset_key = self.course.id.make_asset_key('asset', 'sample_static.html') content = StaticContent( asset_key, "Fake asset", "application/text", "test", ) @@ -1049,7 +1072,7 @@ class MiscCourseTests(ContentStoreTestCase): draft content is also deleted """ # add an asset - asset_key = self.course.id.make_asset_key('asset', 'sample_static.txt') + asset_key = self.course.id.make_asset_key('asset', 'sample_static.html') content = StaticContent( asset_key, "Fake asset", "application/text", "test", ) diff --git a/cms/djangoapps/contentstore/tests/test_import.py b/cms/djangoapps/contentstore/tests/test_import.py index caea0e772d..e026215f9a 100644 --- a/cms/djangoapps/contentstore/tests/test_import.py +++ b/cms/djangoapps/contentstore/tests/test_import.py @@ -172,8 +172,8 @@ class ContentStoreImportTest(SignalDisconnectTestMixin, ModuleStoreTestCase): # we try to refresh the inheritance tree for each update_item in the import with check_exact_number_of_calls(store, 'refresh_cached_metadata_inheritance_tree', 28): - # _get_cached_metadata_inheritance_tree should be called only once - with check_exact_number_of_calls(store, '_get_cached_metadata_inheritance_tree', 1): + # _get_cached_metadata_inheritance_tree should be called twice (once for import, once on publish) + with check_exact_number_of_calls(store, '_get_cached_metadata_inheritance_tree', 2): # with bulk-edit in progress, the inheritance tree should be recomputed only at the end of the import # NOTE: On Jenkins, with memcache enabled, the number of calls here is only 1. diff --git a/cms/djangoapps/contentstore/tests/utils.py b/cms/djangoapps/contentstore/tests/utils.py index 2026295c9e..af5e7b8e52 100644 --- a/cms/djangoapps/contentstore/tests/utils.py +++ b/cms/djangoapps/contentstore/tests/utils.py @@ -121,7 +121,7 @@ class CourseTestCase(ProceduralCourseTestMixin, ModuleStoreTestCase): SEQUENTIAL = 'vertical_sequential' DRAFT_HTML = 'draft_html' DRAFT_VIDEO = 'draft_video' - LOCKED_ASSET_KEY = AssetLocation.from_deprecated_string('/c4x/edX/toy/asset/sample_static.txt') + LOCKED_ASSET_KEY = AssetLocation.from_deprecated_string('/c4x/edX/toy/asset/sample_static.html') def import_and_populate_course(self): """ diff --git a/cms/djangoapps/contentstore/views/error.py b/cms/djangoapps/contentstore/views/error.py index 2eea0bc2a7..6f58ea296d 100644 --- a/cms/djangoapps/contentstore/views/error.py +++ b/cms/djangoapps/contentstore/views/error.py @@ -39,9 +39,9 @@ def server_error(request): @jsonable_error(404, "Resource not found") def render_404(request): - return HttpResponseNotFound(render_to_string('404.html', {})) + return HttpResponseNotFound(render_to_string('404.html', {}, request=request)) @jsonable_error(500, "The Studio servers encountered an error") def render_500(request): - return HttpResponseServerError(render_to_string('500.html', {})) + return HttpResponseServerError(render_to_string('500.html', {}, request=request)) diff --git a/cms/djangoapps/contentstore/views/helpers.py b/cms/djangoapps/contentstore/views/helpers.py index 60683b040c..5a0a45ca21 100644 --- a/cms/djangoapps/contentstore/views/helpers.py +++ b/cms/djangoapps/contentstore/views/helpers.py @@ -24,7 +24,7 @@ from contentstore.utils import reverse_course_url, reverse_library_url, reverse_ from models.settings.course_grading import CourseGradingModel from util.milestones_helpers import is_entrance_exams_enabled -__all__ = ['edge', 'event', 'landing'] +__all__ = ['event'] # Note: Grader types are used throughout the platform but most usages are simply in-line # strings. In addition, new grader types can be defined on the fly anytime one is needed @@ -38,16 +38,6 @@ GRADER_TYPES = { } -# points to the temporary course landing page with log in and sign up -def landing(request, org, course, coursename): - return render_to_response('temp-course-landing.html', {}) - - -# points to the temporary edge page -def edge(request): - return redirect('/') - - def event(request): ''' A noop to swallow the analytics call so that cms methods don't spook and poor developers looking at diff --git a/cms/djangoapps/contentstore/views/tests/test_assets.py b/cms/djangoapps/contentstore/views/tests/test_assets.py index 78ce5b4050..797b76be59 100644 --- a/cms/djangoapps/contentstore/views/tests/test_assets.py +++ b/cms/djangoapps/contentstore/views/tests/test_assets.py @@ -126,7 +126,7 @@ class BasicAssetsTestCase(AssetsTestCase): ) course = module_store.get_course(course_id) - filename = 'sample_static.txt' + filename = 'sample_static.html' html_src_attribute = '"/static/{}"'.format(filename) asset_url = replace_static_urls(html_src_attribute, course_id=course.id) url = asset_url.replace('"', '') @@ -379,7 +379,7 @@ class LockAssetTestCase(AssetsTestCase): """ def verify_asset_locked_state(locked): """ Helper method to verify lock state in the contentstore """ - asset_location = StaticContent.get_location_from_path('/c4x/edX/toy/asset/sample_static.txt') + asset_location = StaticContent.get_location_from_path('/c4x/edX/toy/asset/sample_static.html') content = contentstore().find(asset_location) self.assertEqual(content.locked, locked) @@ -387,14 +387,14 @@ class LockAssetTestCase(AssetsTestCase): """ Helper method for posting asset update. """ content_type = 'application/txt' upload_date = datetime(2013, 6, 1, 10, 30, tzinfo=UTC) - asset_location = course.id.make_asset_key('asset', 'sample_static.txt') + asset_location = course.id.make_asset_key('asset', 'sample_static.html') url = reverse_course_url('assets_handler', course.id, kwargs={'asset_key_string': unicode(asset_location)}) resp = self.client.post( url, # pylint: disable=protected-access json.dumps(assets._get_asset_json( - "sample_static.txt", content_type, upload_date, asset_location, None, lock)), + "sample_static.html", content_type, upload_date, asset_location, None, lock)), "application/json" ) diff --git a/cms/djangoapps/contentstore/views/videos.py b/cms/djangoapps/contentstore/views/videos.py index 0c047f8ba1..ec34567f9f 100644 --- a/cms/djangoapps/contentstore/views/videos.py +++ b/cms/djangoapps/contentstore/views/videos.py @@ -44,6 +44,9 @@ class StatusDisplayStrings(object): _COMPLETE = ugettext_noop("Ready") # Translators: This is the status for a video that the servers have failed to process _FAILED = ugettext_noop("Failed") + # Translators: This is the status for a video which has failed + # due to being flagged as a duplicate by an external or internal CMS + _DUPLICATE = ugettext_noop("Failed Duplicate") # Translators: This is the status for a video for which an invalid # processing token was provided in the course settings _INVALID_TOKEN = ugettext_noop("Invalid Token") @@ -61,6 +64,7 @@ class StatusDisplayStrings(object): "file_complete": _COMPLETE, "file_corrupt": _FAILED, "pipeline_error": _FAILED, + "duplicate": _DUPLICATE, "invalid_token": _INVALID_TOKEN, "imported": _IMPORTED, } @@ -311,9 +315,9 @@ def videos_post(course, request): edx_video_id = unicode(uuid4()) key = storage_service_key(bucket, file_name=edx_video_id) for metadata_name, value in [ - ("course_video_upload_token", course_video_upload_token), - ("client_video_id", file_name), - ("course_key", unicode(course.id)), + ("course_video_upload_token", course_video_upload_token), + ("client_video_id", file_name), + ("course_key", unicode(course.id)), ]: key.set_metadata(metadata_name, value) upload_url = key.generate_url( diff --git a/cms/djangoapps/course_creators/tests/test_views.py b/cms/djangoapps/course_creators/tests/test_views.py index fdca3b8d56..fca8e7faaa 100644 --- a/cms/djangoapps/course_creators/tests/test_views.py +++ b/cms/djangoapps/course_creators/tests/test_views.py @@ -5,13 +5,13 @@ Tests course_creators.views.py. from django.contrib.auth.models import User from django.core.exceptions import PermissionDenied from django.test import TestCase, RequestFactory +from django.core.urlresolvers import reverse from course_creators.views import add_user_with_status_unrequested, add_user_with_status_granted from course_creators.views import get_course_creator_status, update_course_creator_group, user_requested_access import mock from student.roles import CourseCreatorRole from student import auth -from edxmako.tests import mako_middleware_process_request class CourseCreatorView(TestCase): @@ -73,11 +73,12 @@ class CourseCreatorView(TestCase): add_user_with_status_unrequested(self.user) self.assertEqual('unrequested', get_course_creator_status(self.user)) - request = RequestFactory().get('/') - request.user = self.user + self.client.login(username=self.user.username, password='foo') - mako_middleware_process_request(request) - user_requested_access(self.user) + # The user_requested_access function renders a template that requires + # request-specific information. Use the django TestClient to supply + # the appropriate request context. + self.client.post(reverse('request_course_creator')) self.assertEqual('pending', get_course_creator_status(self.user)) def test_user_requested_already_granted(self): diff --git a/cms/envs/aws.py b/cms/envs/aws.py index c8fab8d6a4..811bd3b689 100644 --- a/cms/envs/aws.py +++ b/cms/envs/aws.py @@ -87,6 +87,21 @@ CELERY_QUEUES = { DEFAULT_PRIORITY_QUEUE: {} } +# Setup alternate queues, to allow access to cross-process workers +ALTERNATE_QUEUE_ENVS = os.environ.get('ALTERNATE_WORKER_QUEUES', '').split() +ALTERNATE_QUEUES = [ + DEFAULT_PRIORITY_QUEUE.replace(QUEUE_VARIANT, alternate + '.') + for alternate in ALTERNATE_QUEUE_ENVS +] +CELERY_QUEUES.update( + { + alternate: {} + for alternate in ALTERNATE_QUEUES + if alternate not in CELERY_QUEUES.keys() + } +) +CELERY_ROUTES = "{}celery.Router".format(QUEUE_VARIANT) + ############# NON-SECURE ENV CONFIG ############################## # Things like server locations, ports, etc. with open(CONFIG_ROOT / CONFIG_PREFIX + "env.json") as env_file: diff --git a/cms/envs/common.py b/cms/envs/common.py index 2d4e6bf30e..a3204be72f 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -312,6 +312,7 @@ simplefilter('ignore') ################################# Middleware ################################### MIDDLEWARE_CLASSES = ( + 'crum.CurrentRequestUserMiddleware', 'request_cache.middleware.RequestCache', 'header_control.middleware.HeaderControlMiddleware', 'django.middleware.cache.UpdateCacheMiddleware', @@ -332,7 +333,6 @@ MIDDLEWARE_CLASSES = ( 'student.middleware.UserStandingMiddleware', 'contentserver.middleware.StaticContentServer', - 'crum.CurrentRequestUserMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'track.middleware.TrackMiddleware', @@ -350,9 +350,6 @@ MIDDLEWARE_CLASSES = ( 'codejail.django_integration.ConfigureCodeJailMiddleware', - # needs to run after locale middleware (or anything that modifies the request context) - 'edxmako.middleware.MakoMiddleware', - # catches any uncaught RateLimitExceptions and returns a 403 instead of a 500 'ratelimitbackend.middleware.RateLimitMiddleware', diff --git a/cms/envs/dev_with_worker.py b/cms/envs/devstack_with_worker.py similarity index 54% rename from cms/envs/dev_with_worker.py rename to cms/envs/devstack_with_worker.py index 44145dad99..eb9914d5e7 100644 --- a/cms/envs/dev_with_worker.py +++ b/cms/envs/devstack_with_worker.py @@ -1,32 +1,24 @@ """ -This config file follows the dev enviroment, but adds the +This config file follows the devstack enviroment, but adds the requirement of a celery worker running in the background to process celery tasks. -The worker can be executed using: +When testing locally, run lms/cms with this settings file as well, to test queueing +of tasks onto the appropriate workers. -django_admin.py celery worker +In two separate processes on devstack: + paver devstack studio --settings=devstack_with_worker + ./manage.py cms celery worker --settings=devstack_with_worker """ # We intentionally define lots of variables that aren't used, and # want to import all variables from base settings files # pylint: disable=wildcard-import, unused-wildcard-import +from cms.envs.devstack import * -from dev import * - -################################# CELERY ###################################### - -# Requires a separate celery worker - +# Require a separate celery worker CELERY_ALWAYS_EAGER = False -# Use django db as the broker and result store - -BROKER_URL = 'django://' -INSTALLED_APPS += ('djcelery.transport', ) -CELERY_RESULT_BACKEND = 'database' -DJKOMBU_POLLING_INTERVAL = 1.0 - # Disable transaction management because we are using a worker. Views # that request a task and wait for the result will deadlock otherwise. for database_name in DATABASES: diff --git a/cms/static/coffee/src/views/tabs.coffee b/cms/static/coffee/src/views/tabs.coffee deleted file mode 100644 index 9d00bd425a..0000000000 --- a/cms/static/coffee/src/views/tabs.coffee +++ /dev/null @@ -1,133 +0,0 @@ -define ["underscore", "jquery", "jquery.ui", "backbone", "common/js/components/views/feedback_prompt", - "common/js/components/views/feedback_notification", "coffee/src/views/module_edit", "js/models/module_info", "js/utils/module"], -(_, $, ui, Backbone, PromptView, NotificationView, ModuleEditView, ModuleModel, ModuleUtils) -> - class TabsEdit extends Backbone.View - - initialize: (options) => - @$('.component').each((idx, element) => - model = new ModuleModel({ - id: $(element).data('locator') - }) - - new ModuleEditView( - el: element, - onDelete: @deleteTab, - model: model - ) - ) - @options = _.extend({}, options) - @options.mast.find('.new-tab').on('click', @addNewTab) - $('.add-pages .new-tab').on('click', @addNewTab) - $('.toggle-checkbox').on('click', @toggleVisibilityOfTab) - @$('.course-nav-list').sortable( - handle: '.drag-handle' - update: @tabMoved - helper: 'clone' - opacity: '0.5' - placeholder: 'component-placeholder' - forcePlaceholderSize: true - axis: 'y' - items: '> .is-movable' - ) - - toggleVisibilityOfTab: (event, ui) => - checkbox_element = event.target - tab_element = $(checkbox_element).parents(".course-tab")[0] - - saving = new NotificationView.Mini({title: gettext("Saving")}) - saving.show() - - $.ajax({ - type:'POST', - url: @model.url(), - data: JSON.stringify({ - tab_id_locator : { - tab_id: $(tab_element).data('tab-id'), - tab_locator: $(tab_element).data('locator') - }, - is_hidden : $(checkbox_element).is(':checked') - }), - contentType: 'application/json' - }).success(=> saving.hide()) - - tabMoved: (event, ui) => - tabs = [] - @$('.course-tab').each((idx, element) => - tabs.push( - { - tab_id: $(element).data('tab-id'), - tab_locator: $(element).data('locator') - } - ) - ) - - analytics.track "Reordered Pages", - course: course_location_analytics - - saving = new NotificationView.Mini({title: gettext("Saving")}) - saving.show() - - $.ajax({ - type:'POST', - url: @model.url(), - data: JSON.stringify({ - tabs : tabs - }), - contentType: 'application/json' - }).success(=> saving.hide()) - - addNewTab: (event) => - event.preventDefault() - - editor = new ModuleEditView( - onDelete: @deleteTab - model: new ModuleModel() - ) - - $('.new-component-item').before(editor.$el) - editor.$el.addClass('course-tab is-movable') - editor.$el.addClass('new') - setTimeout(=> - editor.$el.removeClass('new') - , 1000) - $('html, body').animate {scrollTop: $('.new-component-item').offset().top}, 500 - - - editor.createItem( - @model.get('id'), - {category: 'static_tab'} - ) - - analytics.track "Added Page", - course: course_location_analytics - - deleteTab: (event) => - confirm = new PromptView.Warning - title: gettext('Delete Page Confirmation') - message: gettext('Are you sure you want to delete this page? This action cannot be undone.') - actions: - primary: - text: gettext("OK") - click: (view) -> - view.hide() - $component = $(event.currentTarget).parents('.component') - - analytics.track "Deleted Page", - course: course_location_analytics - id: $component.data('locator') - deleting = new NotificationView.Mini - title: gettext('Deleting') - deleting.show() - $.ajax({ - type: 'DELETE', - url: ModuleUtils.getUpdateUrl($component.data('locator')) - }).success(=> - $component.remove() - deleting.hide() - ) - secondary: [ - text: gettext('Cancel') - click: (view) -> - view.hide() - ] - confirm.show() diff --git a/cms/static/js/factories/edit_tabs.js b/cms/static/js/factories/edit_tabs.js index 34ad04d12a..71ba0f42b6 100644 --- a/cms/static/js/factories/edit_tabs.js +++ b/cms/static/js/factories/edit_tabs.js @@ -1,5 +1,5 @@ define([ - 'js/models/explicit_url', 'coffee/src/views/tabs', 'xmodule', 'coffee/src/main', 'xblock/cms.runtime.v1' + 'js/models/explicit_url', 'js/views/tabs', 'xmodule', 'coffee/src/main', 'xblock/cms.runtime.v1' ], function (TabsModel, TabsEditView, xmoduleLoader) { 'use strict'; return function (courseLocation, explicitUrl) { diff --git a/cms/static/js/i18n/ar/djangojs.js b/cms/static/js/i18n/ar/djangojs.js index af81f58869..6effb000fb 100644 --- a/cms/static/js/i18n/ar/djangojs.js +++ b/cms/static/js/i18n/ar/djangojs.js @@ -234,6 +234,7 @@ "Access": "\u0627\u0644\u0648\u0635\u0648\u0644", "Accomplishments": "\u0627\u0644\u0625\u0646\u062c\u0627\u0632\u0627\u062a", "Accomplishments Pagination": "\u062a\u0631\u0642\u064a\u0645 \u0635\u0641\u062d\u0627\u062a \u0627\u0644\u0625\u0646\u062c\u0627\u0632\u0627\u062a", + "Account Information": "\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u062d\u0633\u0627\u0628", "Account Not Activated": "\u0627\u0644\u062d\u0633\u0627\u0628 \u063a\u064a\u0631 \u0645\u0641\u0639\u0651\u0644", "Account Settings": "\u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0627\u0644\u062d\u0633\u0627\u0628", "Account Settings page.": "\u0635\u0641\u062d\u0629 \u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0627\u0644\u062d\u0633\u0627\u0628", @@ -273,6 +274,9 @@ "Add {role} Access": "\u0625\u0636\u0627\u0641\u0629 \u0635\u0644\u0627\u062d\u064a\u0629 \u0627\u0644\u0648\u0635\u0648\u0644 \u0627\u0644\u062e\u0627\u0635\u0629 \u0628\u0640 {role}", "Adding": "\u062c\u0627\u0631\u064a \u0627\u0644\u0625\u0636\u0627\u0641\u0629", "Adding the selected course to your cart": "\u062c\u0627\u0631\u064a \u0625\u0636\u0627\u0641\u0629 \u0627\u0644\u0645\u0633\u0627\u0642 \u0627\u0644\u0645\u062e\u062a\u0627\u0631 \u0625\u0644\u0649 \u0639\u0631\u0628\u0629 \u0645\u0634\u062a\u0631\u064a\u0627\u062a\u0643", + "Additional Information": "\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0625\u0636\u0627\u0641\u064a\u0629", + "Adjust video speed": "\u0636\u0628\u0637 \u0633\u0631\u0639\u0629 \u0627\u0644\u0641\u064a\u062f\u064a\u0648", + "Adjust video volume": "\u0636\u0628\u0637 \u0645\u0633\u062a\u0648\u0649 \u0627\u0644\u0635\u0648\u062a", "Admin": "\u0645\u0634\u0631\u0650\u0641", "Advanced": "\u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0645\u062a\u0642\u062f\u0651\u0645\u0629", "Align center": "\u0645\u062d\u0627\u0630\u0627\u0629 \u0625\u0644\u0649 \u0627\u0644\u0645\u0646\u062a\u0635\u0641", @@ -358,6 +362,7 @@ "Back to {platform} FAQs": "\u0627\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0627\u0644\u0623\u0633\u0626\u0644\u0629 \u0627\u0644\u0634\u0627\u0626\u0639\u0629 \u0644\u0645\u0646\u0635\u0651\u0629 {platform} ", "Background color": "\u0644\u0648\u0646 \u0627\u0644\u062e\u0644\u0641\u064a\u0629", "Basic": "\u0623\u0633\u0627\u0633\u064a", + "Basic Account Information": "\u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u062d\u0633\u0627\u0628 \u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0629", "Be sure your entire face is inside the frame": "\u062a\u0623\u0643\u0651\u062f \u0645\u0646 \u0623\u0646\u0651 \u0648\u062c\u0647\u0643 \u062f\u0627\u062e\u0644 \u0625\u0637\u0627\u0631 \u0627\u0644\u0635\u0648\u0631\u0629 \u0628\u0627\u0644\u0643\u0627\u0645\u0644 ", "Before proceeding, please confirm that your details match": "\u0642\u0628\u0644 \u0627\u0644\u0645\u062a\u0627\u0628\u0639\u0629\u060c \u064a\u064f\u0631\u062c\u0649 \u0627\u0644\u062a\u0623\u0643\u0651\u062f \u0645\u0646 \u062a\u0637\u0627\u0628\u0642 \u0628\u064a\u0627\u0646\u0627\u062a\u0643", "Before you upgrade to a certificate track, you must activate your account.": "\u064a\u062c\u0628 \u0639\u0644\u064a\u0643 \u0623\u0648\u0644\u064b\u0627 \u062a\u0641\u0639\u064a\u0644 \u062d\u0633\u0627\u0628\u0643 \u0642\u0628\u0644 \u0627\u0644\u062a\u0631\u0642\u064a\u0629 \u0644\u0645\u0633\u0627\u0631 \u062a\u064f\u0645\u0646\u062d \u0628\u0645\u0648\u062c\u0628\u0647 \u0634\u0647\u0627\u062f\u0629.", @@ -463,6 +468,7 @@ "Click OK to have your e-mail address sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information.": "\u0627\u0646\u0642\u0631 \u2019\u0645\u0648\u0627\u0641\u0642\u2018 \u0644\u0625\u0631\u0633\u0627\u0644 \u0639\u0646\u0648\u0627\u0646 \u0628\u0631\u064a\u062f\u0643 \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0625\u0644\u0649 \u062a\u0637\u0628\u064a\u0642 \u0637\u0631\u0641 3.\n\n\u0627\u0646\u0642\u0631 \u2019\u0625\u0644\u063a\u0627\u0621\u2018 \u0644\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0647\u0630\u0647 \u0627\u0644\u0635\u0641\u062d\u0629 \u0645\u0646 \u062f\u0648\u0646 \u0625\u0631\u0633\u0627\u0644 \u0645\u0639\u0644\u0648\u0645\u0627\u062a\u0643.", "Click OK to have your username and e-mail address sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information.": "\u0627\u0646\u0642\u0631 \u2019\u0645\u0648\u0627\u0641\u0642\u2018 \u0644\u0625\u0631\u0633\u0627\u0644 \u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 \u0627\u0644\u0630\u064a \u0623\u062f\u062e\u0644\u062a\u0647 \u0648\u0639\u0646\u0648\u0627\u0646 \u0628\u0631\u064a\u062f\u0643 \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0625\u0644\u0649 \u062a\u0637\u0628\u064a\u0642 \u0637\u0631\u0641 3.\n\n\u0627\u0646\u0642\u0631 \u2019\u0625\u0644\u063a\u0627\u0621\u2018 \u0644\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0647\u0630\u0647 \u0627\u0644\u0635\u0641\u062d\u0629 \u0645\u0646 \u062f\u0648\u0646 \u0625\u0631\u0633\u0627\u0644 \u0645\u0639\u0644\u0648\u0645\u0627\u062a\u0643.", "Click OK to have your username sent to a 3rd party application.\n\nClick Cancel to return to this page without sending your information.": "\u0627\u0646\u0642\u0631 \u2019\u0645\u0648\u0627\u0641\u0642\u2018 \u0644\u0625\u0631\u0633\u0627\u0644 \u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 \u0627\u0644\u0630\u064a \u0623\u062f\u062e\u0644\u062a\u0647 \u0625\u0644\u0649 \u062a\u0637\u0628\u064a\u0642 \u0637\u0631\u0641 3.\n\n \u0627\u0646\u0642\u0631 \u2019\u0625\u0644\u063a\u0627\u0621\u2018 \u0644\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0647\u0630\u0647 \u0627\u0644\u0635\u0641\u062d\u0629 \u0645\u0646 \u062f\u0648\u0646 \u0625\u0631\u0633\u0627\u0644 \u0645\u0639\u0644\u0648\u0645\u0627\u062a\u0643.", + "Click on this button to mute or unmute this video or press UP or DOWN buttons to increase or decrease volume level.": "\u0627\u0646\u0642\u0631 \u0639\u0644\u0649 \u0647\u0630\u0627 \u0627\u0644\u0632\u0631 \u0645\u0646 \u0623\u062c\u0644 \u0643\u062a\u0645 \u0623\u0648 \u062a\u0634\u063a\u064a\u0644 \u0635\u0648\u062a \u0627\u0644\u0641\u064a\u062f\u064a\u0648. \u0644\u0631\u0641\u0639 \u0645\u0633\u062a\u0648\u0649 \u0627\u0644\u0635\u0648\u062a \u0623\u0648 \u062e\u0641\u0636\u0647 \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0632\u0631 \"\u0623\u0639\u0644\u0649\" \u0623\u0648 \"\u0623\u0633\u0641\u0644\" \u0645\u0646 \u0639\u0644\u0649 \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d.", "Click to add": "\u0627\u0636\u063a\u0637 \u0644\u0644\u0625\u0636\u0627\u0641\u0629", "Click to add a new %(xblock_type)s": "\u064a\u064f\u0631\u062c\u0649 \u0627\u0644\u0646\u0642\u0631 \u0644\u0625\u0636\u0627\u0641\u0629 \u0648\u062d\u062f\u0627\u062a %(xblock_type)s \u062c\u062f\u064a\u062f\u0629", "Click to change": "\u0623\u0636\u063a\u0637 \u0644\u0644\u062a\u063a\u064a\u0631", @@ -942,7 +948,11 @@ "Limit Access": "\u0627\u0644\u062d\u062f\u0651 \u0645\u0646 \u0635\u0644\u0627\u062d\u064a\u0629 \u0627\u0644\u0648\u0635\u0648\u0644", "Limited Profile": "\u0645\u0644\u0641\u0651\u064a \u0627\u0644\u0634\u062e\u0635\u064a \u0627\u0644\u0645\u062d\u062f\u0648\u062f", "Link Description": "\u0648\u0635\u0641 \u0627\u0644\u0631\u0627\u0628\u0637", + "Link Your Account": "\u0627\u0631\u0628\u0637 \u062d\u0633\u0627\u0628\u0643", "Link types should be unique.": "\u064a\u062c\u0628 \u0623\u0646 \u062a\u0643\u0648\u0646 \u0623\u0646\u0648\u0627\u0639 \u0627\u0644\u0631\u0648\u0627\u0628\u0637 \u0641\u0631\u064a\u062f\u0629.", + "Link your {accountName} account": "\u0627\u0631\u0628\u0637 \u062d\u0633\u0627\u0628\u0643 \u0639\u0644\u0649 {accountName}", + "Link your {accountName} account to your edX account and ": "\u0627\u0631\u0628\u0637 \u062d\u0633\u0627\u0628\u0643 \u0639\u0644\u0649 {accountName} \u0628\u0647\u0630\u0627 \u0627\u0644\u062d\u0633\u0627\u0628 \u0648", + "Linked Accounts": "\u0627\u0644\u062d\u0633\u0627\u0628\u0627\u062a \u0627\u0644\u0645\u0631\u0628\u0648\u0637\u0629", "Linking": "\u0627\u0644\u0631\u0628\u0637", "Links are generated on demand and expire within 5 minutes due to the sensitive nature of student information.": "\u064a\u062c\u0631\u064a \u0627\u0633\u062a\u062d\u062f\u0627\u062b \u0627\u0644\u0631\u0648\u0627\u0628\u0637 \u0639\u0646\u062f \u0627\u0644\u0637\u0644\u0628 \u0648\u064a\u0646\u062a\u0647\u064a \u0645\u0641\u0639\u0648\u0644\u0647\u0627 \u0641\u064a \u063a\u0636\u0648\u0646 5 \u062f\u0642\u0627\u0626\u0642 \u0646\u0638\u0631\u064b\u0627 \u0644\u062d\u0633\u0627\u0633\u064a\u0629 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u0637\u0627\u0644\u0628.", "Links should be unique.": "\u064a\u062c\u0628 \u0623\u0646 \u062a\u0643\u0648\u0646 \u0627\u0644\u0631\u0648\u0627\u0628\u0637 \u0641\u0631\u064a\u062f\u0629.", @@ -1069,6 +1079,7 @@ "Only properly formatted .csv files will be accepted.": "\u0644\u0646 \u062a\u064f\u0642\u0628\u0644 \u0633\u0648\u0649 \u0645\u0644\u0641\u0651\u0627\u062a .csv \u0627\u0644\u0645\u0646\u0633\u0651\u0642\u0629 \u062a\u0646\u0633\u064a\u0642\u064b\u0627 \u0635\u062d\u064a\u062d\u064b\u0627. ", "Open": "\u0641\u062a\u062d", "Open Calculator": "\u0641\u062a\u062d \u0627\u0644\u0622\u0644\u0629 \u0627\u0644\u062d\u0627\u0633\u0628\u0629 ", + "Open language menu": "\u0641\u062a\u062d \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0644\u063a\u0629", "Open language menu.": "\u0641\u062a\u062d \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0644\u063a\u0629.", "Open/download this file": "\u0641\u062a\u062d/\u062a\u0646\u0632\u064a\u0644 \u0647\u0630\u0627 \u0627\u0644\u0645\u0644\u0641\u0651", "OpenAssessment Save Error": "\u0646\u0623\u0633\u0641 \u0644\u062d\u062f\u0648\u062b \u062e\u0637\u0623 \u0641\u064a \u062d\u0641\u0638 \u0627\u0644\u062a\u0642\u064a\u064a\u0645 \u0627\u0644\u0645\u0641\u062a\u0648\u062d.", @@ -1159,6 +1170,8 @@ "Preformatted": "\u0645\u064f\u0646\u0633\u0651\u064e\u0642 \u0645\u0633\u0628\u0642\u064b\u0627", "Prerequisite:": "\u0627\u0644\u0645\u062a\u0637\u0644\u0651\u0628 \u0627\u0644\u0623\u0633\u0627\u0633\u064a:", "Prerequisite: %(prereq_display_name)s": "\u0645\u062a\u0637\u0644\u0651\u0628 \u0623\u0633\u0627\u0633\u064a: %(prereq_display_name)s", + "Press UP to enter the speed menu then use the UP and DOWN arrow keys to navigate the different speeds, then press ENTER to change to the selected speed.": "\u0627\u0636\u063a\u0637 \u0632\u0631 \"\u0623\u0639\u0644\u0649\" \u0645\u0646 \u0639\u0644\u0649 \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0644\u0644\u062f\u062e\u0648\u0644 \u0625\u0644\u0649 \u0642\u0627\u0626\u0645\u0629 \u0636\u0628\u0637 \u0627\u0644\u0633\u0631\u0639\u0629 \u062b\u0645 \u0627\u0633\u062a\u062e\u062f\u0645 \u0632\u0631 \"\u0627\u0644\u0623\u0639\u0644\u0649\" \u0648\"\u0627\u0644\u0623\u0633\u0641\u0644\" \u0644\u0627\u062e\u062a\u064a\u0627\u0631 \u0627\u0644\u0633\u0631\u0639\u0629 \u0627\u0644\u0645\u0646\u0627\u0633\u0628\u0629. \u0644\u062d\u0641\u0638 \u0627\u0644\u0633\u0631\u0639\u0629 \u0627\u0644\u0645\u062e\u062a\u0627\u0631\u0629 \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0632\u0631 \u0627\u0644\u0625\u0631\u0633\u0627\u0644 \"ENTER\"", + "Press the UP arrow key to enter the language menu then use UP and DOWN arrow keys to navigate language options. Press ENTER to change to the selected language.": "\u0627\u0636\u063a\u0637 \u0632\u0631 \"\u0623\u0639\u0644\u0649\" \u0645\u0646 \u0639\u0644\u0649 \u0644\u0648\u062d\u0629 \u0627\u0644\u0645\u0641\u0627\u062a\u064a\u062d \u0644\u0644\u062f\u062e\u0648\u0644 \u0625\u0644\u0649 \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0644\u063a\u0629 \u062b\u0645 \u0627\u0633\u062a\u062e\u062f\u0645 \u0632\u0631 \"\u0627\u0644\u0623\u0639\u0644\u0649\" \u0648\"\u0627\u0644\u0623\u0633\u0641\u0644\" \u0644\u0627\u062e\u062a\u064a\u0627\u0631 \u0627\u0644\u0644\u063a\u0629 \u0627\u0644\u0645\u0646\u0627\u0633\u0628\u0629. \u0644\u062d\u0641\u0638 \u0627\u0644\u0644\u063a\u0629 \u0627\u0644\u0645\u062e\u062a\u0627\u0631\u0629 \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0632\u0631 \u0627\u0644\u0625\u0631\u0633\u0627\u0644 \"ENTER\"", "Prev": "\u0627\u0644\u0633\u0627\u0628\u0642", "Prevent students from generating certificates in this course?": "\u0647\u0644 \u062a\u0631\u064a\u062f \u0645\u0646\u0639 \u0627\u0644\u0637\u0644\u0627\u0628 \u0645\u0646 \u0625\u0639\u062f\u0627\u062f \u0634\u0647\u0627\u062f\u0627\u062a \u0644\u0647\u0630\u0627 \u0627\u0644\u0645\u0633\u0627\u0642\u061f", "Preview": "\u0645\u0639\u0627\u064a\u0646\u0629", @@ -1179,6 +1192,7 @@ "Profile": "\u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0634\u062e\u0635\u064a", "Profile Image": "\u0635\u0648\u0631\u0629 \u0627\u0644\u0645\u0644\u0641 \u0627\u0644\u0634\u062e\u0635\u064a", "Profile image for {username}": "\u0635\u0648\u0631\u0629 \u0627\u0644\u0635\u0641\u062d\u0629 \u0627\u0644\u0634\u062e\u0635\u064a\u0629 \u0644\u0644\u0645\u0633\u062a\u062e\u062f\u0645 {username}", + "Programs": "\u0627\u0644\u0628\u0631\u0627\u0645\u062c", "Promote another member to Admin to remove your admin rights": "\u064a\u064f\u0631\u062c\u0649 \u062a\u0631\u0642\u064a\u0629 \u0639\u0636\u0648 \u0622\u062e\u0631 \u0625\u0644\u0649 \u062f\u0631\u062c\u0629 \u0645\u0634\u0631\u0650\u0641 \u0644\u062a\u062a\u0645\u0643\u0651\u0646 \u0645\u0646 \u0625\u0644\u063a\u0627\u0621 \u062d\u0642\u0648\u0642\u0643 \u0643\u0645\u0634\u0631\u0650\u0641.", "Public": "\u0639\u0627\u0645", "Publish": "\u0646\u0634\u0631", @@ -1236,6 +1250,7 @@ "Required field.": "\u062d\u0642\u0644 \u0645\u0637\u0644\u0648\u0628.", "Rescore problem '<%= problem_id %>' for all students?": "\u0625\u0639\u0627\u062f\u0629 \u062a\u0642\u064a\u064a\u0645 \u0627\u0644\u0645\u0633\u0623\u0644\u0629 \u0631\u0642\u0645 \u2019<%= problem_id %>\u2018 \u0644\u0643\u0627\u0641\u0629 \u0627\u0644\u0637\u0644\u0627\u0628\u061f", "Reset Password": "\u062a\u063a\u064a\u064a\u0631 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631", + "Reset Your Password": "\u063a\u064a\u0631 \u0643\u0644\u0645\u0629 \u0633\u0631 \u062d\u0633\u0627\u0628\u0643", "Reset attempts for all students on problem '<%= problem_id %>'?": "\u0625\u0639\u0627\u062f\u0629 \u0636\u0628\u0637 \u0639\u062f\u062f \u0645\u062d\u0627\u0648\u0644\u0627\u062a \u062d\u0644\u0651 \u0627\u0644\u0637\u0644\u0651\u0627\u0628 \u0644\u0644\u0645\u0633\u0623\u0644\u0629 \u0631\u0642\u0645 \u2019<%= problem_id %>\u2018\u061f", "Reset my password": "\u062a\u063a\u064a\u064a\u0631 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631", "Restore enrollment code": "\u0627\u0633\u062a\u0639\u0627\u062f\u0629 \u0631\u0645\u0632 \u0627\u0644\u062a\u0633\u062c\u064a\u0644", @@ -1527,6 +1542,7 @@ "There was an error, try searching again.": "\u0646\u0623\u0633\u0641 \u0644\u062d\u062f\u0648\u062b \u062e\u0637\u0623\u060c \u064a\u064f\u0631\u062c\u0649 \u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u0628\u062d\u062b \u0645\u062c\u062f\u0651\u062f\u064b\u0627.", "There were errors reindexing course.": "\u0646\u0623\u0633\u0641 \u0644\u062d\u062f\u0648\u062b \u0623\u062e\u0637\u0627\u0621 \u0641\u064a \u0625\u0639\u0627\u062f\u0629 \u0641\u0647\u0631\u0633\u0629 \u0645\u062d\u062a\u0648\u064a\u0627\u062a \u0627\u0644\u0645\u0633\u0627\u0642.", "There's already another assignment type with this name.": "\u064a\u0648\u062c\u062f \u0645\u0633\u0628\u0642\u064b\u0627 \u0646\u0648\u0639 \u0622\u062e\u0631 \u0645\u0646 \u0627\u0644\u0648\u0627\u062c\u0628\u0627\u062a \u0628\u0647\u0630\u0627 \u0627\u0644\u0627\u0633\u0645.", + "These settings include basic information about your account. You can also ": "\u0647\u0630\u0647 \u0627\u0644\u0625\u0639\u062f\u0627\u062f\u0627\u062a \u062a\u062d\u062a\u0648\u064a \u0639\u0644\u0649 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u062d\u0633\u0627\u0628\u0643 \u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0629. \u064a\u0645\u0643\u0646\u0643 \u0623\u064a\u0636\u0627\u064b", "These users were not added as beta testers:": "\u0644\u0645 \u064a\u064f\u0636\u064e\u0641 \u0647\u0624\u0644\u0627\u0621 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u0648\u0646 \u0625\u0644\u0649 \u0642\u0627\u0626\u0645\u0629 \u0623\u0639\u0636\u0627\u0621 \u0645\u062e\u062a\u0628\u0631\u064a \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u062a\u062c\u0631\u064a\u0628\u064a\u0629:", "These users were not affiliated with the course so could not be unenrolled:": "\u0644\u0645 \u064a\u0643\u0646 \u0647\u0624\u0644\u0627\u0621 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u0648\u0646 \u0645\u0646\u062a\u0633\u0628\u064a\u0646 \u0625\u0644\u0649 \u0627\u0644\u0645\u0633\u0627\u0642 \u0648\u0628\u0627\u0644\u062a\u0627\u0644\u064a \u062a\u0639\u0630\u0651\u0631 \u0625\u0644\u063a\u0627\u0621 \u062a\u0633\u062c\u064a\u0644\u0647\u0645:", "These users were not removed as beta testers:": "\u0644\u0645 \u064a\u064f\u062d\u0630\u064e\u0641 \u0647\u0624\u0644\u0627\u0621 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645\u064a\u0646 \u0645\u0646 \u0642\u0627\u0626\u0645\u0629 \u0623\u0639\u0636\u0627\u0621 \u0645\u062e\u062a\u0628\u0631\u064a \u0627\u0644\u0646\u0633\u062e\u0629 \u0627\u0644\u062a\u062c\u0631\u064a\u0628\u064a\u0629:", @@ -1587,6 +1603,7 @@ "Title:": "\u0627\u0644\u0639\u0646\u0648\u0627\u0646:", "Titles more than 100 characters may prevent students from printing their certificate on a single page.": "\u064a\u0645\u0643\u0646 \u0623\u0646 \u062a\u0645\u0646\u0639 \u0627\u0644\u0639\u0646\u0627\u0648\u064a\u0646 \u0627\u0644\u062a\u064a \u062a\u0632\u064a\u062f \u0639\u0646 100 \u062d\u0631\u0641\u064b\u0627 \u0627\u0644\u0637\u0644\u0627\u0628 \u0645\u0646 \u0637\u0628\u0627\u0639\u0629 \u0634\u0647\u0627\u062f\u062a\u0647\u0645 \u0639\u0644\u0649 \u0635\u0641\u062d\u0629 \u0648\u0627\u062d\u062f\u0629", "To be sure all students can access the video, we recommend providing both an .mp4 and a .webm version of your video. Click below to add a URL for another version. These URLs cannot be YouTube URLs. The first listed video that's compatible with the student's computer will play.": "\u0644\u062a\u062a\u0623\u0643\u0651\u062f \u0645\u0646 \u062a\u0645\u0643\u0651\u0646 \u062c\u0645\u064a\u0639 \u0627\u0644\u0637\u0644\u0627\u0628 \u0645\u0646 \u0627\u0644\u0648\u0635\u0648\u0644 \u0625\u0644\u0649 \u0647\u0630\u0627 \u0627\u0644\u0641\u064a\u062f\u064a\u0648\u060c \u0646\u0648\u0635\u064a \u0628\u062a\u062d\u0645\u064a\u0644 \u0645\u0642\u0637\u0639 \u0627\u0644\u0641\u064a\u062f\u064a\u0648 \u0630\u0627\u062a\u0647 \u0628\u0643\u0644 \u0645\u0646 \u0635\u064a\u063a\u062a\u064e\u064a .mp4 \u0648 .webm. \u064a\u064f\u0631\u062c\u0649 \u0627\u0644\u0646\u0642\u0631 \u0623\u062f\u0646\u0627\u0647 \u0644\u0625\u0636\u0627\u0641\u0629 \u0631\u0627\u0628\u0637 \u0644\u0646\u0633\u062e\u0629 \u0623\u062e\u0631\u0649. \u0644\u0627 \u064a\u0645\u0643\u0646 \u0644\u0647\u0630\u0647 \u0627\u0644\u0631\u0648\u0627\u0628\u0637 \u0623\u0646 \u062a\u0634\u064a\u0631 \u0625\u0644\u0649 \u0645\u0648\u0642\u0639 \u064a\u0648\u062a\u064a\u0648\u0628. \u0648\u0633\u064a\u064f\u0639\u0631\u064e\u0636 \u0623\u0648\u0651\u0644 \u0641\u064a\u062f\u064a\u0648 \u0645\u064f\u062f\u0631\u064e\u062c \u0648\u0645\u062a\u0648\u0627\u0641\u0642 \u0645\u0639 \u0646\u0638\u0627\u0645 \u0643\u0648\u0645\u0628\u064a\u0648\u062a\u0631 \u0627\u0644\u0637\u0627\u0644\u0628.", + "To complete the {program} XSeries and earn an XSeries Certificate you must successfully earn a Verified Certificate in all courses shown below.": "\u064a\u062c\u0628 \u0623\u0646 \u062a\u062d\u0635\u0644 \u0639\u0644\u0649 \u0634\u0647\u0627\u062f\u0629 \u0645\u0648\u0642\u0629 \u0641\u064a \u062c\u0645\u064a\u0639 \u0627\u0644\u0645\u0633\u0627\u0642\u0627\u062a \u0627\u0644\u0645\u0648\u0636\u062d\u0629 \u0641\u064a \u0627\u0644\u0623\u0633\u0641\u0644 \u0644\u0625\u0643\u0645\u0627\u0644 \u0633\u0644\u0633\u0629 \u0645\u0633\u0627\u0642\u0627\u062a {program} \u0648\u0627\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0634\u0647\u0627\u062f\u0629 \u0625\u062a\u0645\u0627\u0645 \u0647\u0630\u0647 \u0627\u0644\u0633\u0644\u0633\u0644\u0629.", "To finalize course credit, %(display_name)s requires %(platform_name)s learners to submit a credit request.": "\u0644\u0627\u0633\u062a\u0643\u0645\u0627\u0644 \u0639\u0645\u0644\u064a\u0629 \u0627\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0645\u0627\u062f\u0629 \u062f\u0631\u0627\u0633\u064a\u0629 \u0628\u0634\u0643\u0644 \u0646\u0647\u0627\u0626\u064a\u060c \u064a\u064f\u0648\u062c\u0628 %(display_name)s \u0639\u0644\u0649 \u0645\u062a\u0639\u0644\u0651\u0645\u064a %(platform_name)s \u0627\u0644\u062a\u0642\u062f\u0651\u0645 \u0628\u0637\u0644\u0628 \u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0645\u0627\u062f\u0651\u0629 \u062f\u0631\u0627\u0633\u064a\u0629", "To invalidate a certificate for a particular learner, add the username or email address below.": "\u0623\u0636\u0641 \u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u062e\u062f\u0645 \u0623\u0648 \u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0623\u062f\u0646\u0627\u0647 \u0644\u0625\u0644\u063a\u0627\u0621 \u0634\u0647\u0627\u062f\u0629 \u0645\u0645\u0646\u0648\u062d\u0629 \u0644\u0645\u062a\u0639\u0644\u0651\u0645 \u0645\u0639\u064a\u0651\u0646.", "To receive a certificate, you must also verify your identity before %(date)s.": "\u0644\u0627 \u0628\u062f\u0651 \u0645\u0646 \u0625\u062b\u0628\u0627\u062a \u0647\u0648\u064a\u0651\u062a\u0643 \u0642\u0628\u0644 \u062a\u0627\u0631\u064a\u062e %(date)s \u0644\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0634\u0647\u0627\u062f\u0629.", @@ -1627,6 +1644,8 @@ "Unknown": "\u063a\u064a\u0631 \u0645\u0639\u0631\u0648\u0641 ", "Unknown Error Occurred.": "\u0646\u0623\u0633\u0641 \u0644\u062d\u062f\u0648\u062b \u062e\u0637\u0623 \u063a\u064a\u0631 \u0645\u0639\u0631\u0648\u0641. ", "Unknown user: {user}": "\u0645\u0633\u062a\u062e\u062f\u0645 \u063a\u064a\u0631 \u0645\u0639\u0631\u0648\u0641: {user}", + "Unlink This Account": "\u0627\u0641\u0635\u0644 \u0647\u0630\u0627 \u0627\u0644\u062d\u0633\u0627\u0628", + "Unlink your {accountName} account": "\u0627\u0641\u0635\u0644 \u062d\u0633\u0627\u0628\u0643 \u0639\u0644\u0649 {accountName}", "Unlinking": "\u0641\u0635\u0644 \u0627\u0644\u0631\u0628\u0637", "Unmark as Answer": "\u0625\u0644\u063a\u0627\u0621 \u0627\u0644\u062a\u062d\u062f\u064a\u062f \u0643\u0625\u062c\u0627\u0628\u0629", "Unmute": "\u0625\u0644\u063a\u0627\u0621 \u0643\u062a\u0645 \u0627\u0644\u0635\u0648\u062a", @@ -1721,6 +1740,7 @@ "Video ID": "\u0627\u0644\u0631\u0642\u0645 \u0627\u0644\u062a\u0639\u0631\u064a\u0641\u064a \u0644\u0644\u0641\u064a\u062f\u064a\u0648", "Video ended": "\u0627\u0646\u062a\u0647\u0649 \u0627\u0644\u0641\u064a\u062f\u064a\u0648", "Video position": "\u0645\u0648\u0636\u0639 \u0627\u0644\u0641\u064a\u062f\u064a\u0648", + "Video speed: ": "\u0633\u0631\u0639\u0629 \u0627\u0644\u0641\u064a\u062f\u064a\u0648:", "Video transcript": "\u0646\u0635 \u0627\u0644\u0641\u064a\u062f\u064a\u0648", "VideoPlayer: Element corresponding to the given selector was not found.": "\u0645\u0634\u063a\u0651\u0644 \u0627\u0644\u0641\u064a\u062f\u064a\u0648: \u0646\u0623\u0633\u0641 \u0644\u062a\u0639\u0630\u0651\u0631 \u0625\u064a\u062c\u0627\u062f \u0627\u0644\u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u062a\u0648\u0627\u0641\u0642 \u0645\u0639 \u0623\u062f\u0627\u0629 \u0627\u0644\u0627\u0646\u062a\u0642\u0627\u0621 \u0627\u0644\u0645\u062d\u062f\u0651\u062f\u0629.", "View": "\u0639\u0631\u0636", @@ -1778,6 +1798,8 @@ "We weren't able to send you a password reset email.": "\u0639\u0630\u0631\u064b\u0627\u060c \u0644\u0645 \u0646\u062a\u0645\u0643\u0651\u0646 \u0645\u0646 \u0645\u0631\u0627\u0633\u0644\u062a\u0643 \u0639\u0628\u0631 \u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0644\u062a\u063a\u064a\u064a\u0631 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631. ", "We're sorry, there was an error": "\u0646\u0623\u0633\u0641 \u0644\u062d\u062f\u0648\u062b \u062e\u0637\u0623. ", "We've encountered an error. Refresh your browser and then try again.": "\u0646\u0623\u0633\u0641 \u0644\u062d\u062f\u0648\u062b \u062e\u0637\u0623. \u064a\u064f\u062c\u0631\u0649 \u0625\u0639\u0627\u062f\u0629 \u0641\u062a\u062d \u0645\u062a\u0635\u0641\u0651\u062d\u0643 \u062b\u0645\u0651 \u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u0645\u062d\u0627\u0648\u0644\u0629.", + "We've sent a confirmation message to {new_email_address}. Click the link in the ": "\u0642\u0645\u0646\u0627 \u0628\u0625\u0631\u0633\u0627\u0644 \u0631\u0633\u0627\u0644\u0629 \u062a\u0623\u0643\u064a\u062f \u0625\u0644\u0649 {new_email_address}. \u0642\u0645 \u0628\u0627\u0644\u0646\u0642\u0631 \u0639\u0644\u0649 \u0627\u0644\u0631\u0627\u0628\u0637 \u0627\u0644\u0645\u0648\u062c\u0648\u062f \u0641\u064a", + "We've sent a message to {email_address}. Click the link in the message to reset ": "\u0642\u0645\u0646\u0627 \u0628\u0625\u0631\u0633\u0627\u0644 \u0631\u0633\u0627\u0644\u0629 \u0625\u0644\u0649 {email_address}. \u0642\u0645 \u0628\u0627\u0644\u0646\u0642\u0631 \u0639\u0644\u0649 \u0627\u0644\u0631\u0627\u0628\u0637 \u0627\u0644\u0645\u0648\u062c\u0648\u062f \u0641\u064a \u0627\u0644\u0631\u0633\u0627\u0644\u0629 \u0644\u0644\u062a\u063a\u064a\u064a\u0631", "We've sent instructions for resetting your password to the email address you provided.": "\u0623\u0631\u0633\u0644\u0646\u0627 \u0644\u0643 \u0627\u0644\u062a\u0639\u0644\u064a\u0645\u0627\u062a \u0627\u0644\u0644\u0627\u0632\u0645\u0629 \u0644\u062a\u0639\u064a\u062f \u0636\u0628\u0637 \u0643\u0644\u0645\u0629 \u0645\u0631\u0648\u0631\u0643 \u0644\u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0627\u0644\u0630\u064a \u062d\u062f\u0651\u062f\u062a\u0647. ", "Web:": "\u0627\u0644\u0648\u064a\u0628:", "Webcam": "\u0643\u0627\u0645\u064a\u0631\u0627 \u0627\u0644\u0648\u064a\u0628 ", @@ -1786,6 +1808,7 @@ "What does %(platformName)s do with this photo?": "\u0645\u0627 \u0627\u0644\u0630\u064a \u062a\u0641\u0639\u0644\u0647 %(platformName)s \u0628\u0647\u0630\u0647 \u0627\u0644\u0635\u0648\u0631\u0629\u061f", "What does this mean?": "\u0645\u0627\u0630\u0627 \u064a\u0639\u0646\u064a \u0647\u0630\u0627\u061f", "What's Your Next Accomplishment?": "\u0645\u0627\u0647\u0648 \u0625\u0646\u062c\u0627\u0632\u0643 \u0627\u0644\u0642\u0627\u062f\u0645\u061f", + "When you click \"Reset Your Password\", edX will send a message ": "\u0633\u062a\u0635\u0644\u0643 \u0631\u0633\u0627\u0644\u0629 \u0639\u0644\u0649 \u0628\u0631\u064a\u062f\u0643 \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0639\u0646\u062f \u0627\u0644\u0646\u0642\u0631 \u0639\u0644\u0649 \"\u0625\u0639\u0627\u062f\u0629 \u0636\u0628\u0637 \u0643\u0644\u0645\u0629 \u0627\u0644\u0633\u0631\"", "When your face is in position, use the camera button {icon} below to take your photo.": "\u0639\u0646\u062f\u0645\u0627 \u064a\u0643\u0648\u0646 \u0648\u062c\u0647\u0643 \u0641\u064a \u0627\u0644\u0645\u0643\u0627\u0646 \u0627\u0644\u0635\u062d\u064a\u062d\u060c \u0627\u0633\u062a\u062e\u062f\u0645 {icon} \u0627\u0644\u0643\u0627\u0645\u064a\u0631\u0627 \u0623\u062f\u0646\u0627\u0647 \u0644\u0627\u0644\u062a\u0642\u0627\u0637 \u0635\u0648\u0631\u062a\u0643.", "Which timed transcript would you like to use?": "\u0645\u0627 \u0647\u0648 \u0627\u0644\u0646\u0635 \u0645\u062d\u062f\u0651\u064e\u062f \u0627\u0644\u062a\u0648\u0642\u064a\u062a \u0627\u0644\u0630\u064a \u062a\u0631\u063a\u0628 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645\u0647\u061f", "Whole words": "\u0643\u0644\u0645\u0627\u062a \u0643\u0627\u0645\u0644\u0629 ", @@ -1810,10 +1833,12 @@ "You are not enrolled in any XSeries Programs yet.": "\u0623\u0646\u062a \u0644\u0633\u062a \u0645\u0633\u062c\u0644\u0627\u064b \u0641\u064a \u0623\u064a \u0645\u0646 \u0628\u0631\u0627\u0645\u062c XSeries.", "You are now enrolled as a verified student for:": "\u0623\u0646\u062a \u0627\u0644\u0622\u0646 \u0645\u0633\u062c\u0651\u0650\u0644 \u0643\u0637\u0627\u0644\u0628 \u0645\u0648\u062b\u0651\u064e\u0642 \u0644\u062f\u0649: ", "You are upgrading your enrollment for: {courseName}": "\u0623\u0646\u062a \u062a\u0637\u0648\u0631 \u0627\u0634\u062a\u0631\u0627\u0643\u0643 \u0641\u064a: {courseName}", + "You can link your social media accounts to your edX account to make signing in to edx.org ": "\u064a\u0645\u0643\u0646\u0643 \u0631\u0628\u0637 \u062d\u0633\u0627\u0628\u0627\u062a\u0643 \u0639\u0644\u0649 \u0634\u0628\u0643\u0627\u062a \u0627\u0644\u062a\u0648\u0627\u0635\u0644 \u0627\u0644\u0627\u062c\u062a\u0645\u0627\u0639\u064a \u0628\u0647\u0630\u0627 \u0627\u0644\u062d\u0633\u0627\u0628 \u0644\u062a\u0633\u0647\u064a\u0644 \u0639\u0645\u0644\u064a\u0629 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0644\u0627\u062d\u0642\u0627\u064b", "You can now enter your payment information and complete your enrollment.": "\u064a\u0645\u0643\u0646\u0643 \u0627\u0644\u0622\u0646 \u0625\u062f\u062e\u0627\u0644 \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u0627\u0644\u062f\u0641\u0639 \u0648\u0627\u0633\u062a\u0643\u0645\u0627\u0644 \u062a\u0633\u062c\u064a\u0644\u0643. ", "You can pay now even if you don't have the following items available, but you will need to have these by %(date)s to qualify to earn a Verified Certificate.": "\u064a\u0645\u0643\u0646\u0643 \u0623\u0646 \u062a\u062f\u0641\u0639 \u0627\u0644\u0622\u0646 \u062d\u062a\u0649 \u0644\u0645 \u0644\u0645 \u062a\u062a\u0648\u0641\u0651\u0631 \u0644\u062f\u064a\u0643 \u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u062a\u0627\u0644\u064a\u0629\u060c \u0644\u0643\u0646 \u064a\u062c\u0628 \u0639\u0644\u064a\u0643 \u062a\u0648\u0641\u064a\u0631\u0647\u0627 \u0628\u062d\u0644\u0648\u0644 %(date)s \u0645\u0646 \u0623\u062c\u0644 \u0627\u0644\u062a\u0623\u0647\u0651\u0644 \u0644\u0646\u064a\u0644 \"\u0634\u0647\u0627\u062f\u0629 \u0645\u0648\u062b\u0651\u0642\u0629\". ", "You can pay now even if you don't have the following items available, but you will need to have these to qualify to earn a Verified Certificate.": "\u064a\u0645\u0643\u0646\u0643 \u0623\u0646 \u062a\u062f\u0641\u0639 \u0627\u0644\u0622\u0646 \u062d\u062a\u0649 \u0644\u0645 \u0644\u0645 \u062a\u062a\u0648\u0641\u0651\u0631 \u0644\u062f\u064a\u0643 \u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u062a\u0627\u0644\u064a\u0629\u060c \u0644\u0643\u0646 \u064a\u062c\u0628 \u0639\u0644\u064a\u0643 \u062a\u0648\u0641\u064a\u0631\u0647\u0627 \u0645\u0646 \u0623\u062c\u0644 \u0627\u0644\u062a\u0623\u0647\u0651\u0644 \u0644\u0646\u064a\u0644 \"\u0634\u0647\u0627\u062f\u0629 \u0645\u0648\u062b\u0651\u0642\u0629\". ", "You can remove members from this team, especially if they have not participated in the team's activity.": "\u064a\u0645\u0643\u0646\u0643 \u0627\u0633\u062a\u0628\u0639\u0627\u062f \u0623\u0639\u0636\u0627\u0621 \u0645\u0646 \u0647\u0630\u0627 \u0627\u0644\u0641\u0631\u064a\u0642\u060c \u0648\u062e\u0627\u0635\u0629\u064b \u0641\u064a \u062d\u0627\u0644 \u0639\u062f\u0645 \u0645\u0634\u0627\u0631\u0643\u062a\u0647\u0645 \u0628\u0623\u0646\u0634\u0637\u0629 \u0627\u0644\u0641\u0631\u064a\u0642.", + "You can use your {accountName} account to sign in to your edX account.": "\u064a\u0645\u0643\u0646\u0643 \u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u062d\u0633\u0627\u0628\u0643 \u0639\u0644\u0649 {accountName} \u0644\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0625\u0644\u0649 \u062d\u0633\u0627\u0628\u0643.", "You changed a video URL, but did not change the timed transcript file. Do you want to use the current timed transcript or upload a new .srt transcript file?": "\u0644\u0642\u062f \u0642\u064f\u0645\u062a \u0628\u062a\u063a\u064a\u064a\u0631 \u0631\u0627\u0628\u0637 \u0627\u0644\u0641\u064a\u062f\u064a\u0648 \u062f\u0648\u0646 \u0623\u0646 \u062a\u063a\u064a\u0651\u0631 \u0645\u0644\u0641 \u0627\u0644\u0646\u0635 \u0645\u062d\u062f\u0651\u064e\u062f \u0627\u0644\u062a\u0648\u0642\u064a\u062a \u0627\u0644\u0645\u0631\u062a\u0628\u0637 \u0628\u0647. \u0647\u0644 \u062a\u0631\u063a\u0628 \u0641\u064a \u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0627\u0644\u0646\u0635 \u0645\u062d\u062f\u0651\u064e\u062f \u0627\u0644\u062a\u0648\u0642\u064a\u062a \u0627\u0644\u062d\u0627\u0644\u064a \u0623\u0648 \u062a\u062d\u0645\u064a\u0644 \u0645\u0644\u0641 \u0646\u0635 \u062c\u062f\u064a\u062f \u0628\u0635\u064a\u063a\u0629 .srt\u061f", "You commented...": "\u0643\u0627\u0646 \u062a\u0639\u0644\u064a\u0642\u0643...", "You currently have no cohorts configured": "\u0644\u064a\u0633 \u0644\u062f\u064a\u0643 \u062d\u0627\u0644\u064a\u0651\u064b\u0627 \u0623\u064a \u0634\u0639\u0628 \u0645\u0636\u0628\u0648\u0637\u0629 ", @@ -1954,13 +1979,14 @@ "or sign in with": "\u0623\u0648 \u0633\u062c\u0651\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645", "post anonymously": "\u0627\u0646\u0634\u064f\u0631 \u0645\u0646 \u062f\u0648\u0646 \u0627\u0644\u0643\u0634\u0641 \u0639\u0646 \u0627\u0644\u0647\u0648\u064a\u0629 ", "post anonymously to classmates": "\u0627\u0646\u0634\u0631 \u0623\u0645\u0627\u0645 \u0627\u0644\u0632\u0645\u0644\u0627\u0621 \u0645\u0646 \u062f\u0648\u0646 \u0627\u0644\u0643\u0634\u0641 \u0639\u0646 \u0627\u0644\u0647\u0648\u064a\u0629 ", - "posted %(time_ago)s by %(author)s": "\u0646\u064f\u0634\u0650\u0631 %(time_ago)s \u0645\u0646 \u0642\u0650\u0628\u0644 %(author)s", + "posted %(time_ago)s by %(author)s": "\u0645\u0646\u0634\u0648\u0631 %(author)s \u0628\u0648\u0627\u0633\u0637\u0629 %(time_ago)s", "price": "\u0627\u0644\u0633\u0639\u0631", "provide the title/name of the chapter that will be used in navigating": "\u062d\u062f\u0651\u062f \u0639\u0646\u0648\u0627\u0646/ \u0627\u0633\u0645 \u0627\u0644\u0641\u0635\u0644 \u0627\u0644\u0630\u064a \u0633\u064a\u064f\u0633\u062a\u062e\u062f\u0645 \u0641\u064a \u0627\u0644\u062a\u0635\u0641\u0651\u062d ", "provide the title/name of the text book as you would like your students to see it": "\u062d\u062f\u0651\u062f \u0639\u0646\u0648\u0627\u0646/\u0627\u0633\u0645 \u0627\u0644\u0643\u062a\u0627\u0628 \u0643\u0645\u0627 \u062a\u0631\u064a\u062f \u0623\u0646 \u064a\u0631\u0627\u0647 \u0637\u0644\u0627\u0628\u0651\u0643", "remove": "\u062d\u0630\u0641", "remove all": "\u062d\u0630\u0641 \u0627\u0644\u0643\u0644", "section": "\u0642\u0633\u0645", + "section.subtitle": "section.subtitle", "section.title": "section.title", "send an email message to {email}": "\u0623\u0631\u0633\u0644 \u0631\u0633\u0627\u0644\u0629 \u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a\u0629 \u0625\u0644\u0649 \u0627\u0644\u0639\u0646\u0648\u0627\u0646 {email} ", "status": "\u0627\u0644\u062d\u0627\u0644\u0629", @@ -1985,6 +2011,7 @@ "with %(release_date_from)s": "\u0645\u0639 %(release_date_from)s", "with %(section_or_subsection)s": "\u0645\u0639 %(section_or_subsection)s", "{browse_span_start}Browse teams in other topics{span_end} or {search_span_start}search teams{span_end} in this topic. If you still can't find a team to join, {create_span_start}create a new team in this topic{span_end}.": "{browse_span_start}\u062a\u0635\u0641\u0651\u062d \u0641\u0631\u0642 \u0641\u064a \u0645\u0648\u0636\u0648\u0639\u0627\u062a \u0623\u062e\u0631\u0649{span_end} \u0623\u0648 {search_span_start} \u0627\u0628\u062d\u062b \u0641\u064a \u0627\u0644\u0641\u0631\u0642{span_end} \u0636\u0645\u0646 \u0647\u0630\u0627 \u0627\u0644\u0645\u0648\u0636\u0648\u0639. \u0641\u064a \u062d\u0627\u0644 \u0644\u0645 \u062a\u062a\u0645\u0643\u0651\u0646 \u0645\u0646 \u0625\u064a\u062c\u0627\u062f \u0641\u0631\u064a\u0642 \u0644\u0644\u0627\u0646\u0636\u0645\u0627\u0645 \u0625\u0644\u064a\u0647\u060c {create_span_start}\u0623\u0646\u0634\u0626 \u0641\u0631\u064a\u0642\u064b\u0627 \u062c\u062f\u064a\u062f\u064b\u0627 \u0636\u0645\u0646 \u0647\u0630\u0627 \u0627\u0644\u0645\u0648\u0636\u0648\u0639{span_end}.", + "{category}\\'s program": "\u0628\u0631\u0627\u0645\u062c \u0627\u0644{category}", "{email} is already on the {container} team. Recheck the email address if you want to add a new member.": "{email} \u0647\u0648 \u0639\u0636\u0648 \u0645\u0633\u062c\u0651\u064e\u0644 \u0645\u0646 \u0642\u0628\u0644 \u0641\u064a \u0641\u0631\u064a\u0642 {container}. \u064a\u064f\u0631\u062c\u0649 \u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u062a\u062d\u0642\u0651\u0642 \u0645\u0646 \u0639\u0646\u0648\u0627\u0646 \u0627\u0644\u0628\u0631\u064a\u062f \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a \u0625\u0630\u0627 \u0623\u0631\u062f\u062a \u0625\u0636\u0627\u0641\u0629 \u0639\u0636\u0648 \u062c\u062f\u064a\u062f.", "{hours}:{minutes} (current UTC time)": "{hours}:{minutes} (\u062a\u0648\u0642\u064a\u062a \u063a\u0631\u064a\u0646\u062a\u0634 \u0627\u0644\u062d\u0627\u0644\u064a)", "{numMoved} student was removed from {oldCohort}": [ @@ -2011,6 +2038,7 @@ "\u062a\u0645 \u0625\u0636\u0627\u0641\u0629 {numUsersAdded} \u0637\u0627\u0644\u0628 \u0644\u0647\u0630\u0647 \u0627\u0644\u0634\u0639\u0628\u0629.", "\u0623\u064f\u0636\u064a\u0641 {numUsersAdded} \u0637\u0627\u0644\u0628 \u0625\u0644\u0649 \u0647\u0630\u0647 \u0627\u0644\u0634\u0639\u0628\u0629." ], + "{organization}\\'s logo": "\u0634\u0639\u0627\u0631 \u0627\u0644{organization}", "{platform_name} learners can see my:": "\u064a\u0645\u0643\u0646 \u0644\u0644\u0645\u062a\u0639\u0644\u0651\u0645\u064a\u0646 \u0641\u064a \u0645\u0646\u0635\u0651\u0629 {platform_name} \u0631\u0624\u064a\u0629:", "{screen_reader_start}Warning:{screen_reader_end} No content groups exist.": "{screen_reader_start}\u062a\u062d\u0630\u064a\u0631:{screen_reader_end} \u062a\u0639\u0630\u0651\u0631 \u0625\u064a\u062c\u0627\u062f \u0645\u062c\u0645\u0648\u0639\u0627\u062a \u0645\u062d\u062a\u0648\u0649.", "{screen_reader_start}Warning:{screen_reader_end} The previously selected content group was deleted. Select another content group.": "{screen_reader_start}\u062a\u062d\u0630\u064a\u0631:{screen_reader_end} \u062d\u0651\u0630\u0641\u062a \u0645\u062c\u0645\u0648\u0639\u0629 \u0627\u0644\u0645\u062d\u062a\u0648\u0649 \u0627\u0644\u0645\u062d\u062f\u0651\u062f\u0629 \u0633\u0627\u0628\u0642\u064b\u0627. \u064a\u064f\u0631\u062c\u0649 \u0627\u062e\u062a\u064a\u0627\u0631 \u0645\u062c\u0645\u0648\u0639\u0629 \u0645\u062d\u062a\u0648\u0649 \u0623\u062e\u0631\u0649.", diff --git a/cms/static/js/i18n/eo/djangojs.js b/cms/static/js/i18n/eo/djangojs.js index febbf46113..5dd968d7bd 100644 --- a/cms/static/js/i18n/eo/djangojs.js +++ b/cms/static/js/i18n/eo/djangojs.js @@ -172,10 +172,12 @@ "Add URLs for additional versions": "\u00c0dd \u00dbRLs f\u00f6r \u00e4dd\u00eft\u00ef\u00f6n\u00e4l v\u00e9rs\u00ef\u00f6ns \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454#", "Add a Chapter": "\u00c0dd \u00e4 \u00c7h\u00e4pt\u00e9r \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", "Add a New Cohort": "\u00c0dd \u00e4 N\u00e9w \u00c7\u00f6h\u00f6rt \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c#", + "Add a Post": "\u00c0dd \u00e4 P\u00f6st \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3#", "Add a Response": "\u00c0dd \u00e4 R\u00e9sp\u00f6ns\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442#", "Add a clear and descriptive title to encourage participation.": "\u00c0dd \u00e4 \u00e7l\u00e9\u00e4r \u00e4nd d\u00e9s\u00e7r\u00efpt\u00efv\u00e9 t\u00eftl\u00e9 t\u00f6 \u00e9n\u00e7\u00f6\u00fcr\u00e4g\u00e9 p\u00e4rt\u00ef\u00e7\u00efp\u00e4t\u00ef\u00f6n. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "Add a comment": "\u00c0dd \u00e4 \u00e7\u00f6mm\u00e9nt \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", "Add a learning outcome here": "\u00c0dd \u00e4 l\u00e9\u00e4rn\u00efng \u00f6\u00fct\u00e7\u00f6m\u00e9 h\u00e9r\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454#", + "Add a response:": "\u00c0dd \u00e4 r\u00e9sp\u00f6ns\u00e9: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1#", "Add another group": "\u00c0dd \u00e4n\u00f6th\u00e9r gr\u00f6\u00fcp \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454#", "Add language": "\u00c0dd l\u00e4ng\u00fc\u00e4g\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", "Add notes about this learner": "\u00c0dd n\u00f6t\u00e9s \u00e4\u00df\u00f6\u00fct th\u00efs l\u00e9\u00e4rn\u00e9r \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2#", @@ -206,6 +208,7 @@ "All flags have been removed. To undo, uncheck the box.": "\u00c0ll fl\u00e4gs h\u00e4v\u00e9 \u00df\u00e9\u00e9n r\u00e9m\u00f6v\u00e9d. T\u00f6 \u00fcnd\u00f6, \u00fcn\u00e7h\u00e9\u00e7k th\u00e9 \u00df\u00f6x. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "All groups must have a name.": "\u00c0ll gr\u00f6\u00fcps m\u00fcst h\u00e4v\u00e9 \u00e4 n\u00e4m\u00e9. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2#", "All groups must have a unique name.": "\u00c0ll gr\u00f6\u00fcps m\u00fcst h\u00e4v\u00e9 \u00e4 \u00fcn\u00efq\u00fc\u00e9 n\u00e4m\u00e9. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442#", + "All learners in the {cohort_name} cohort": "\u00c0ll l\u00e9\u00e4rn\u00e9rs \u00efn th\u00e9 {cohort_name} \u00e7\u00f6h\u00f6rt \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442#", "All learners who are enrolled in this course": "\u00c0ll l\u00e9\u00e4rn\u00e9rs wh\u00f6 \u00e4r\u00e9 \u00e9nr\u00f6ll\u00e9d \u00efn th\u00efs \u00e7\u00f6\u00fcrs\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f #", "All payment options are currently unavailable.": "\u00c0ll p\u00e4\u00fdm\u00e9nt \u00f6pt\u00ef\u00f6ns \u00e4r\u00e9 \u00e7\u00fcrr\u00e9ntl\u00fd \u00fcn\u00e4v\u00e4\u00efl\u00e4\u00dfl\u00e9. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "All professional education courses are fee-based, and require payment to complete the enrollment process.": "\u00c0ll pr\u00f6f\u00e9ss\u00ef\u00f6n\u00e4l \u00e9d\u00fc\u00e7\u00e4t\u00ef\u00f6n \u00e7\u00f6\u00fcrs\u00e9s \u00e4r\u00e9 f\u00e9\u00e9-\u00df\u00e4s\u00e9d, \u00e4nd r\u00e9q\u00fc\u00efr\u00e9 p\u00e4\u00fdm\u00e9nt t\u00f6 \u00e7\u00f6mpl\u00e9t\u00e9 th\u00e9 \u00e9nr\u00f6llm\u00e9nt pr\u00f6\u00e7\u00e9ss. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 #", @@ -476,7 +479,7 @@ "Custom...": "\u00c7\u00fcst\u00f6m... \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142#", "Cut": "\u00c7\u00fct \u2c60'\u03c3\u044f\u0454\u043c#", "Cut row": "\u00c7\u00fct r\u00f6w \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c #", - "DISCUSSION HOME:": "D\u00ccS\u00c7\u00dbSS\u00cc\u00d6N H\u00d6M\u00c9: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c#", + "Dashboard": "D\u00e4sh\u00df\u00f6\u00e4rd \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142#", "Date": "D\u00e4t\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9#", "Date Added": "D\u00e4t\u00e9 \u00c0dd\u00e9d \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3#", "Date added": "D\u00e4t\u00e9 \u00e4dd\u00e9d \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3#", @@ -515,6 +518,7 @@ "Discard Changes": "D\u00efs\u00e7\u00e4rd \u00c7h\u00e4ng\u00e9s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1#", "Discarding Changes": "D\u00efs\u00e7\u00e4rd\u00efng \u00c7h\u00e4ng\u00e9s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442#", "Discussion": "D\u00efs\u00e7\u00fcss\u00ef\u00f6n \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3#", + "Discussion Home": "D\u00efs\u00e7\u00fcss\u00ef\u00f6n H\u00f6m\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1#", "Discussion admins, moderators, and TAs can make their posts visible to all students or specify a single cohort.": "D\u00efs\u00e7\u00fcss\u00ef\u00f6n \u00e4dm\u00efns, m\u00f6d\u00e9r\u00e4t\u00f6rs, \u00e4nd T\u00c0s \u00e7\u00e4n m\u00e4k\u00e9 th\u00e9\u00efr p\u00f6sts v\u00efs\u00ef\u00dfl\u00e9 t\u00f6 \u00e4ll st\u00fcd\u00e9nts \u00f6r sp\u00e9\u00e7\u00eff\u00fd \u00e4 s\u00efngl\u00e9 \u00e7\u00f6h\u00f6rt. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f #", "Discussion topics; currently listing: ": "D\u00efs\u00e7\u00fcss\u00ef\u00f6n t\u00f6p\u00ef\u00e7s; \u00e7\u00fcrr\u00e9ntl\u00fd l\u00efst\u00efng: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f#", "Display Name": "D\u00efspl\u00e4\u00fd N\u00e4m\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", @@ -918,6 +922,7 @@ "Muted": "M\u00fct\u00e9d \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455#", "My Bookmarks": "M\u00fd B\u00f6\u00f6km\u00e4rks \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", "My Notes": "M\u00fd N\u00f6t\u00e9s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202#", + "My Orders": "M\u00fd \u00d6rd\u00e9rs \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142#", "My Team": "M\u00fd T\u00e9\u00e4m \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c #", "N/A": "N/\u00c0 \u2c60'\u03c3\u044f\u0454\u043c#", "Name": "N\u00e4m\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9#", @@ -930,7 +935,6 @@ "New %(component_type)s": "N\u00e9w %(component_type)s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c #", "New %(item_type)s": "N\u00e9w %(item_type)s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c #", "New Address": "N\u00e9w \u00c0ddr\u00e9ss \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f #", - "New Post": "N\u00e9w P\u00f6st \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202#", "New document": "N\u00e9w d\u00f6\u00e7\u00fcm\u00e9nt \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", "New enrollment mode:": "N\u00e9w \u00e9nr\u00f6llm\u00e9nt m\u00f6d\u00e9: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, #", "New to %(platformName)s?": "N\u00e9w t\u00f6 %(platformName)s? \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f #", @@ -976,6 +980,9 @@ "Numbered List (Ctrl+O)": "N\u00fcm\u00df\u00e9r\u00e9d L\u00efst (\u00c7trl+\u00d6) \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2#", "Numbered list": "N\u00fcm\u00df\u00e9r\u00e9d l\u00efst \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", "OK": "\u00d6K \u2c60'\u03c3\u044f#", + "ORDER NAME": "\u00d6RD\u00c9R N\u00c0M\u00c9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3#", + "ORDER NUMBER": "\u00d6RD\u00c9R N\u00dbMB\u00c9R \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", + "ORDER PLACED": "\u00d6RD\u00c9R PL\u00c0\u00c7\u00c9D \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", "Ok": "\u00d6k \u2c60'\u03c3\u044f#", "Once in position, use the camera button {icon} to capture your ID": "\u00d6n\u00e7\u00e9 \u00efn p\u00f6s\u00eft\u00ef\u00f6n, \u00fcs\u00e9 th\u00e9 \u00e7\u00e4m\u00e9r\u00e4 \u00df\u00fctt\u00f6n {icon} t\u00f6 \u00e7\u00e4pt\u00fcr\u00e9 \u00fd\u00f6\u00fcr \u00ccD \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "Once in position, use the camera button {icon} to capture your photo": "\u00d6n\u00e7\u00e9 \u00efn p\u00f6s\u00eft\u00ef\u00f6n, \u00fcs\u00e9 th\u00e9 \u00e7\u00e4m\u00e9r\u00e4 \u00df\u00fctt\u00f6n {icon} t\u00f6 \u00e7\u00e4pt\u00fcr\u00e9 \u00fd\u00f6\u00fcr ph\u00f6t\u00f6 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", @@ -990,6 +997,8 @@ "Optional Characteristics": "\u00d6pt\u00ef\u00f6n\u00e4l \u00c7h\u00e4r\u00e4\u00e7t\u00e9r\u00efst\u00ef\u00e7s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7#", "Optional long description": "\u00d6pt\u00ef\u00f6n\u00e4l l\u00f6ng d\u00e9s\u00e7r\u00efpt\u00ef\u00f6n \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455#", "Options for {license_name}": "\u00d6pt\u00ef\u00f6ns f\u00f6r {license_name} \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1#", + "Order Details": "\u00d6rd\u00e9r D\u00e9t\u00e4\u00efls \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", + "Order History": "\u00d6rd\u00e9r H\u00efst\u00f6r\u00fd \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", "Order No.": "\u00d6rd\u00e9r N\u00f6. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142#", "Organization": "\u00d6rg\u00e4n\u00efz\u00e4t\u00ef\u00f6n \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", "Organization ": "\u00d6rg\u00e4n\u00efz\u00e4t\u00ef\u00f6n \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", @@ -1063,7 +1072,6 @@ "Please verify that you have uploaded a valid image (PNG and JPEG).": "Pl\u00e9\u00e4s\u00e9 v\u00e9r\u00eff\u00fd th\u00e4t \u00fd\u00f6\u00fc h\u00e4v\u00e9 \u00fcpl\u00f6\u00e4d\u00e9d \u00e4 v\u00e4l\u00efd \u00efm\u00e4g\u00e9 (PNG \u00e4nd JP\u00c9G). \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f #", "Please verify that your webcam is connected and that you have allowed your browser to access it.": "Pl\u00e9\u00e4s\u00e9 v\u00e9r\u00eff\u00fd th\u00e4t \u00fd\u00f6\u00fcr w\u00e9\u00df\u00e7\u00e4m \u00efs \u00e7\u00f6nn\u00e9\u00e7t\u00e9d \u00e4nd th\u00e4t \u00fd\u00f6\u00fc h\u00e4v\u00e9 \u00e4ll\u00f6w\u00e9d \u00fd\u00f6\u00fcr \u00dfr\u00f6ws\u00e9r t\u00f6 \u00e4\u00e7\u00e7\u00e9ss \u00eft. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, #", "Post": "P\u00f6st \u2c60'\u03c3\u044f\u0454\u043c \u03b9#", - "Post a response:": "P\u00f6st \u00e4 r\u00e9sp\u00f6ns\u00e9: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c#", "Post body": "P\u00f6st \u00df\u00f6d\u00fd \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142#", "Post type:": "P\u00f6st t\u00fdp\u00e9: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3#", "Poster": "P\u00f6st\u00e9r \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5#", @@ -1203,6 +1211,7 @@ "Selected tab": "S\u00e9l\u00e9\u00e7t\u00e9d t\u00e4\u00df \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", "Send notification to mobile apps": "S\u00e9nd n\u00f6t\u00eff\u00ef\u00e7\u00e4t\u00ef\u00f6n t\u00f6 m\u00f6\u00df\u00efl\u00e9 \u00e4pps \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454#", "Send push notification to mobile apps": "S\u00e9nd p\u00fcsh n\u00f6t\u00eff\u00ef\u00e7\u00e4t\u00ef\u00f6n t\u00f6 m\u00f6\u00df\u00efl\u00e9 \u00e4pps \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5#", + "Send to:": "S\u00e9nd t\u00f6: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202#", "Sent By": "S\u00e9nt B\u00fd \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c #", "Sent By:": "S\u00e9nt B\u00fd: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202#", "Sent To": "S\u00e9nt T\u00f6 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c #", @@ -1285,6 +1294,7 @@ "Started entrance exam rescore task for student '{student_id}'. Click the 'Show Background Task History for Student' button to see the status of the task.": "St\u00e4rt\u00e9d \u00e9ntr\u00e4n\u00e7\u00e9 \u00e9x\u00e4m r\u00e9s\u00e7\u00f6r\u00e9 t\u00e4sk f\u00f6r st\u00fcd\u00e9nt '{student_id}'. \u00c7l\u00ef\u00e7k th\u00e9 'Sh\u00f6w B\u00e4\u00e7kgr\u00f6\u00fcnd T\u00e4sk H\u00efst\u00f6r\u00fd f\u00f6r St\u00fcd\u00e9nt' \u00df\u00fctt\u00f6n t\u00f6 s\u00e9\u00e9 th\u00e9 st\u00e4t\u00fcs \u00f6f th\u00e9 t\u00e4sk. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1\u2202\u03b9\u03c1\u03b9\u0455\u03b9\u00a2\u03b9\u03b7g \u0454\u0142\u03b9\u0442, \u0455\u0454\u2202 \u2202\u03c3 \u0454\u03b9\u03c5\u0455\u043c\u03c3\u2202 \u0442\u0454\u043c\u03c1\u03c3\u044f \u03b9\u03b7\u00a2\u03b9\u2202\u03b9\u2202\u03c5\u03b7\u0442 \u03c5\u0442 \u0142\u03b1\u0432\u03c3\u044f\u0454 \u0454\u0442 \u2202\u03c3\u0142\u03c3\u044f\u0454 \u043c\u03b1g\u03b7\u03b1 \u03b1\u0142\u03b9q\u03c5\u03b1. \u03c5\u0442 \u0454\u03b7\u03b9\u043c \u03b1\u2202 \u043c\u03b9\u03b7\u03b9\u043c \u03bd\u0454\u03b7\u03b9\u03b1\u043c, q\u03c5\u03b9\u0455 \u03b7\u03c3\u0455\u0442\u044f\u03c5\u2202 \u0454\u03c7\u0454\u044f\u00a2\u03b9\u0442\u03b1\u0442\u03b9\u03c3\u03b7 \u03c5\u0142\u0142\u03b1\u043c\u00a2\u03c3 \u0142\u03b1\u0432\u03c3\u044f\u03b9\u0455 \u03b7\u03b9\u0455\u03b9 \u03c5\u0442 \u03b1\u0142\u03b9q\u03c5\u03b9\u03c1 \u0454\u03c7 \u0454\u03b1 \u00a2\u03c3\u043c\u043c\u03c3\u2202\u03c3 \u00a2\u03c3\u03b7\u0455\u0454q\u03c5\u03b1\u0442. \u2202\u03c5\u03b9\u0455 \u03b1\u03c5\u0442\u0454 \u03b9\u044f\u03c5\u044f\u0454 \u2202\u03c3\u0142\u03c3\u044f \u03b9\u03b7 \u044f\u0454\u03c1\u044f\u0454\u043d\u0454\u03b7\u2202\u0454\u044f\u03b9\u0442 \u03b9\u03b7 \u03bd\u03c3\u0142\u03c5\u03c1\u0442\u03b1\u0442\u0454 \u03bd\u0454\u0142\u03b9\u0442 \u0454\u0455\u0455\u0454 \u00a2\u03b9\u0142\u0142\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f\u0454 \u0454\u03c5 \u0192\u03c5g\u03b9\u03b1\u0442 \u03b7\u03c5\u0142\u0142\u03b1 \u03c1\u03b1\u044f\u03b9\u03b1\u0442\u03c5\u044f. \u0454\u03c7\u00a2\u0454\u03c1\u0442\u0454\u03c5\u044f \u0455\u03b9\u03b7\u0442 \u03c3\u00a2\u00a2\u03b1\u0454\u00a2\u03b1\u0442 \u00a2\u03c5\u03c1\u03b9\u2202\u03b1\u0442\u03b1\u0442 \u03b7\u03c3\u03b7 \u03c1\u044f\u03c3\u03b9\u2202\u0454\u03b7\u0442, \u0455\u03c5\u03b7\u0442 \u03b9\u03b7 \u00a2\u03c5\u0142\u03c1\u03b1 q\u03c5\u03b9 \u03c3\u0192\u0192\u03b9\u00a2\u03b9\u03b1 \u2202\u0454\u0455\u0454\u044f\u03c5\u03b7\u0442 \u043c\u03c3\u0142\u0142\u03b9\u0442 \u03b1\u03b7\u03b9\u043c \u03b9\u2202 \u0454#", "Started rescore problem task for problem '<%= problem_id %>' and student '<%= student_id %>'. Click the 'Show Background Task History for Student' button to see the status of the task.": "St\u00e4rt\u00e9d r\u00e9s\u00e7\u00f6r\u00e9 pr\u00f6\u00dfl\u00e9m t\u00e4sk f\u00f6r pr\u00f6\u00dfl\u00e9m '<%= problem_id %>' \u00e4nd st\u00fcd\u00e9nt '<%= student_id %>'. \u00c7l\u00ef\u00e7k th\u00e9 'Sh\u00f6w B\u00e4\u00e7kgr\u00f6\u00fcnd T\u00e4sk H\u00efst\u00f6r\u00fd f\u00f6r St\u00fcd\u00e9nt' \u00df\u00fctt\u00f6n t\u00f6 s\u00e9\u00e9 th\u00e9 st\u00e4t\u00fcs \u00f6f th\u00e9 t\u00e4sk. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1\u2202\u03b9\u03c1\u03b9\u0455\u03b9\u00a2\u03b9\u03b7g \u0454\u0142\u03b9\u0442, \u0455\u0454\u2202 \u2202\u03c3 \u0454\u03b9\u03c5\u0455\u043c\u03c3\u2202 \u0442\u0454\u043c\u03c1\u03c3\u044f \u03b9\u03b7\u00a2\u03b9\u2202\u03b9\u2202\u03c5\u03b7\u0442 \u03c5\u0442 \u0142\u03b1\u0432\u03c3\u044f\u0454 \u0454\u0442 \u2202\u03c3\u0142\u03c3\u044f\u0454 \u043c\u03b1g\u03b7\u03b1 \u03b1\u0142\u03b9q\u03c5\u03b1. \u03c5\u0442 \u0454\u03b7\u03b9\u043c \u03b1\u2202 \u043c\u03b9\u03b7\u03b9\u043c \u03bd\u0454\u03b7\u03b9\u03b1\u043c, q\u03c5\u03b9\u0455 \u03b7\u03c3\u0455\u0442\u044f\u03c5\u2202 \u0454\u03c7\u0454\u044f\u00a2\u03b9\u0442\u03b1\u0442\u03b9\u03c3\u03b7 \u03c5\u0142\u0142\u03b1\u043c\u00a2\u03c3 \u0142\u03b1\u0432\u03c3\u044f\u03b9\u0455 \u03b7\u03b9\u0455\u03b9 \u03c5\u0442 \u03b1\u0142\u03b9q\u03c5\u03b9\u03c1 \u0454\u03c7 \u0454\u03b1 \u00a2\u03c3\u043c\u043c\u03c3\u2202\u03c3 \u00a2\u03c3\u03b7\u0455\u0454q\u03c5\u03b1\u0442. \u2202\u03c5\u03b9\u0455 \u03b1\u03c5\u0442\u0454 \u03b9\u044f\u03c5\u044f\u0454 \u2202\u03c3\u0142\u03c3\u044f \u03b9\u03b7 \u044f\u0454\u03c1\u044f\u0454\u043d\u0454\u03b7\u2202\u0454\u044f\u03b9\u0442 \u03b9\u03b7 \u03bd\u03c3\u0142\u03c5\u03c1\u0442\u03b1\u0442\u0454 \u03bd\u0454\u0142\u03b9\u0442 \u0454\u0455\u0455\u0454 \u00a2\u03b9\u0142\u0142\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f\u0454 \u0454\u03c5 \u0192\u03c5g\u03b9\u03b1\u0442 \u03b7\u03c5\u0142\u0142\u03b1 \u03c1\u03b1\u044f\u03b9\u03b1\u0442\u03c5\u044f. \u0454\u03c7\u00a2\u0454\u03c1\u0442\u0454\u03c5\u044f \u0455\u03b9\u03b7\u0442 \u03c3\u00a2\u00a2\u03b1\u0454\u00a2\u03b1\u0442 \u00a2\u03c5\u03c1\u03b9\u2202\u03b1\u0442\u03b1\u0442 \u03b7\u03c3\u03b7 \u03c1\u044f\u03c3\u03b9\u2202\u0454\u03b7\u0442, \u0455\u03c5\u03b7\u0442 \u03b9\u03b7 \u00a2\u03c5\u0142\u03c1\u03b1 q\u03c5\u03b9 \u03c3\u0192\u0192\u03b9\u00a2\u03b9\u03b1 \u2202\u0454\u0455\u0454\u044f\u03c5\u03b7\u0442 \u043c\u03c3#", "Starts": "St\u00e4rts \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5#", + "Starts %(start)s": "St\u00e4rts %(start)s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3#", "Starts: %(start)s": "St\u00e4rts: %(start)s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f #", "Starts: %(start_date)s": "St\u00e4rts: %(start_date)s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f #", "State": "St\u00e4t\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455#", @@ -1319,6 +1329,7 @@ "Successfully started task to reset attempts for problem '<%= problem_id %>'. Click the 'Show Background Task History for Problem' button to see the status of the task.": "S\u00fc\u00e7\u00e7\u00e9ssf\u00fcll\u00fd st\u00e4rt\u00e9d t\u00e4sk t\u00f6 r\u00e9s\u00e9t \u00e4tt\u00e9mpts f\u00f6r pr\u00f6\u00dfl\u00e9m '<%= problem_id %>'. \u00c7l\u00ef\u00e7k th\u00e9 'Sh\u00f6w B\u00e4\u00e7kgr\u00f6\u00fcnd T\u00e4sk H\u00efst\u00f6r\u00fd f\u00f6r Pr\u00f6\u00dfl\u00e9m' \u00df\u00fctt\u00f6n t\u00f6 s\u00e9\u00e9 th\u00e9 st\u00e4t\u00fcs \u00f6f th\u00e9 t\u00e4sk. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1\u2202\u03b9\u03c1\u03b9\u0455\u03b9\u00a2\u03b9\u03b7g \u0454\u0142\u03b9\u0442, \u0455\u0454\u2202 \u2202\u03c3 \u0454\u03b9\u03c5\u0455\u043c\u03c3\u2202 \u0442\u0454\u043c\u03c1\u03c3\u044f \u03b9\u03b7\u00a2\u03b9\u2202\u03b9\u2202\u03c5\u03b7\u0442 \u03c5\u0442 \u0142\u03b1\u0432\u03c3\u044f\u0454 \u0454\u0442 \u2202\u03c3\u0142\u03c3\u044f\u0454 \u043c\u03b1g\u03b7\u03b1 \u03b1\u0142\u03b9q\u03c5\u03b1. \u03c5\u0442 \u0454\u03b7\u03b9\u043c \u03b1\u2202 \u043c\u03b9\u03b7\u03b9\u043c \u03bd\u0454\u03b7\u03b9\u03b1\u043c, q\u03c5\u03b9\u0455 \u03b7\u03c3\u0455\u0442\u044f\u03c5\u2202 \u0454\u03c7\u0454\u044f\u00a2\u03b9\u0442\u03b1\u0442\u03b9\u03c3\u03b7 \u03c5\u0142\u0142\u03b1\u043c\u00a2\u03c3 \u0142\u03b1\u0432\u03c3\u044f\u03b9\u0455 \u03b7\u03b9\u0455\u03b9 \u03c5\u0442 \u03b1\u0142\u03b9q\u03c5\u03b9\u03c1 \u0454\u03c7 \u0454\u03b1 \u00a2\u03c3\u043c\u043c\u03c3\u2202\u03c3 \u00a2\u03c3\u03b7\u0455\u0454q\u03c5\u03b1\u0442. \u2202\u03c5\u03b9\u0455 \u03b1\u03c5\u0442\u0454 \u03b9\u044f\u03c5\u044f\u0454 \u2202\u03c3\u0142\u03c3\u044f \u03b9\u03b7 \u044f\u0454\u03c1\u044f\u0454\u043d\u0454\u03b7\u2202\u0454\u044f\u03b9\u0442 \u03b9\u03b7 \u03bd\u03c3\u0142\u03c5\u03c1\u0442\u03b1\u0442\u0454 \u03bd\u0454\u0142\u03b9\u0442 \u0454\u0455\u0455\u0454 \u00a2\u03b9\u0142\u0142\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f\u0454 \u0454\u03c5 \u0192\u03c5g\u03b9\u03b1\u0442 \u03b7\u03c5\u0142\u0142\u03b1 \u03c1\u03b1\u044f\u03b9\u03b1\u0442\u03c5\u044f. \u0454\u03c7\u00a2\u0454\u03c1\u0442\u0454\u03c5\u044f \u0455\u03b9\u03b7\u0442 \u03c3\u00a2\u00a2\u03b1\u0454\u00a2\u03b1\u0442 \u00a2\u03c5\u03c1\u03b9\u2202\u03b1\u0442\u03b1\u0442 \u03b7\u03c3\u03b7 \u03c1\u044f\u03c3\u03b9\u2202\u0454\u03b7\u0442, \u0455\u03c5\u03b7\u0442 \u03b9\u03b7 \u00a2\u03c5\u0142\u03c1\u03b1 q\u03c5\u03b9 \u03c3\u0192\u0192\u03b9\u00a2\u03b9\u03b1 \u2202\u0454\u0455\u0454\u044f\u03c5\u03b7\u0442 \u043c\u03c3\u0142\u0142\u03b9#", "Successfully unlinked.": "S\u00fc\u00e7\u00e7\u00e9ssf\u00fcll\u00fd \u00fcnl\u00efnk\u00e9d. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2#", "Superscript": "S\u00fcp\u00e9rs\u00e7r\u00efpt \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f #", + "TOTAL": "T\u00d6T\u00c0L \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455#", "Table": "T\u00e4\u00dfl\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455#", "Table properties": "T\u00e4\u00dfl\u00e9 pr\u00f6p\u00e9rt\u00ef\u00e9s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c#", "Tags": "T\u00e4gs \u2c60'\u03c3\u044f\u0454\u043c \u03b9#", @@ -1355,9 +1366,9 @@ "Textbook Name": "T\u00e9xt\u00df\u00f6\u00f6k N\u00e4m\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", "Textbook information": "T\u00e9xt\u00df\u00f6\u00f6k \u00efnf\u00f6rm\u00e4t\u00ef\u00f6n \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, #", "Textbook name is required": "T\u00e9xt\u00df\u00f6\u00f6k n\u00e4m\u00e9 \u00efs r\u00e9q\u00fc\u00efr\u00e9d \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455#", + "Thank you %(full_name)s! We have received your payment for %(course_name)s.": "Th\u00e4nk \u00fd\u00f6\u00fc %(full_name)s! W\u00e9 h\u00e4v\u00e9 r\u00e9\u00e7\u00e9\u00efv\u00e9d \u00fd\u00f6\u00fcr p\u00e4\u00fdm\u00e9nt f\u00f6r %(course_name)s. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "Thank you for submitting your financial assistance application for {course_name}! You can expect a response in 2-4 business days.": "Th\u00e4nk \u00fd\u00f6\u00fc f\u00f6r s\u00fc\u00dfm\u00eftt\u00efng \u00fd\u00f6\u00fcr f\u00efn\u00e4n\u00e7\u00ef\u00e4l \u00e4ss\u00efst\u00e4n\u00e7\u00e9 \u00e4ppl\u00ef\u00e7\u00e4t\u00ef\u00f6n f\u00f6r {course_name}! \u00dd\u00f6\u00fc \u00e7\u00e4n \u00e9xp\u00e9\u00e7t \u00e4 r\u00e9sp\u00f6ns\u00e9 \u00efn 2-4 \u00df\u00fcs\u00efn\u00e9ss d\u00e4\u00fds. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c#", "Thank you for submitting your photos. We will review them shortly. You can now sign up for any %(platformName)s course that offers verified certificates. Verification is good for one year. After one year, you must submit photos for verification again.": "Th\u00e4nk \u00fd\u00f6\u00fc f\u00f6r s\u00fc\u00dfm\u00eftt\u00efng \u00fd\u00f6\u00fcr ph\u00f6t\u00f6s. W\u00e9 w\u00efll r\u00e9v\u00ef\u00e9w th\u00e9m sh\u00f6rtl\u00fd. \u00dd\u00f6\u00fc \u00e7\u00e4n n\u00f6w s\u00efgn \u00fcp f\u00f6r \u00e4n\u00fd %(platformName)s \u00e7\u00f6\u00fcrs\u00e9 th\u00e4t \u00f6ff\u00e9rs v\u00e9r\u00eff\u00ef\u00e9d \u00e7\u00e9rt\u00eff\u00ef\u00e7\u00e4t\u00e9s. V\u00e9r\u00eff\u00ef\u00e7\u00e4t\u00ef\u00f6n \u00efs g\u00f6\u00f6d f\u00f6r \u00f6n\u00e9 \u00fd\u00e9\u00e4r. \u00c0ft\u00e9r \u00f6n\u00e9 \u00fd\u00e9\u00e4r, \u00fd\u00f6\u00fc m\u00fcst s\u00fc\u00dfm\u00eft ph\u00f6t\u00f6s f\u00f6r v\u00e9r\u00eff\u00ef\u00e7\u00e4t\u00ef\u00f6n \u00e4g\u00e4\u00efn. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1\u2202\u03b9\u03c1\u03b9\u0455\u03b9\u00a2\u03b9\u03b7g \u0454\u0142\u03b9\u0442, \u0455\u0454\u2202 \u2202\u03c3 \u0454\u03b9\u03c5\u0455\u043c\u03c3\u2202 \u0442\u0454\u043c\u03c1\u03c3\u044f \u03b9\u03b7\u00a2\u03b9\u2202\u03b9\u2202\u03c5\u03b7\u0442 \u03c5\u0442 \u0142\u03b1\u0432\u03c3\u044f\u0454 \u0454\u0442 \u2202\u03c3\u0142\u03c3\u044f\u0454 \u043c\u03b1g\u03b7\u03b1 \u03b1\u0142\u03b9q\u03c5\u03b1. \u03c5\u0442 \u0454\u03b7\u03b9\u043c \u03b1\u2202 \u043c\u03b9\u03b7\u03b9\u043c \u03bd\u0454\u03b7\u03b9\u03b1\u043c, q\u03c5\u03b9\u0455 \u03b7\u03c3\u0455\u0442\u044f\u03c5\u2202 \u0454\u03c7\u0454\u044f\u00a2\u03b9\u0442\u03b1\u0442\u03b9\u03c3\u03b7 \u03c5\u0142\u0142\u03b1\u043c\u00a2\u03c3 \u0142\u03b1\u0432\u03c3\u044f\u03b9\u0455 \u03b7\u03b9\u0455\u03b9 \u03c5\u0442 \u03b1\u0142\u03b9q\u03c5\u03b9\u03c1 \u0454\u03c7 \u0454\u03b1 \u00a2\u03c3\u043c\u043c\u03c3\u2202\u03c3 \u00a2\u03c3\u03b7\u0455\u0454q\u03c5\u03b1\u0442. \u2202\u03c5\u03b9\u0455 \u03b1\u03c5\u0442\u0454 \u03b9\u044f\u03c5\u044f\u0454 \u2202\u03c3\u0142\u03c3\u044f \u03b9\u03b7 \u044f\u0454\u03c1\u044f\u0454\u043d\u0454\u03b7\u2202\u0454\u044f\u03b9\u0442 \u03b9\u03b7 \u03bd\u03c3\u0142\u03c5\u03c1\u0442\u03b1\u0442\u0454 \u03bd\u0454\u0142\u03b9\u0442 \u0454\u0455\u0455\u0454#", - "Thank you! We have received your payment for %(course_name)s.": "Th\u00e4nk \u00fd\u00f6\u00fc! W\u00e9 h\u00e4v\u00e9 r\u00e9\u00e7\u00e9\u00efv\u00e9d \u00fd\u00f6\u00fcr p\u00e4\u00fdm\u00e9nt f\u00f6r %(course_name)s. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "Thank you! We have received your payment for {courseName}.": "Th\u00e4nk \u00fd\u00f6\u00fc! W\u00e9 h\u00e4v\u00e9 r\u00e9\u00e7\u00e9\u00efv\u00e9d \u00fd\u00f6\u00fcr p\u00e4\u00fdm\u00e9nt f\u00f6r {courseName}. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "Thanks for returning to verify your ID in: {courseName}": "Th\u00e4nks f\u00f6r r\u00e9t\u00fcrn\u00efng t\u00f6 v\u00e9r\u00eff\u00fd \u00fd\u00f6\u00fcr \u00ccD \u00efn: {courseName} \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "Th\u00e9 \u00dbRL \u00fd\u00f6\u00fc \u00e9nt\u00e9r\u00e9d s\u00e9\u00e9ms t\u00f6 \u00df\u00e9 \u00e4n \u00e9m\u00e4\u00efl \u00e4ddr\u00e9ss. D\u00f6 \u00fd\u00f6\u00fc w\u00e4nt t\u00f6 \u00e4dd th\u00e9 r\u00e9q\u00fc\u00efr\u00e9d m\u00e4\u00eflt\u00f6: pr\u00e9f\u00efx? \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, #", @@ -1470,6 +1481,7 @@ "This link will open in a modal window": "Th\u00efs l\u00efnk w\u00efll \u00f6p\u00e9n \u00efn \u00e4 m\u00f6d\u00e4l w\u00efnd\u00f6w \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5#", "This link will open in a new browser window/tab": "Th\u00efs l\u00efnk w\u00efll \u00f6p\u00e9n \u00efn \u00e4 n\u00e9w \u00dfr\u00f6ws\u00e9r w\u00efnd\u00f6w/t\u00e4\u00df \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.": "Th\u00efs m\u00e4\u00fd \u00df\u00e9 h\u00e4pp\u00e9n\u00efng \u00df\u00e9\u00e7\u00e4\u00fcs\u00e9 \u00f6f \u00e4n \u00e9rr\u00f6r w\u00efth \u00f6\u00fcr s\u00e9rv\u00e9r \u00f6r \u00fd\u00f6\u00fcr \u00efnt\u00e9rn\u00e9t \u00e7\u00f6nn\u00e9\u00e7t\u00ef\u00f6n. Tr\u00fd r\u00e9fr\u00e9sh\u00efng th\u00e9 p\u00e4g\u00e9 \u00f6r m\u00e4k\u00efng s\u00fcr\u00e9 \u00fd\u00f6\u00fc \u00e4r\u00e9 \u00f6nl\u00efn\u00e9. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1\u2202\u03b9\u03c1\u03b9\u0455\u03b9\u00a2\u03b9\u03b7g \u0454\u0142\u03b9\u0442, \u0455\u0454\u2202 \u2202\u03c3 \u0454\u03b9\u03c5\u0455\u043c\u03c3\u2202 \u0442\u0454\u043c\u03c1\u03c3\u044f \u03b9\u03b7\u00a2\u03b9\u2202\u03b9\u2202\u03c5\u03b7\u0442 \u03c5\u0442 \u0142\u03b1\u0432\u03c3\u044f\u0454 \u0454\u0442 \u2202\u03c3\u0142\u03c3\u044f\u0454 \u043c\u03b1g\u03b7\u03b1 \u03b1\u0142\u03b9q\u03c5\u03b1. \u03c5\u0442 \u0454\u03b7\u03b9\u043c \u03b1\u2202 \u043c\u03b9\u03b7\u03b9\u043c \u03bd\u0454\u03b7\u03b9\u03b1\u043c, q\u03c5\u03b9\u0455 \u03b7\u03c3\u0455\u0442\u044f\u03c5\u2202 \u0454\u03c7\u0454\u044f\u00a2\u03b9\u0442\u03b1\u0442\u03b9\u03c3\u03b7 \u03c5\u0142\u0142\u03b1\u043c\u00a2\u03c3 \u0142\u03b1\u0432\u03c3\u044f\u03b9\u0455 \u03b7\u03b9\u0455\u03b9 \u03c5\u0442 \u03b1\u0142\u03b9q\u03c5\u03b9\u03c1 \u0454\u03c7 \u0454\u03b1 \u00a2\u03c3\u043c\u043c\u03c3\u2202\u03c3 \u00a2\u03c3\u03b7\u0455\u0454q\u03c5\u03b1\u0442. \u2202\u03c5\u03b9\u0455 \u03b1\u03c5\u0442\u0454 \u03b9\u044f\u03c5\u044f\u0454 \u2202\u03c3\u0142\u03c3\u044f \u03b9\u03b7 \u044f\u0454\u03c1\u044f\u0454\u043d\u0454\u03b7\u2202\u0454\u044f\u03b9\u0442 \u03b9\u03b7 \u03bd\u03c3\u0142\u03c5\u03c1\u0442\u03b1\u0442\u0454 \u03bd\u0454\u0142\u03b9\u0442 \u0454\u0455\u0455\u0454 \u00a2\u03b9\u0142\u0142\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f\u0454 \u0454\u03c5 \u0192\u03c5g\u03b9\u03b1\u0442 \u03b7\u03c5\u0142\u0142\u03b1 \u03c1\u03b1\u044f\u03b9\u03b1\u0442\u03c5\u044f. \u0454\u03c7\u00a2\u0454\u03c1\u0442\u0454\u03c5\u044f \u0455\u03b9\u03b7\u0442 \u03c3\u00a2\u00a2\u03b1\u0454\u00a2\u03b1\u0442 \u00a2\u03c5\u03c1\u03b9\u2202\u03b1\u0442\u03b1\u0442 \u03b7\u03c3\u03b7 \u03c1\u044f\u03c3\u03b9\u2202\u0454\u03b7\u0442, \u0455\u03c5\u03b7\u0442 \u03b9\u03b7 \u00a2\u03c5\u0142\u03c1\u03b1 q\u03c5\u03b9 \u03c3\u0192\u0192\u03b9\u00a2\u03b9\u03b1 \u2202\u0454\u0455\u0454\u044f\u03c5\u03b7\u0442 \u043c\u03c3\u0142\u0142\u03b9\u0442 \u03b1\u03b7\u03b9\u043c \u03b9\u2202 \u0454\u0455\u0442 #", + "This page contains information about orders that you have placed with {platform_name}.": "Th\u00efs p\u00e4g\u00e9 \u00e7\u00f6nt\u00e4\u00efns \u00efnf\u00f6rm\u00e4t\u00ef\u00f6n \u00e4\u00df\u00f6\u00fct \u00f6rd\u00e9rs th\u00e4t \u00fd\u00f6\u00fc h\u00e4v\u00e9 pl\u00e4\u00e7\u00e9d w\u00efth {platform_name}. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5#", "This post is visible only to %(group_name)s.": "Th\u00efs p\u00f6st \u00efs v\u00efs\u00ef\u00dfl\u00e9 \u00f6nl\u00fd t\u00f6 %(group_name)s. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454#", "This post is visible to everyone.": "Th\u00efs p\u00f6st \u00efs v\u00efs\u00ef\u00dfl\u00e9 t\u00f6 \u00e9v\u00e9r\u00fd\u00f6n\u00e9. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454#", "This short name for the assignment type (for example, HW or Midterm) appears next to assignments on a learner's Progress page.": "Th\u00efs sh\u00f6rt n\u00e4m\u00e9 f\u00f6r th\u00e9 \u00e4ss\u00efgnm\u00e9nt t\u00fdp\u00e9 (f\u00f6r \u00e9x\u00e4mpl\u00e9, HW \u00f6r M\u00efdt\u00e9rm) \u00e4pp\u00e9\u00e4rs n\u00e9xt t\u00f6 \u00e4ss\u00efgnm\u00e9nts \u00f6n \u00e4 l\u00e9\u00e4rn\u00e9r's Pr\u00f6gr\u00e9ss p\u00e4g\u00e9. \u2c60'\u03c3\u044f\u0454\u043c#", @@ -1492,7 +1504,6 @@ "Title:": "T\u00eftl\u00e9: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5#", "Titles more than 100 characters may prevent students from printing their certificate on a single page.": "T\u00eftl\u00e9s m\u00f6r\u00e9 th\u00e4n 100 \u00e7h\u00e4r\u00e4\u00e7t\u00e9rs m\u00e4\u00fd pr\u00e9v\u00e9nt st\u00fcd\u00e9nts fr\u00f6m pr\u00efnt\u00efng th\u00e9\u00efr \u00e7\u00e9rt\u00eff\u00ef\u00e7\u00e4t\u00e9 \u00f6n \u00e4 s\u00efngl\u00e9 p\u00e4g\u00e9. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c#", "To be sure all students can access the video, we recommend providing both an .mp4 and a .webm version of your video. Click below to add a URL for another version. These URLs cannot be YouTube URLs. The first listed video that's compatible with the student's computer will play.": "T\u00f6 \u00df\u00e9 s\u00fcr\u00e9 \u00e4ll st\u00fcd\u00e9nts \u00e7\u00e4n \u00e4\u00e7\u00e7\u00e9ss th\u00e9 v\u00efd\u00e9\u00f6, w\u00e9 r\u00e9\u00e7\u00f6mm\u00e9nd pr\u00f6v\u00efd\u00efng \u00df\u00f6th \u00e4n .mp4 \u00e4nd \u00e4 .w\u00e9\u00dfm v\u00e9rs\u00ef\u00f6n \u00f6f \u00fd\u00f6\u00fcr v\u00efd\u00e9\u00f6. \u00c7l\u00ef\u00e7k \u00df\u00e9l\u00f6w t\u00f6 \u00e4dd \u00e4 \u00dbRL f\u00f6r \u00e4n\u00f6th\u00e9r v\u00e9rs\u00ef\u00f6n. Th\u00e9s\u00e9 \u00dbRLs \u00e7\u00e4nn\u00f6t \u00df\u00e9 \u00dd\u00f6\u00fcT\u00fc\u00df\u00e9 \u00dbRLs. Th\u00e9 f\u00efrst l\u00efst\u00e9d v\u00efd\u00e9\u00f6 th\u00e4t's \u00e7\u00f6mp\u00e4t\u00ef\u00dfl\u00e9 w\u00efth th\u00e9 st\u00fcd\u00e9nt's \u00e7\u00f6mp\u00fct\u00e9r w\u00efll pl\u00e4\u00fd. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1\u2202\u03b9\u03c1\u03b9\u0455\u03b9\u00a2\u03b9\u03b7g \u0454\u0142\u03b9\u0442, \u0455\u0454\u2202 \u2202\u03c3 \u0454\u03b9\u03c5\u0455\u043c\u03c3\u2202 \u0442\u0454\u043c\u03c1\u03c3\u044f \u03b9\u03b7\u00a2\u03b9\u2202\u03b9\u2202\u03c5\u03b7\u0442 \u03c5\u0442 \u0142\u03b1\u0432\u03c3\u044f\u0454 \u0454\u0442 \u2202\u03c3\u0142\u03c3\u044f\u0454 \u043c\u03b1g\u03b7\u03b1 \u03b1\u0142\u03b9q\u03c5\u03b1. \u03c5\u0442 \u0454\u03b7\u03b9\u043c \u03b1\u2202 \u043c\u03b9\u03b7\u03b9\u043c \u03bd\u0454\u03b7\u03b9\u03b1\u043c, q\u03c5\u03b9\u0455 \u03b7\u03c3\u0455\u0442\u044f\u03c5\u2202 \u0454\u03c7\u0454\u044f\u00a2\u03b9\u0442\u03b1\u0442\u03b9\u03c3\u03b7 \u03c5\u0142\u0142\u03b1\u043c\u00a2\u03c3 \u0142\u03b1\u0432\u03c3\u044f\u03b9\u0455 \u03b7\u03b9\u0455\u03b9 \u03c5\u0442 \u03b1\u0142\u03b9q\u03c5\u03b9\u03c1 \u0454\u03c7 \u0454\u03b1 \u00a2\u03c3\u043c\u043c\u03c3\u2202#", - "To complete the {program} XSeries and earn an XSeries Certificate you must successfully earn a Verified Certificate in all courses shown below.": "T\u00f6 \u00e7\u00f6mpl\u00e9t\u00e9 th\u00e9 {program} XS\u00e9r\u00ef\u00e9s \u00e4nd \u00e9\u00e4rn \u00e4n XS\u00e9r\u00ef\u00e9s \u00c7\u00e9rt\u00eff\u00ef\u00e7\u00e4t\u00e9 \u00fd\u00f6\u00fc m\u00fcst s\u00fc\u00e7\u00e7\u00e9ssf\u00fcll\u00fd \u00e9\u00e4rn \u00e4 V\u00e9r\u00eff\u00ef\u00e9d \u00c7\u00e9rt\u00eff\u00ef\u00e7\u00e4t\u00e9 \u00efn \u00e4ll \u00e7\u00f6\u00fcrs\u00e9s sh\u00f6wn \u00df\u00e9l\u00f6w. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1\u2202\u03b9\u03c1\u03b9\u0455\u03b9\u00a2\u03b9\u03b7g \u0454\u0142\u03b9\u0442, \u0455\u0454\u2202 \u2202\u03c3 \u0454\u03b9\u03c5\u0455\u043c\u03c3\u2202 \u0442\u0454\u043c\u03c1\u03c3\u044f \u03b9\u03b7\u00a2\u03b9\u2202\u03b9\u2202\u03c5\u03b7\u0442 \u03c5\u0442 \u0142\u03b1\u0432\u03c3\u044f\u0454 \u0454\u0442 \u2202\u03c3\u0142\u03c3\u044f\u0454 \u043c\u03b1g\u03b7\u03b1 \u03b1\u0142\u03b9q\u03c5\u03b1. \u03c5\u0442 \u0454\u03b7\u03b9\u043c \u03b1\u2202 \u043c\u03b9\u03b7\u03b9\u043c \u03bd\u0454\u03b7\u03b9\u03b1\u043c, q\u03c5\u03b9\u0455 \u03b7\u03c3\u0455\u0442\u044f\u03c5\u2202 \u0454\u03c7\u0454\u044f\u00a2\u03b9\u0442\u03b1\u0442\u03b9\u03c3\u03b7 \u03c5\u0142\u0142\u03b1\u043c\u00a2\u03c3 \u0142\u03b1\u0432\u03c3\u044f\u03b9\u0455 \u03b7\u03b9\u0455\u03b9 \u03c5\u0442 \u03b1\u0142\u03b9q\u03c5\u03b9\u03c1 \u0454\u03c7 \u0454\u03b1 \u00a2\u03c3\u043c\u043c\u03c3\u2202\u03c3 \u00a2\u03c3\u03b7\u0455\u0454q\u03c5\u03b1\u0442. \u2202\u03c5\u03b9\u0455 \u03b1\u03c5\u0442\u0454 \u03b9\u044f\u03c5\u044f\u0454 \u2202\u03c3\u0142\u03c3\u044f \u03b9\u03b7 \u044f\u0454\u03c1\u044f\u0454\u043d\u0454\u03b7\u2202\u0454\u044f\u03b9\u0442 \u03b9\u03b7 \u03bd\u03c3\u0142\u03c5\u03c1\u0442\u03b1\u0442\u0454 \u03bd\u0454\u0142\u03b9\u0442 \u0454\u0455\u0455\u0454 \u00a2\u03b9\u0142\u0142\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f\u0454 \u0454\u03c5 \u0192\u03c5g\u03b9\u03b1\u0442 \u03b7\u03c5\u0142\u0142\u03b1 \u03c1\u03b1\u044f\u03b9\u03b1\u0442\u03c5\u044f. \u0454\u03c7\u00a2\u0454\u03c1\u0442\u0454\u03c5\u044f \u0455\u03b9\u03b7\u0442 \u03c3\u00a2\u00a2\u03b1\u0454\u00a2\u03b1\u0442 \u00a2\u03c5\u03c1\u03b9\u2202\u03b1\u0442\u03b1\u0442 \u03b7\u03c3\u03b7 \u03c1\u044f\u03c3\u03b9\u2202\u0454\u03b7\u0442, \u0455\u03c5\u03b7\u0442 \u03b9\u03b7 \u00a2\u03c5\u0142\u03c1\u03b1 q\u03c5\u03b9 \u03c3\u0192\u0192\u03b9\u00a2\u03b9\u03b1 \u2202\u0454\u0455\u0454\u044f\u03c5\u03b7\u0442 \u043c\u03c3\u0142\u0142\u03b9\u0442 \u03b1\u03b7\u03b9\u043c \u03b9\u2202 \u0454\u0455\u0442 \u0142\u03b1\u0432\u03c3#", "To finalize course credit, %(display_name)s requires %(platform_name)s learners to submit a credit request.": "T\u00f6 f\u00efn\u00e4l\u00efz\u00e9 \u00e7\u00f6\u00fcrs\u00e9 \u00e7r\u00e9d\u00eft, %(display_name)s r\u00e9q\u00fc\u00efr\u00e9s %(platform_name)s l\u00e9\u00e4rn\u00e9rs t\u00f6 s\u00fc\u00dfm\u00eft \u00e4 \u00e7r\u00e9d\u00eft r\u00e9q\u00fc\u00e9st. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454#", "To invalidate a certificate for a particular learner, add the username or email address below.": "T\u00f6 \u00efnv\u00e4l\u00efd\u00e4t\u00e9 \u00e4 \u00e7\u00e9rt\u00eff\u00ef\u00e7\u00e4t\u00e9 f\u00f6r \u00e4 p\u00e4rt\u00ef\u00e7\u00fcl\u00e4r l\u00e9\u00e4rn\u00e9r, \u00e4dd th\u00e9 \u00fcs\u00e9rn\u00e4m\u00e9 \u00f6r \u00e9m\u00e4\u00efl \u00e4ddr\u00e9ss \u00df\u00e9l\u00f6w. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2#", "To receive a certificate, you must also verify your identity before %(date)s.": "T\u00f6 r\u00e9\u00e7\u00e9\u00efv\u00e9 \u00e4 \u00e7\u00e9rt\u00eff\u00ef\u00e7\u00e4t\u00e9, \u00fd\u00f6\u00fc m\u00fcst \u00e4ls\u00f6 v\u00e9r\u00eff\u00fd \u00fd\u00f6\u00fcr \u00efd\u00e9nt\u00eft\u00fd \u00df\u00e9f\u00f6r\u00e9 %(date)s. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f#", @@ -1625,6 +1636,7 @@ "Video ID": "V\u00efd\u00e9\u00f6 \u00ccD \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202#", "Video ended": "V\u00efd\u00e9\u00f6 \u00e9nd\u00e9d \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f #", "Video position": "V\u00efd\u00e9\u00f6 p\u00f6s\u00eft\u00ef\u00f6n \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442#", + "Video speed: ": "V\u00efd\u00e9\u00f6 sp\u00e9\u00e9d: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", "Video transcript": "V\u00efd\u00e9\u00f6 tr\u00e4ns\u00e7r\u00efpt \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c#", "VideoPlayer: Element corresponding to the given selector was not found.": "V\u00efd\u00e9\u00f6Pl\u00e4\u00fd\u00e9r: \u00c9l\u00e9m\u00e9nt \u00e7\u00f6rr\u00e9sp\u00f6nd\u00efng t\u00f6 th\u00e9 g\u00efv\u00e9n s\u00e9l\u00e9\u00e7t\u00f6r w\u00e4s n\u00f6t f\u00f6\u00fcnd. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f#", "View": "V\u00ef\u00e9w \u2c60'\u03c3\u044f\u0454\u043c \u03b9#", @@ -1707,6 +1719,7 @@ "You are a member of this team.": "\u00dd\u00f6\u00fc \u00e4r\u00e9 \u00e4 m\u00e9m\u00df\u00e9r \u00f6f th\u00efs t\u00e9\u00e4m. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442#", "You are currently sharing a limited profile.": "\u00dd\u00f6\u00fc \u00e4r\u00e9 \u00e7\u00fcrr\u00e9ntl\u00fd sh\u00e4r\u00efng \u00e4 l\u00efm\u00eft\u00e9d pr\u00f6f\u00efl\u00e9. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f #", "You are enrolling in: {courseName}": "\u00dd\u00f6\u00fc \u00e4r\u00e9 \u00e9nr\u00f6ll\u00efng \u00efn: {courseName} \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455#", + "You are here": "\u00dd\u00f6\u00fc \u00e4r\u00e9 h\u00e9r\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455#", "You are not currently a member of any team.": "\u00dd\u00f6\u00fc \u00e4r\u00e9 n\u00f6t \u00e7\u00fcrr\u00e9ntl\u00fd \u00e4 m\u00e9m\u00df\u00e9r \u00f6f \u00e4n\u00fd t\u00e9\u00e4m. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f #", "You are not enrolled in any XSeries Programs yet.": "\u00dd\u00f6\u00fc \u00e4r\u00e9 n\u00f6t \u00e9nr\u00f6ll\u00e9d \u00efn \u00e4n\u00fd XS\u00e9r\u00ef\u00e9s Pr\u00f6gr\u00e4ms \u00fd\u00e9t. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", "You are now enrolled as a verified student for:": "\u00dd\u00f6\u00fc \u00e4r\u00e9 n\u00f6w \u00e9nr\u00f6ll\u00e9d \u00e4s \u00e4 v\u00e9r\u00eff\u00ef\u00e9d st\u00fcd\u00e9nt f\u00f6r: \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1#", @@ -1865,7 +1878,6 @@ "remove": "r\u00e9m\u00f6v\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5#", "remove all": "r\u00e9m\u00f6v\u00e9 \u00e4ll \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3#", "section": "s\u00e9\u00e7t\u00ef\u00f6n \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c #", - "section.subtitle": "s\u00e9\u00e7t\u00ef\u00f6n.s\u00fc\u00dft\u00eftl\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c#", "section.title": "s\u00e9\u00e7t\u00ef\u00f6n.t\u00eftl\u00e9 \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9#", "send an email message to {email}": "s\u00e9nd \u00e4n \u00e9m\u00e4\u00efl m\u00e9ss\u00e4g\u00e9 t\u00f6 {email} \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2#", "status": "st\u00e4t\u00fcs \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5#", @@ -1886,7 +1898,6 @@ "with %(release_date_from)s": "w\u00efth %(release_date_from)s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202#", "with %(section_or_subsection)s": "w\u00efth %(section_or_subsection)s \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202#", "{browse_span_start}Browse teams in other topics{span_end} or {search_span_start}search teams{span_end} in this topic. If you still can't find a team to join, {create_span_start}create a new team in this topic{span_end}.": "{browse_span_start}Br\u00f6ws\u00e9 t\u00e9\u00e4ms \u00efn \u00f6th\u00e9r t\u00f6p\u00ef\u00e7s{span_end} \u00f6r {search_span_start}s\u00e9\u00e4r\u00e7h t\u00e9\u00e4ms{span_end} \u00efn th\u00efs t\u00f6p\u00ef\u00e7. \u00ccf \u00fd\u00f6\u00fc st\u00efll \u00e7\u00e4n't f\u00efnd \u00e4 t\u00e9\u00e4m t\u00f6 j\u00f6\u00efn, {create_span_start}\u00e7r\u00e9\u00e4t\u00e9 \u00e4 n\u00e9w t\u00e9\u00e4m \u00efn th\u00efs t\u00f6p\u00ef\u00e7{span_end}. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455\u0454\u00a2\u0442\u0454\u0442\u03c5\u044f \u03b1\u2202\u03b9\u03c1\u03b9\u0455\u03b9\u00a2\u03b9\u03b7g \u0454\u0142\u03b9\u0442, \u0455\u0454\u2202 \u2202\u03c3 \u0454\u03b9\u03c5\u0455\u043c\u03c3\u2202 \u0442\u0454\u043c\u03c1\u03c3\u044f \u03b9\u03b7\u00a2\u03b9\u2202\u03b9\u2202\u03c5\u03b7\u0442 \u03c5\u0442 \u0142\u03b1\u0432\u03c3\u044f\u0454 \u0454\u0442 \u2202\u03c3\u0142\u03c3\u044f\u0454 \u043c\u03b1g\u03b7\u03b1 \u03b1\u0142\u03b9q\u03c5\u03b1. \u03c5\u0442 \u0454\u03b7\u03b9\u043c \u03b1\u2202 \u043c\u03b9\u03b7\u03b9\u043c \u03bd\u0454\u03b7\u03b9\u03b1\u043c, q\u03c5\u03b9\u0455 \u03b7\u03c3\u0455\u0442\u044f\u03c5\u2202 \u0454\u03c7\u0454\u044f\u00a2\u03b9\u0442\u03b1\u0442\u03b9\u03c3\u03b7 \u03c5\u0142\u0142\u03b1\u043c\u00a2\u03c3 \u0142\u03b1\u0432\u03c3\u044f\u03b9\u0455 \u03b7\u03b9\u0455\u03b9 \u03c5\u0442 \u03b1\u0142\u03b9q\u03c5\u03b9\u03c1 \u0454\u03c7 \u0454\u03b1 \u00a2\u03c3\u043c\u043c\u03c3\u2202\u03c3 \u00a2\u03c3\u03b7\u0455\u0454q\u03c5\u03b1\u0442. \u2202\u03c5\u03b9\u0455 \u03b1\u03c5\u0442\u0454 \u03b9\u044f\u03c5\u044f\u0454 \u2202\u03c3\u0142\u03c3\u044f \u03b9\u03b7 \u044f\u0454\u03c1\u044f\u0454\u043d\u0454\u03b7\u2202\u0454\u044f\u03b9\u0442 \u03b9\u03b7 \u03bd\u03c3\u0142\u03c5\u03c1\u0442\u03b1\u0442\u0454 \u03bd\u0454\u0142\u03b9\u0442 \u0454\u0455\u0455\u0454 \u00a2\u03b9\u0142\u0142\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f\u0454 \u0454\u03c5 \u0192\u03c5g\u03b9\u03b1\u0442 \u03b7\u03c5\u0142\u0142\u03b1 \u03c1\u03b1\u044f\u03b9\u03b1\u0442\u03c5\u044f. \u0454\u03c7\u00a2\u0454\u03c1\u0442\u0454\u03c5\u044f \u0455\u03b9\u03b7\u0442 \u03c3\u00a2\u00a2\u03b1\u0454\u00a2\u03b1\u0442 \u00a2\u03c5\u03c1\u03b9\u2202\u03b1\u0442\u03b1\u0442 \u03b7\u03c3\u03b7 \u03c1\u044f\u03c3\u03b9\u2202\u0454\u03b7\u0442, \u0455\u03c5\u03b7\u0442 \u03b9\u03b7 \u00a2\u03c5\u0142\u03c1\u03b1 q\u03c5\u03b9 \u03c3\u0192\u0192\u03b9\u00a2\u03b9\u03b1 \u2202\u0454\u0455\u0454\u044f\u03c5\u03b7\u0442 \u043c\u03c3\u0142\u0142\u03b9\u0442 \u03b1\u03b7#", - "{category}\\'s program": "{category}\\'s pr\u00f6gr\u00e4m \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442#", "{email} is already on the {container} team. Recheck the email address if you want to add a new member.": "{email} \u00efs \u00e4lr\u00e9\u00e4d\u00fd \u00f6n th\u00e9 {container} t\u00e9\u00e4m. R\u00e9\u00e7h\u00e9\u00e7k th\u00e9 \u00e9m\u00e4\u00efl \u00e4ddr\u00e9ss \u00eff \u00fd\u00f6\u00fc w\u00e4nt t\u00f6 \u00e4dd \u00e4 n\u00e9w m\u00e9m\u00df\u00e9r. \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455#", "{hours}:{minutes} (current UTC time)": "{hours}:{minutes} (\u00e7\u00fcrr\u00e9nt \u00dbT\u00c7 t\u00efm\u00e9) \u2c60'\u03c3\u044f\u0454\u043c \u03b9\u03c1\u0455\u03c5\u043c \u2202\u03c3\u0142\u03c3\u044f \u0455\u03b9\u0442 \u03b1\u043c\u0454\u0442, \u00a2\u03c3\u03b7\u0455#", "{numMoved} student was removed from {oldCohort}": [ diff --git a/cms/static/js/i18n/fake2/djangojs.js b/cms/static/js/i18n/fake2/djangojs.js index 578be49877..4968a1597d 100644 --- a/cms/static/js/i18n/fake2/djangojs.js +++ b/cms/static/js/i18n/fake2/djangojs.js @@ -172,10 +172,12 @@ "Add URLs for additional versions": "\u023add \u0244\u024c\u0141s \u025f\u00f8\u0279 \u0250dd\u1d09\u0287\u1d09\u00f8n\u0250l \u028c\u01dd\u0279s\u1d09\u00f8ns", "Add a Chapter": "\u023add \u0250 \u023b\u0265\u0250d\u0287\u01dd\u0279", "Add a New Cohort": "\u023add \u0250 N\u01dd\u028d \u023b\u00f8\u0265\u00f8\u0279\u0287", + "Add a Post": "\u023add \u0250 \u2c63\u00f8s\u0287", "Add a Response": "\u023add \u0250 \u024c\u01ddsd\u00f8ns\u01dd", "Add a clear and descriptive title to encourage participation.": "\u023add \u0250 \u0254l\u01dd\u0250\u0279 \u0250nd d\u01dds\u0254\u0279\u1d09d\u0287\u1d09\u028c\u01dd \u0287\u1d09\u0287l\u01dd \u0287\u00f8 \u01ddn\u0254\u00f8n\u0279\u0250\u0183\u01dd d\u0250\u0279\u0287\u1d09\u0254\u1d09d\u0250\u0287\u1d09\u00f8n.", "Add a comment": "\u023add \u0250 \u0254\u00f8\u026f\u026f\u01ddn\u0287", "Add a learning outcome here": "\u023add \u0250 l\u01dd\u0250\u0279n\u1d09n\u0183 \u00f8n\u0287\u0254\u00f8\u026f\u01dd \u0265\u01dd\u0279\u01dd", + "Add a response:": "\u023add \u0250 \u0279\u01ddsd\u00f8ns\u01dd:", "Add another group": "\u023add \u0250n\u00f8\u0287\u0265\u01dd\u0279 \u0183\u0279\u00f8nd", "Add language": "\u023add l\u0250n\u0183n\u0250\u0183\u01dd", "Add notes about this learner": "\u023add n\u00f8\u0287\u01dds \u0250b\u00f8n\u0287 \u0287\u0265\u1d09s l\u01dd\u0250\u0279n\u01dd\u0279", @@ -206,6 +208,7 @@ "All flags have been removed. To undo, uncheck the box.": "\u023all \u025fl\u0250\u0183s \u0265\u0250\u028c\u01dd b\u01dd\u01ddn \u0279\u01dd\u026f\u00f8\u028c\u01ddd. \u0166\u00f8 nnd\u00f8, nn\u0254\u0265\u01dd\u0254\u029e \u0287\u0265\u01dd b\u00f8x.", "All groups must have a name.": "\u023all \u0183\u0279\u00f8nds \u026fns\u0287 \u0265\u0250\u028c\u01dd \u0250 n\u0250\u026f\u01dd.", "All groups must have a unique name.": "\u023all \u0183\u0279\u00f8nds \u026fns\u0287 \u0265\u0250\u028c\u01dd \u0250 nn\u1d09bn\u01dd n\u0250\u026f\u01dd.", + "All learners in the {cohort_name} cohort": "\u023all l\u01dd\u0250\u0279n\u01dd\u0279s \u1d09n \u0287\u0265\u01dd {cohort_name} \u0254\u00f8\u0265\u00f8\u0279\u0287", "All learners who are enrolled in this course": "\u023all l\u01dd\u0250\u0279n\u01dd\u0279s \u028d\u0265\u00f8 \u0250\u0279\u01dd \u01ddn\u0279\u00f8ll\u01ddd \u1d09n \u0287\u0265\u1d09s \u0254\u00f8n\u0279s\u01dd", "All payment options are currently unavailable.": "\u023all d\u0250\u028e\u026f\u01ddn\u0287 \u00f8d\u0287\u1d09\u00f8ns \u0250\u0279\u01dd \u0254n\u0279\u0279\u01ddn\u0287l\u028e nn\u0250\u028c\u0250\u1d09l\u0250bl\u01dd.", "All professional education courses are fee-based, and require payment to complete the enrollment process.": "\u023all d\u0279\u00f8\u025f\u01ddss\u1d09\u00f8n\u0250l \u01dddn\u0254\u0250\u0287\u1d09\u00f8n \u0254\u00f8n\u0279s\u01dds \u0250\u0279\u01dd \u025f\u01dd\u01dd-b\u0250s\u01ddd, \u0250nd \u0279\u01ddbn\u1d09\u0279\u01dd d\u0250\u028e\u026f\u01ddn\u0287 \u0287\u00f8 \u0254\u00f8\u026fdl\u01dd\u0287\u01dd \u0287\u0265\u01dd \u01ddn\u0279\u00f8ll\u026f\u01ddn\u0287 d\u0279\u00f8\u0254\u01ddss.", @@ -476,7 +479,7 @@ "Custom...": "\u023bns\u0287\u00f8\u026f...", "Cut": "\u023bn\u0287", "Cut row": "\u023bn\u0287 \u0279\u00f8\u028d", - "DISCUSSION HOME:": "\u0110\u0197S\u023b\u0244SS\u0197\u00d8N \u0126\u00d8M\u0246:", + "Dashboard": "\u0110\u0250s\u0265b\u00f8\u0250\u0279d", "Date": "\u0110\u0250\u0287\u01dd", "Date Added": "\u0110\u0250\u0287\u01dd \u023add\u01ddd", "Date added": "\u0110\u0250\u0287\u01dd \u0250dd\u01ddd", @@ -515,6 +518,7 @@ "Discard Changes": "\u0110\u1d09s\u0254\u0250\u0279d \u023b\u0265\u0250n\u0183\u01dds", "Discarding Changes": "\u0110\u1d09s\u0254\u0250\u0279d\u1d09n\u0183 \u023b\u0265\u0250n\u0183\u01dds", "Discussion": "\u0110\u1d09s\u0254nss\u1d09\u00f8n", + "Discussion Home": "\u0110\u1d09s\u0254nss\u1d09\u00f8n \u0126\u00f8\u026f\u01dd", "Discussion admins, moderators, and TAs can make their posts visible to all students or specify a single cohort.": "\u0110\u1d09s\u0254nss\u1d09\u00f8n \u0250d\u026f\u1d09ns, \u026f\u00f8d\u01dd\u0279\u0250\u0287\u00f8\u0279s, \u0250nd \u0166\u023as \u0254\u0250n \u026f\u0250\u029e\u01dd \u0287\u0265\u01dd\u1d09\u0279 d\u00f8s\u0287s \u028c\u1d09s\u1d09bl\u01dd \u0287\u00f8 \u0250ll s\u0287nd\u01ddn\u0287s \u00f8\u0279 sd\u01dd\u0254\u1d09\u025f\u028e \u0250 s\u1d09n\u0183l\u01dd \u0254\u00f8\u0265\u00f8\u0279\u0287.", "Discussion topics; currently listing: ": "\u0110\u1d09s\u0254nss\u1d09\u00f8n \u0287\u00f8d\u1d09\u0254s; \u0254n\u0279\u0279\u01ddn\u0287l\u028e l\u1d09s\u0287\u1d09n\u0183: ", "Display Name": "\u0110\u1d09sdl\u0250\u028e N\u0250\u026f\u01dd", @@ -918,6 +922,7 @@ "Muted": "Mn\u0287\u01ddd", "My Bookmarks": "M\u028e \u0243\u00f8\u00f8\u029e\u026f\u0250\u0279\u029es", "My Notes": "M\u028e N\u00f8\u0287\u01dds", + "My Orders": "M\u028e \u00d8\u0279d\u01dd\u0279s", "My Team": "M\u028e \u0166\u01dd\u0250\u026f", "N/A": "N/\u023a", "Name": "N\u0250\u026f\u01dd", @@ -930,7 +935,6 @@ "New %(component_type)s": "N\u01dd\u028d %(component_type)s", "New %(item_type)s": "N\u01dd\u028d %(item_type)s", "New Address": "N\u01dd\u028d \u023add\u0279\u01ddss", - "New Post": "N\u01dd\u028d \u2c63\u00f8s\u0287", "New document": "N\u01dd\u028d d\u00f8\u0254n\u026f\u01ddn\u0287", "New enrollment mode:": "N\u01dd\u028d \u01ddn\u0279\u00f8ll\u026f\u01ddn\u0287 \u026f\u00f8d\u01dd:", "New to %(platformName)s?": "N\u01dd\u028d \u0287\u00f8 %(platformName)s?", @@ -976,6 +980,9 @@ "Numbered List (Ctrl+O)": "Nn\u026fb\u01dd\u0279\u01ddd \u0141\u1d09s\u0287 (\u023b\u0287\u0279l+\u00d8)", "Numbered list": "Nn\u026fb\u01dd\u0279\u01ddd l\u1d09s\u0287", "OK": "\u00d8\ua740", + "ORDER NAME": "\u00d8\u024c\u0110\u0246\u024c N\u023aM\u0246", + "ORDER NUMBER": "\u00d8\u024c\u0110\u0246\u024c N\u0244M\u0243\u0246\u024c", + "ORDER PLACED": "\u00d8\u024c\u0110\u0246\u024c \u2c63\u0141\u023a\u023b\u0246\u0110", "Ok": "\u00d8\u029e", "Once in position, use the camera button {icon} to capture your ID": "\u00d8n\u0254\u01dd \u1d09n d\u00f8s\u1d09\u0287\u1d09\u00f8n, ns\u01dd \u0287\u0265\u01dd \u0254\u0250\u026f\u01dd\u0279\u0250 bn\u0287\u0287\u00f8n {icon} \u0287\u00f8 \u0254\u0250d\u0287n\u0279\u01dd \u028e\u00f8n\u0279 \u0197\u0110", "Once in position, use the camera button {icon} to capture your photo": "\u00d8n\u0254\u01dd \u1d09n d\u00f8s\u1d09\u0287\u1d09\u00f8n, ns\u01dd \u0287\u0265\u01dd \u0254\u0250\u026f\u01dd\u0279\u0250 bn\u0287\u0287\u00f8n {icon} \u0287\u00f8 \u0254\u0250d\u0287n\u0279\u01dd \u028e\u00f8n\u0279 d\u0265\u00f8\u0287\u00f8", @@ -990,6 +997,8 @@ "Optional Characteristics": "\u00d8d\u0287\u1d09\u00f8n\u0250l \u023b\u0265\u0250\u0279\u0250\u0254\u0287\u01dd\u0279\u1d09s\u0287\u1d09\u0254s", "Optional long description": "\u00d8d\u0287\u1d09\u00f8n\u0250l l\u00f8n\u0183 d\u01dds\u0254\u0279\u1d09d\u0287\u1d09\u00f8n", "Options for {license_name}": "\u00d8d\u0287\u1d09\u00f8ns \u025f\u00f8\u0279 {license_name}", + "Order Details": "\u00d8\u0279d\u01dd\u0279 \u0110\u01dd\u0287\u0250\u1d09ls", + "Order History": "\u00d8\u0279d\u01dd\u0279 \u0126\u1d09s\u0287\u00f8\u0279\u028e", "Order No.": "\u00d8\u0279d\u01dd\u0279 N\u00f8.", "Organization": "\u00d8\u0279\u0183\u0250n\u1d09z\u0250\u0287\u1d09\u00f8n", "Organization ": "\u00d8\u0279\u0183\u0250n\u1d09z\u0250\u0287\u1d09\u00f8n ", @@ -1063,7 +1072,6 @@ "Please verify that you have uploaded a valid image (PNG and JPEG).": "\u2c63l\u01dd\u0250s\u01dd \u028c\u01dd\u0279\u1d09\u025f\u028e \u0287\u0265\u0250\u0287 \u028e\u00f8n \u0265\u0250\u028c\u01dd ndl\u00f8\u0250d\u01ddd \u0250 \u028c\u0250l\u1d09d \u1d09\u026f\u0250\u0183\u01dd (\u2c63N\u01e4 \u0250nd \u0248\u2c63\u0246\u01e4).", "Please verify that your webcam is connected and that you have allowed your browser to access it.": "\u2c63l\u01dd\u0250s\u01dd \u028c\u01dd\u0279\u1d09\u025f\u028e \u0287\u0265\u0250\u0287 \u028e\u00f8n\u0279 \u028d\u01ddb\u0254\u0250\u026f \u1d09s \u0254\u00f8nn\u01dd\u0254\u0287\u01ddd \u0250nd \u0287\u0265\u0250\u0287 \u028e\u00f8n \u0265\u0250\u028c\u01dd \u0250ll\u00f8\u028d\u01ddd \u028e\u00f8n\u0279 b\u0279\u00f8\u028ds\u01dd\u0279 \u0287\u00f8 \u0250\u0254\u0254\u01ddss \u1d09\u0287.", "Post": "\u2c63\u00f8s\u0287", - "Post a response:": "\u2c63\u00f8s\u0287 \u0250 \u0279\u01ddsd\u00f8ns\u01dd:", "Post body": "\u2c63\u00f8s\u0287 b\u00f8d\u028e", "Post type:": "\u2c63\u00f8s\u0287 \u0287\u028ed\u01dd:", "Poster": "\u2c63\u00f8s\u0287\u01dd\u0279", @@ -1203,6 +1211,7 @@ "Selected tab": "S\u01ddl\u01dd\u0254\u0287\u01ddd \u0287\u0250b", "Send notification to mobile apps": "S\u01ddnd n\u00f8\u0287\u1d09\u025f\u1d09\u0254\u0250\u0287\u1d09\u00f8n \u0287\u00f8 \u026f\u00f8b\u1d09l\u01dd \u0250dds", "Send push notification to mobile apps": "S\u01ddnd dns\u0265 n\u00f8\u0287\u1d09\u025f\u1d09\u0254\u0250\u0287\u1d09\u00f8n \u0287\u00f8 \u026f\u00f8b\u1d09l\u01dd \u0250dds", + "Send to:": "S\u01ddnd \u0287\u00f8:", "Sent By": "S\u01ddn\u0287 \u0243\u028e", "Sent By:": "S\u01ddn\u0287 \u0243\u028e:", "Sent To": "S\u01ddn\u0287 \u0166\u00f8", @@ -1285,6 +1294,7 @@ "Started entrance exam rescore task for student '{student_id}'. Click the 'Show Background Task History for Student' button to see the status of the task.": "S\u0287\u0250\u0279\u0287\u01ddd \u01ddn\u0287\u0279\u0250n\u0254\u01dd \u01ddx\u0250\u026f \u0279\u01dds\u0254\u00f8\u0279\u01dd \u0287\u0250s\u029e \u025f\u00f8\u0279 s\u0287nd\u01ddn\u0287 '{student_id}'. \u023bl\u1d09\u0254\u029e \u0287\u0265\u01dd 'S\u0265\u00f8\u028d \u0243\u0250\u0254\u029e\u0183\u0279\u00f8nnd \u0166\u0250s\u029e \u0126\u1d09s\u0287\u00f8\u0279\u028e \u025f\u00f8\u0279 S\u0287nd\u01ddn\u0287' bn\u0287\u0287\u00f8n \u0287\u00f8 s\u01dd\u01dd \u0287\u0265\u01dd s\u0287\u0250\u0287ns \u00f8\u025f \u0287\u0265\u01dd \u0287\u0250s\u029e.", "Started rescore problem task for problem '<%= problem_id %>' and student '<%= student_id %>'. Click the 'Show Background Task History for Student' button to see the status of the task.": "S\u0287\u0250\u0279\u0287\u01ddd \u0279\u01dds\u0254\u00f8\u0279\u01dd d\u0279\u00f8bl\u01dd\u026f \u0287\u0250s\u029e \u025f\u00f8\u0279 d\u0279\u00f8bl\u01dd\u026f '<%= problem_id %>' \u0250nd s\u0287nd\u01ddn\u0287 '<%= student_id %>'. \u023bl\u1d09\u0254\u029e \u0287\u0265\u01dd 'S\u0265\u00f8\u028d \u0243\u0250\u0254\u029e\u0183\u0279\u00f8nnd \u0166\u0250s\u029e \u0126\u1d09s\u0287\u00f8\u0279\u028e \u025f\u00f8\u0279 S\u0287nd\u01ddn\u0287' bn\u0287\u0287\u00f8n \u0287\u00f8 s\u01dd\u01dd \u0287\u0265\u01dd s\u0287\u0250\u0287ns \u00f8\u025f \u0287\u0265\u01dd \u0287\u0250s\u029e.", "Starts": "S\u0287\u0250\u0279\u0287s", + "Starts %(start)s": "S\u0287\u0250\u0279\u0287s %(start)s", "Starts: %(start)s": "S\u0287\u0250\u0279\u0287s: %(start)s", "Starts: %(start_date)s": "S\u0287\u0250\u0279\u0287s: %(start_date)s", "State": "S\u0287\u0250\u0287\u01dd", @@ -1319,6 +1329,7 @@ "Successfully started task to reset attempts for problem '<%= problem_id %>'. Click the 'Show Background Task History for Problem' button to see the status of the task.": "Sn\u0254\u0254\u01ddss\u025fnll\u028e s\u0287\u0250\u0279\u0287\u01ddd \u0287\u0250s\u029e \u0287\u00f8 \u0279\u01dds\u01dd\u0287 \u0250\u0287\u0287\u01dd\u026fd\u0287s \u025f\u00f8\u0279 d\u0279\u00f8bl\u01dd\u026f '<%= problem_id %>'. \u023bl\u1d09\u0254\u029e \u0287\u0265\u01dd 'S\u0265\u00f8\u028d \u0243\u0250\u0254\u029e\u0183\u0279\u00f8nnd \u0166\u0250s\u029e \u0126\u1d09s\u0287\u00f8\u0279\u028e \u025f\u00f8\u0279 \u2c63\u0279\u00f8bl\u01dd\u026f' bn\u0287\u0287\u00f8n \u0287\u00f8 s\u01dd\u01dd \u0287\u0265\u01dd s\u0287\u0250\u0287ns \u00f8\u025f \u0287\u0265\u01dd \u0287\u0250s\u029e.", "Successfully unlinked.": "Sn\u0254\u0254\u01ddss\u025fnll\u028e nnl\u1d09n\u029e\u01ddd.", "Superscript": "Snd\u01dd\u0279s\u0254\u0279\u1d09d\u0287", + "TOTAL": "\u0166\u00d8\u0166\u023a\u0141", "Table": "\u0166\u0250bl\u01dd", "Table properties": "\u0166\u0250bl\u01dd d\u0279\u00f8d\u01dd\u0279\u0287\u1d09\u01dds", "Tags": "\u0166\u0250\u0183s", @@ -1355,9 +1366,9 @@ "Textbook Name": "\u0166\u01ddx\u0287b\u00f8\u00f8\u029e N\u0250\u026f\u01dd", "Textbook information": "\u0166\u01ddx\u0287b\u00f8\u00f8\u029e \u1d09n\u025f\u00f8\u0279\u026f\u0250\u0287\u1d09\u00f8n", "Textbook name is required": "\u0166\u01ddx\u0287b\u00f8\u00f8\u029e n\u0250\u026f\u01dd \u1d09s \u0279\u01ddbn\u1d09\u0279\u01ddd", + "Thank you %(full_name)s! We have received your payment for %(course_name)s.": "\u0166\u0265\u0250n\u029e \u028e\u00f8n %(full_name)s! W\u01dd \u0265\u0250\u028c\u01dd \u0279\u01dd\u0254\u01dd\u1d09\u028c\u01ddd \u028e\u00f8n\u0279 d\u0250\u028e\u026f\u01ddn\u0287 \u025f\u00f8\u0279 %(course_name)s.", "Thank you for submitting your financial assistance application for {course_name}! You can expect a response in 2-4 business days.": "\u0166\u0265\u0250n\u029e \u028e\u00f8n \u025f\u00f8\u0279 snb\u026f\u1d09\u0287\u0287\u1d09n\u0183 \u028e\u00f8n\u0279 \u025f\u1d09n\u0250n\u0254\u1d09\u0250l \u0250ss\u1d09s\u0287\u0250n\u0254\u01dd \u0250ddl\u1d09\u0254\u0250\u0287\u1d09\u00f8n \u025f\u00f8\u0279 {course_name}! \u024e\u00f8n \u0254\u0250n \u01ddxd\u01dd\u0254\u0287 \u0250 \u0279\u01ddsd\u00f8ns\u01dd \u1d09n 2-4 bns\u1d09n\u01ddss d\u0250\u028es.", "Thank you for submitting your photos. We will review them shortly. You can now sign up for any %(platformName)s course that offers verified certificates. Verification is good for one year. After one year, you must submit photos for verification again.": "\u0166\u0265\u0250n\u029e \u028e\u00f8n \u025f\u00f8\u0279 snb\u026f\u1d09\u0287\u0287\u1d09n\u0183 \u028e\u00f8n\u0279 d\u0265\u00f8\u0287\u00f8s. W\u01dd \u028d\u1d09ll \u0279\u01dd\u028c\u1d09\u01dd\u028d \u0287\u0265\u01dd\u026f s\u0265\u00f8\u0279\u0287l\u028e. \u024e\u00f8n \u0254\u0250n n\u00f8\u028d s\u1d09\u0183n nd \u025f\u00f8\u0279 \u0250n\u028e %(platformName)s \u0254\u00f8n\u0279s\u01dd \u0287\u0265\u0250\u0287 \u00f8\u025f\u025f\u01dd\u0279s \u028c\u01dd\u0279\u1d09\u025f\u1d09\u01ddd \u0254\u01dd\u0279\u0287\u1d09\u025f\u1d09\u0254\u0250\u0287\u01dds. V\u01dd\u0279\u1d09\u025f\u1d09\u0254\u0250\u0287\u1d09\u00f8n \u1d09s \u0183\u00f8\u00f8d \u025f\u00f8\u0279 \u00f8n\u01dd \u028e\u01dd\u0250\u0279. \u023a\u025f\u0287\u01dd\u0279 \u00f8n\u01dd \u028e\u01dd\u0250\u0279, \u028e\u00f8n \u026fns\u0287 snb\u026f\u1d09\u0287 d\u0265\u00f8\u0287\u00f8s \u025f\u00f8\u0279 \u028c\u01dd\u0279\u1d09\u025f\u1d09\u0254\u0250\u0287\u1d09\u00f8n \u0250\u0183\u0250\u1d09n.", - "Thank you! We have received your payment for %(course_name)s.": "\u0166\u0265\u0250n\u029e \u028e\u00f8n! W\u01dd \u0265\u0250\u028c\u01dd \u0279\u01dd\u0254\u01dd\u1d09\u028c\u01ddd \u028e\u00f8n\u0279 d\u0250\u028e\u026f\u01ddn\u0287 \u025f\u00f8\u0279 %(course_name)s.", "Thank you! We have received your payment for {courseName}.": "\u0166\u0265\u0250n\u029e \u028e\u00f8n! W\u01dd \u0265\u0250\u028c\u01dd \u0279\u01dd\u0254\u01dd\u1d09\u028c\u01ddd \u028e\u00f8n\u0279 d\u0250\u028e\u026f\u01ddn\u0287 \u025f\u00f8\u0279 {courseName}.", "Thanks for returning to verify your ID in: {courseName}": "\u0166\u0265\u0250n\u029es \u025f\u00f8\u0279 \u0279\u01dd\u0287n\u0279n\u1d09n\u0183 \u0287\u00f8 \u028c\u01dd\u0279\u1d09\u025f\u028e \u028e\u00f8n\u0279 \u0197\u0110 \u1d09n: {courseName}", "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u0166\u0265\u01dd \u0244\u024c\u0141 \u028e\u00f8n \u01ddn\u0287\u01dd\u0279\u01ddd s\u01dd\u01dd\u026fs \u0287\u00f8 b\u01dd \u0250n \u01dd\u026f\u0250\u1d09l \u0250dd\u0279\u01ddss. \u0110\u00f8 \u028e\u00f8n \u028d\u0250n\u0287 \u0287\u00f8 \u0250dd \u0287\u0265\u01dd \u0279\u01ddbn\u1d09\u0279\u01ddd \u026f\u0250\u1d09l\u0287\u00f8: d\u0279\u01dd\u025f\u1d09x?", @@ -1470,6 +1481,7 @@ "This link will open in a modal window": "\u0166\u0265\u1d09s l\u1d09n\u029e \u028d\u1d09ll \u00f8d\u01ddn \u1d09n \u0250 \u026f\u00f8d\u0250l \u028d\u1d09nd\u00f8\u028d", "This link will open in a new browser window/tab": "\u0166\u0265\u1d09s l\u1d09n\u029e \u028d\u1d09ll \u00f8d\u01ddn \u1d09n \u0250 n\u01dd\u028d b\u0279\u00f8\u028ds\u01dd\u0279 \u028d\u1d09nd\u00f8\u028d/\u0287\u0250b", "This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.": "\u0166\u0265\u1d09s \u026f\u0250\u028e b\u01dd \u0265\u0250dd\u01ddn\u1d09n\u0183 b\u01dd\u0254\u0250ns\u01dd \u00f8\u025f \u0250n \u01dd\u0279\u0279\u00f8\u0279 \u028d\u1d09\u0287\u0265 \u00f8n\u0279 s\u01dd\u0279\u028c\u01dd\u0279 \u00f8\u0279 \u028e\u00f8n\u0279 \u1d09n\u0287\u01dd\u0279n\u01dd\u0287 \u0254\u00f8nn\u01dd\u0254\u0287\u1d09\u00f8n. \u0166\u0279\u028e \u0279\u01dd\u025f\u0279\u01dds\u0265\u1d09n\u0183 \u0287\u0265\u01dd d\u0250\u0183\u01dd \u00f8\u0279 \u026f\u0250\u029e\u1d09n\u0183 sn\u0279\u01dd \u028e\u00f8n \u0250\u0279\u01dd \u00f8nl\u1d09n\u01dd.", + "This page contains information about orders that you have placed with {platform_name}.": "\u0166\u0265\u1d09s d\u0250\u0183\u01dd \u0254\u00f8n\u0287\u0250\u1d09ns \u1d09n\u025f\u00f8\u0279\u026f\u0250\u0287\u1d09\u00f8n \u0250b\u00f8n\u0287 \u00f8\u0279d\u01dd\u0279s \u0287\u0265\u0250\u0287 \u028e\u00f8n \u0265\u0250\u028c\u01dd dl\u0250\u0254\u01ddd \u028d\u1d09\u0287\u0265 {platform_name}.", "This post is visible only to %(group_name)s.": "\u0166\u0265\u1d09s d\u00f8s\u0287 \u1d09s \u028c\u1d09s\u1d09bl\u01dd \u00f8nl\u028e \u0287\u00f8 %(group_name)s.", "This post is visible to everyone.": "\u0166\u0265\u1d09s d\u00f8s\u0287 \u1d09s \u028c\u1d09s\u1d09bl\u01dd \u0287\u00f8 \u01dd\u028c\u01dd\u0279\u028e\u00f8n\u01dd.", "This short name for the assignment type (for example, HW or Midterm) appears next to assignments on a learner's Progress page.": "\u0166\u0265\u1d09s s\u0265\u00f8\u0279\u0287 n\u0250\u026f\u01dd \u025f\u00f8\u0279 \u0287\u0265\u01dd \u0250ss\u1d09\u0183n\u026f\u01ddn\u0287 \u0287\u028ed\u01dd (\u025f\u00f8\u0279 \u01ddx\u0250\u026fdl\u01dd, \u0126W \u00f8\u0279 M\u1d09d\u0287\u01dd\u0279\u026f) \u0250dd\u01dd\u0250\u0279s n\u01ddx\u0287 \u0287\u00f8 \u0250ss\u1d09\u0183n\u026f\u01ddn\u0287s \u00f8n \u0250 l\u01dd\u0250\u0279n\u01dd\u0279's \u2c63\u0279\u00f8\u0183\u0279\u01ddss d\u0250\u0183\u01dd.", @@ -1492,7 +1504,6 @@ "Title:": "\u0166\u1d09\u0287l\u01dd:", "Titles more than 100 characters may prevent students from printing their certificate on a single page.": "\u0166\u1d09\u0287l\u01dds \u026f\u00f8\u0279\u01dd \u0287\u0265\u0250n 100 \u0254\u0265\u0250\u0279\u0250\u0254\u0287\u01dd\u0279s \u026f\u0250\u028e d\u0279\u01dd\u028c\u01ddn\u0287 s\u0287nd\u01ddn\u0287s \u025f\u0279\u00f8\u026f d\u0279\u1d09n\u0287\u1d09n\u0183 \u0287\u0265\u01dd\u1d09\u0279 \u0254\u01dd\u0279\u0287\u1d09\u025f\u1d09\u0254\u0250\u0287\u01dd \u00f8n \u0250 s\u1d09n\u0183l\u01dd d\u0250\u0183\u01dd.", "To be sure all students can access the video, we recommend providing both an .mp4 and a .webm version of your video. Click below to add a URL for another version. These URLs cannot be YouTube URLs. The first listed video that's compatible with the student's computer will play.": "\u0166\u00f8 b\u01dd sn\u0279\u01dd \u0250ll s\u0287nd\u01ddn\u0287s \u0254\u0250n \u0250\u0254\u0254\u01ddss \u0287\u0265\u01dd \u028c\u1d09d\u01dd\u00f8, \u028d\u01dd \u0279\u01dd\u0254\u00f8\u026f\u026f\u01ddnd d\u0279\u00f8\u028c\u1d09d\u1d09n\u0183 b\u00f8\u0287\u0265 \u0250n .\u026fd4 \u0250nd \u0250 .\u028d\u01ddb\u026f \u028c\u01dd\u0279s\u1d09\u00f8n \u00f8\u025f \u028e\u00f8n\u0279 \u028c\u1d09d\u01dd\u00f8. \u023bl\u1d09\u0254\u029e b\u01ddl\u00f8\u028d \u0287\u00f8 \u0250dd \u0250 \u0244\u024c\u0141 \u025f\u00f8\u0279 \u0250n\u00f8\u0287\u0265\u01dd\u0279 \u028c\u01dd\u0279s\u1d09\u00f8n. \u0166\u0265\u01dds\u01dd \u0244\u024c\u0141s \u0254\u0250nn\u00f8\u0287 b\u01dd \u024e\u00f8n\u0166nb\u01dd \u0244\u024c\u0141s. \u0166\u0265\u01dd \u025f\u1d09\u0279s\u0287 l\u1d09s\u0287\u01ddd \u028c\u1d09d\u01dd\u00f8 \u0287\u0265\u0250\u0287's \u0254\u00f8\u026fd\u0250\u0287\u1d09bl\u01dd \u028d\u1d09\u0287\u0265 \u0287\u0265\u01dd s\u0287nd\u01ddn\u0287's \u0254\u00f8\u026fdn\u0287\u01dd\u0279 \u028d\u1d09ll dl\u0250\u028e.", - "To complete the {program} XSeries and earn an XSeries Certificate you must successfully earn a Verified Certificate in all courses shown below.": "\u0166\u00f8 \u0254\u00f8\u026fdl\u01dd\u0287\u01dd \u0287\u0265\u01dd {program} XS\u01dd\u0279\u1d09\u01dds \u0250nd \u01dd\u0250\u0279n \u0250n XS\u01dd\u0279\u1d09\u01dds \u023b\u01dd\u0279\u0287\u1d09\u025f\u1d09\u0254\u0250\u0287\u01dd \u028e\u00f8n \u026fns\u0287 sn\u0254\u0254\u01ddss\u025fnll\u028e \u01dd\u0250\u0279n \u0250 V\u01dd\u0279\u1d09\u025f\u1d09\u01ddd \u023b\u01dd\u0279\u0287\u1d09\u025f\u1d09\u0254\u0250\u0287\u01dd \u1d09n \u0250ll \u0254\u00f8n\u0279s\u01dds s\u0265\u00f8\u028dn b\u01ddl\u00f8\u028d.", "To finalize course credit, %(display_name)s requires %(platform_name)s learners to submit a credit request.": "\u0166\u00f8 \u025f\u1d09n\u0250l\u1d09z\u01dd \u0254\u00f8n\u0279s\u01dd \u0254\u0279\u01ddd\u1d09\u0287, %(display_name)s \u0279\u01ddbn\u1d09\u0279\u01dds %(platform_name)s l\u01dd\u0250\u0279n\u01dd\u0279s \u0287\u00f8 snb\u026f\u1d09\u0287 \u0250 \u0254\u0279\u01ddd\u1d09\u0287 \u0279\u01ddbn\u01dds\u0287.", "To invalidate a certificate for a particular learner, add the username or email address below.": "\u0166\u00f8 \u1d09n\u028c\u0250l\u1d09d\u0250\u0287\u01dd \u0250 \u0254\u01dd\u0279\u0287\u1d09\u025f\u1d09\u0254\u0250\u0287\u01dd \u025f\u00f8\u0279 \u0250 d\u0250\u0279\u0287\u1d09\u0254nl\u0250\u0279 l\u01dd\u0250\u0279n\u01dd\u0279, \u0250dd \u0287\u0265\u01dd ns\u01dd\u0279n\u0250\u026f\u01dd \u00f8\u0279 \u01dd\u026f\u0250\u1d09l \u0250dd\u0279\u01ddss b\u01ddl\u00f8\u028d.", "To receive a certificate, you must also verify your identity before %(date)s.": "\u0166\u00f8 \u0279\u01dd\u0254\u01dd\u1d09\u028c\u01dd \u0250 \u0254\u01dd\u0279\u0287\u1d09\u025f\u1d09\u0254\u0250\u0287\u01dd, \u028e\u00f8n \u026fns\u0287 \u0250ls\u00f8 \u028c\u01dd\u0279\u1d09\u025f\u028e \u028e\u00f8n\u0279 \u1d09d\u01ddn\u0287\u1d09\u0287\u028e b\u01dd\u025f\u00f8\u0279\u01dd %(date)s.", @@ -1625,6 +1636,7 @@ "Video ID": "V\u1d09d\u01dd\u00f8 \u0197\u0110", "Video ended": "V\u1d09d\u01dd\u00f8 \u01ddnd\u01ddd", "Video position": "V\u1d09d\u01dd\u00f8 d\u00f8s\u1d09\u0287\u1d09\u00f8n", + "Video speed: ": "V\u1d09d\u01dd\u00f8 sd\u01dd\u01ddd: ", "Video transcript": "V\u1d09d\u01dd\u00f8 \u0287\u0279\u0250ns\u0254\u0279\u1d09d\u0287", "VideoPlayer: Element corresponding to the given selector was not found.": "V\u1d09d\u01dd\u00f8\u2c63l\u0250\u028e\u01dd\u0279: \u0246l\u01dd\u026f\u01ddn\u0287 \u0254\u00f8\u0279\u0279\u01ddsd\u00f8nd\u1d09n\u0183 \u0287\u00f8 \u0287\u0265\u01dd \u0183\u1d09\u028c\u01ddn s\u01ddl\u01dd\u0254\u0287\u00f8\u0279 \u028d\u0250s n\u00f8\u0287 \u025f\u00f8nnd.", "View": "V\u1d09\u01dd\u028d", @@ -1707,6 +1719,7 @@ "You are a member of this team.": "\u024e\u00f8n \u0250\u0279\u01dd \u0250 \u026f\u01dd\u026fb\u01dd\u0279 \u00f8\u025f \u0287\u0265\u1d09s \u0287\u01dd\u0250\u026f.", "You are currently sharing a limited profile.": "\u024e\u00f8n \u0250\u0279\u01dd \u0254n\u0279\u0279\u01ddn\u0287l\u028e s\u0265\u0250\u0279\u1d09n\u0183 \u0250 l\u1d09\u026f\u1d09\u0287\u01ddd d\u0279\u00f8\u025f\u1d09l\u01dd.", "You are enrolling in: {courseName}": "\u024e\u00f8n \u0250\u0279\u01dd \u01ddn\u0279\u00f8ll\u1d09n\u0183 \u1d09n: {courseName}", + "You are here": "\u024e\u00f8n \u0250\u0279\u01dd \u0265\u01dd\u0279\u01dd", "You are not currently a member of any team.": "\u024e\u00f8n \u0250\u0279\u01dd n\u00f8\u0287 \u0254n\u0279\u0279\u01ddn\u0287l\u028e \u0250 \u026f\u01dd\u026fb\u01dd\u0279 \u00f8\u025f \u0250n\u028e \u0287\u01dd\u0250\u026f.", "You are not enrolled in any XSeries Programs yet.": "\u024e\u00f8n \u0250\u0279\u01dd n\u00f8\u0287 \u01ddn\u0279\u00f8ll\u01ddd \u1d09n \u0250n\u028e XS\u01dd\u0279\u1d09\u01dds \u2c63\u0279\u00f8\u0183\u0279\u0250\u026fs \u028e\u01dd\u0287.", "You are now enrolled as a verified student for:": "\u024e\u00f8n \u0250\u0279\u01dd n\u00f8\u028d \u01ddn\u0279\u00f8ll\u01ddd \u0250s \u0250 \u028c\u01dd\u0279\u1d09\u025f\u1d09\u01ddd s\u0287nd\u01ddn\u0287 \u025f\u00f8\u0279:", @@ -1865,7 +1878,6 @@ "remove": "\u0279\u01dd\u026f\u00f8\u028c\u01dd", "remove all": "\u0279\u01dd\u026f\u00f8\u028c\u01dd \u0250ll", "section": "s\u01dd\u0254\u0287\u1d09\u00f8n", - "section.subtitle": "s\u01dd\u0254\u0287\u1d09\u00f8n.snb\u0287\u1d09\u0287l\u01dd", "section.title": "s\u01dd\u0254\u0287\u1d09\u00f8n.\u0287\u1d09\u0287l\u01dd", "send an email message to {email}": "s\u01ddnd \u0250n \u01dd\u026f\u0250\u1d09l \u026f\u01ddss\u0250\u0183\u01dd \u0287\u00f8 {email}", "status": "s\u0287\u0250\u0287ns", @@ -1886,7 +1898,6 @@ "with %(release_date_from)s": "\u028d\u1d09\u0287\u0265 %(release_date_from)s", "with %(section_or_subsection)s": "\u028d\u1d09\u0287\u0265 %(section_or_subsection)s", "{browse_span_start}Browse teams in other topics{span_end} or {search_span_start}search teams{span_end} in this topic. If you still can't find a team to join, {create_span_start}create a new team in this topic{span_end}.": "{browse_span_start}\u0243\u0279\u00f8\u028ds\u01dd \u0287\u01dd\u0250\u026fs \u1d09n \u00f8\u0287\u0265\u01dd\u0279 \u0287\u00f8d\u1d09\u0254s{span_end} \u00f8\u0279 {search_span_start}s\u01dd\u0250\u0279\u0254\u0265 \u0287\u01dd\u0250\u026fs{span_end} \u1d09n \u0287\u0265\u1d09s \u0287\u00f8d\u1d09\u0254. \u0197\u025f \u028e\u00f8n s\u0287\u1d09ll \u0254\u0250n'\u0287 \u025f\u1d09nd \u0250 \u0287\u01dd\u0250\u026f \u0287\u00f8 \u027e\u00f8\u1d09n, {create_span_start}\u0254\u0279\u01dd\u0250\u0287\u01dd \u0250 n\u01dd\u028d \u0287\u01dd\u0250\u026f \u1d09n \u0287\u0265\u1d09s \u0287\u00f8d\u1d09\u0254{span_end}.", - "{category}\\'s program": "{category}\\'s d\u0279\u00f8\u0183\u0279\u0250\u026f", "{email} is already on the {container} team. Recheck the email address if you want to add a new member.": "{email} \u1d09s \u0250l\u0279\u01dd\u0250d\u028e \u00f8n \u0287\u0265\u01dd {container} \u0287\u01dd\u0250\u026f. \u024c\u01dd\u0254\u0265\u01dd\u0254\u029e \u0287\u0265\u01dd \u01dd\u026f\u0250\u1d09l \u0250dd\u0279\u01ddss \u1d09\u025f \u028e\u00f8n \u028d\u0250n\u0287 \u0287\u00f8 \u0250dd \u0250 n\u01dd\u028d \u026f\u01dd\u026fb\u01dd\u0279.", "{hours}:{minutes} (current UTC time)": "{hours}:{minutes} (\u0254n\u0279\u0279\u01ddn\u0287 \u0244\u0166\u023b \u0287\u1d09\u026f\u01dd)", "{numMoved} student was removed from {oldCohort}": [ diff --git a/cms/static/js/i18n/hi/djangojs.js b/cms/static/js/i18n/hi/djangojs.js index 54cd260cc8..ef738bea45 100644 --- a/cms/static/js/i18n/hi/djangojs.js +++ b/cms/static/js/i18n/hi/djangojs.js @@ -23,6 +23,7 @@ "%(numResponses)s \u092a\u094d\u0930\u0924\u093f\u0915\u094d\u0930\u093f\u092f\u093e", "%(numResponses)s \u091c\u0935\u093e\u092c" ], + "%(total_items)s total": "%(total_items)s \u0915\u0941\u0932 \u092f\u094b\u0917", "%(unread_count)s new comment": [ "%(unread_count)s \u0928\u0908 \u091f\u093f\u092a\u094d\u092a\u0923\u0940", "%(unread_count)s \u0928\u0908 \u091f\u093f\u092a\u094d\u092a\u0923\u0940" @@ -114,6 +115,7 @@ "Files must be in JPEG or PNG format.": "\u092b\u093e\u0907\u0932\u0947\u0902 JPEG \u092f\u093e PNG \u092b\u0949\u0930\u094d\u092e\u0947\u091f \u092e\u0947\u0902 \u0939\u094b\u0928\u0940 \u091a\u093e\u0939\u093f\u092f\u0947\u0902.", "Fill browser": "\u092c\u094d\u0930\u093e\u0909\u091c\u093c\u0930 \u0938\u0915\u094d\u0930\u0940\u0928 \u0915\u094b \u092a\u0942\u0930\u093e \u0916\u094b\u0932\u0947\u0902 (open full browser)", "Find discussions": "\u091a\u0930\u094d\u091a\u093e\u0913\u0902 \u0915\u094b \u0922\u0942\u0902\u0922\u0947\u0902", + "Fullscreen": "\u092a\u0942\u0930\u094d\u0923 \u0938\u094d\u0915\u094d\u0930\u0940\u0928", "Grace period must be specified in HH:MM format.": "\u092e\u0941\u0939\u0932\u0924 \u0915\u0940 \u0905\u0935\u0927\u093f \u0915\u093e \u092a\u094d\u0930\u093e\u0930\u0942\u092a HH:MM \u0939\u094b\u0928\u093e \u091a\u093e\u0939\u093f\u090f.", "Group name is required": "\u0938\u092e\u0942\u0939 \u0915\u0947 \u0928\u093e\u092e \u0915\u0940 \u0906\u0935\u0936\u094d\u200d\u092f\u0915\u0924\u093e \u0939\u0948", "Heading": "\u0936\u0940\u0930\u094d\u0937\u0915", @@ -165,6 +167,7 @@ "Previous": "\u092a\u093f\u091b\u0932\u093e", "Redo (Ctrl+Shift+Z)": "\u092b\u093f\u0930 \u0938\u0947 \u0915\u0930\u0947\u0902 (Ctrl+Shift+Z)", "Redo (Ctrl+Y)": "\u092b\u093f\u0930 \u0938\u0947 \u0915\u0930\u0947\u0902 (Ctrl+Y)", + "Remove": "\u0939\u091f\u093e\u090f\u0902", "Reply to Annotation": "\u090f\u0928\u094b\u091f\u0947\u0936\u0928 \u0915\u093e \u091c\u0935\u093e\u092c \u0926\u0947\u0902", "Requester": "\u0928\u093f\u0935\u0947\u0926\u0915", "Rescore problem '<%= problem_id %>' for all students?": "\u0938\u092e\u0938\u094d\u092f\u093e '<%= problem_id %>' \u0915\u094b \u0938\u092c \u091b\u093e\u0924\u094d\u0930\u094b\u0902 \u0915\u0947 \u0932\u093f\u090f \u0930\u0940\u0938\u094d\u0915\u094b\u0930 \u0915\u0930\u0947\u0902?", @@ -176,6 +179,7 @@ "Show Annotations": "\u091f\u093f\u092a\u094d\u092a\u0923\u093f\u092f\u093e\u0902 \u0926\u093f\u0916\u093e\u090f\u0902", "Show Answer": "\u091c\u0935\u093e\u092c \u0926\u0947\u0916\u0947\u0902", "Show Discussion": " \u091a\u0930\u094d\u091a\u093e \u0926\u093f\u0916\u093e\u090f\u0902", + "Showing %(current_item_range)s out of %(total_items_count)s, sorted by %(sort_name)s ascending": "\u092a\u094d\u0930\u0926\u0930\u094d\u0936\u093f\u0924 \u0939\u0948 %(current_item_range)s \u092e\u0947\u0902 \u0938\u0947 %(total_items_count)s, \u0915\u0947 \u0905\u0928\u0941\u0938\u093e\u0930 \u0915\u094d\u0930\u092e\u092c\u0926\u094d\u0927 %(sort_name)s \u0906\u0930\u094b\u0939\u0940 \u0915\u094d\u0930\u092e \u092e\u0947\u0902", "Showing all responses": "\u0938\u092d\u0940 \u091c\u0935\u093e\u092c \u0926\u093f\u0916\u093e\u090f \u091c\u093e \u0930\u0939\u0947 \u0939\u0948\u0902", "Showing first response": [ "\u092a\u0939\u0932\u0940 %(numResponses)s \u092a\u094d\u0930\u0924\u093f\u0915\u094d\u0930\u093f\u092f\u093e\u090f\u0902 ", @@ -215,6 +219,7 @@ "These users will be enrolled once they register:": "\u0930\u091c\u093f\u0938\u094d\u091f\u0930 \u0939\u094b\u0928\u0947 \u0915\u0947 \u092c\u093e\u0926 \u0907\u0928 \u091b\u093e\u0924\u094d\u0930\u094b\u0902 \u0915\u093e \u0928\u093e\u092e\u093e\u0902\u0915\u0928 \u0915\u0930 \u0926\u093f\u092f\u093e \u091c\u093e\u090f\u0917\u093e:", "This action cannot be undone.": "\u0907\u0938 \u0915\u094d\u0930\u093f\u092f\u093e \u0915\u094b \u092a\u0942\u0930\u094d\u0935\u0935\u0924 \u0928\u0939\u0940\u0902 \u0915\u093f\u092f\u093e \u091c\u093e \u0938\u0915\u0924\u093e \u0939\u0948.", "This link will open in a modal window": "\u092f\u0939 \u0932\u093f\u0902\u0915 \u090f\u0915 \u092e\u0949\u0921\u0932 \u0935\u093f\u0902\u0921\u094b \u091f\u0948\u092c \u092e\u0947\u0902 \u0916\u0941\u0932\u0947\u0917\u0940", + "This link will open in a new browser window/tab": "\u092f\u0939 \u0932\u093f\u0902\u0915 \u090f\u0915 \u0928\u090f \u092c\u094d\u0930\u093e\u0909\u095b\u0930 \u0935\u093f\u0902\u0921\u094b / \u091f\u0948\u092c \u092e\u0947\u0902 \u0916\u0941\u0932\u0947\u0917\u0940", "This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.": "\u0939\u092e\u093e\u0930\u0947 \u0938\u0930\u094d\u0935\u0930 \u092a\u0930 \u0924\u094d\u0930\u0941\u091f\u093f \u0915\u0947 \u0935\u091c\u0939 \u0938\u0947 \u092f\u093e \u0906\u092a\u0915\u0947 \u0907\u0902\u091f\u0930\u0928\u0947\u091f \u0915\u0928\u0947\u0915\u094d\u0936\u0928 \u0915\u0947 \u0938\u093e\u0925 \u0915\u093f\u0938\u0940 \u0924\u094d\u0930\u0941\u091f\u093f \u0915\u0947 \u0915\u093e\u0930\u0923 \u092f\u0939 \u0939\u094b \u0938\u0915\u0924\u093e \u0939\u0948| \u092a\u0943\u0937\u094d\u0920 \u092b\u093f\u0930 \u0938\u0947 \u0916\u094b\u0932\u0947 \u092f\u093e \u0938\u0941\u0928\u093f\u0936\u094d\u091a\u093f\u0924 \u0915\u0930\u0947\u0902 \u0915\u093f \u0906\u092a \u0911\u0928\u0932\u093e\u0907\u0928 \u0939\u0948\u0902|", "Unable to retrieve data, please try again later.": "\u0921\u0947\u091f\u093e \u092a\u0941\u0928\u0903 \u092a\u094d\u0930\u093e\u092a\u094d\u0924 \u0915\u0930\u0928\u0947 \u092e\u0947\u0902 \u0905\u0938\u092e\u0930\u094d\u0925 \u0939\u0948, \u0915\u0943\u092a\u092f\u093e \u092b\u093f\u0930 \u0938\u0947 \u0915\u094b\u0936\u093f\u0936 \u0915\u0930\u0947\u0902", "Undo (Ctrl+Z)": "\u092b\u093f\u0930 \u0938\u0947 \u0915\u0930\u0947\u0902 (Ctrl+Z)", diff --git a/cms/static/js/i18n/rtl/djangojs.js b/cms/static/js/i18n/rtl/djangojs.js index f49abcbb19..f8f88d1f9e 100644 --- a/cms/static/js/i18n/rtl/djangojs.js +++ b/cms/static/js/i18n/rtl/djangojs.js @@ -172,10 +172,12 @@ "Add URLs for additional versions": "\u0634\u064a\u064a \u0639\u0642\u0645\u0633 \u0628\u062e\u0642 \u0634\u064a\u064a\u0647\u0641\u0647\u062e\u0631\u0634\u0645 \u062f\u062b\u0642\u0633\u0647\u062e\u0631\u0633", "Add a Chapter": "\u0634\u064a\u064a \u0634 \u0630\u0627\u0634\u062d\u0641\u062b\u0642", "Add a New Cohort": "\u0634\u064a\u064a \u0634 \u0631\u062b\u0635 \u0630\u062e\u0627\u062e\u0642\u0641", + "Add a Post": "\u0634\u064a\u064a \u0634 \u062d\u062e\u0633\u0641", "Add a Response": "\u0634\u064a\u064a \u0634 \u0642\u062b\u0633\u062d\u062e\u0631\u0633\u062b", "Add a clear and descriptive title to encourage participation.": "\u0634\u064a\u064a \u0634 \u0630\u0645\u062b\u0634\u0642 \u0634\u0631\u064a \u064a\u062b\u0633\u0630\u0642\u0647\u062d\u0641\u0647\u062f\u062b \u0641\u0647\u0641\u0645\u062b \u0641\u062e \u062b\u0631\u0630\u062e\u0639\u0642\u0634\u0644\u062b \u062d\u0634\u0642\u0641\u0647\u0630\u0647\u062d\u0634\u0641\u0647\u062e\u0631.", "Add a comment": "\u0634\u064a\u064a \u0634 \u0630\u062e\u0648\u0648\u062b\u0631\u0641", "Add a learning outcome here": "\u0634\u064a\u064a \u0634 \u0645\u062b\u0634\u0642\u0631\u0647\u0631\u0644 \u062e\u0639\u0641\u0630\u062e\u0648\u062b \u0627\u062b\u0642\u062b", + "Add a response:": "\u0634\u064a\u064a \u0634 \u0642\u062b\u0633\u062d\u062e\u0631\u0633\u062b:", "Add another group": "\u0634\u064a\u064a \u0634\u0631\u062e\u0641\u0627\u062b\u0642 \u0644\u0642\u062e\u0639\u062d", "Add language": "\u0634\u064a\u064a \u0645\u0634\u0631\u0644\u0639\u0634\u0644\u062b", "Add notes about this learner": "\u0634\u064a\u064a \u0631\u062e\u0641\u062b\u0633 \u0634\u0632\u062e\u0639\u0641 \u0641\u0627\u0647\u0633 \u0645\u062b\u0634\u0642\u0631\u062b\u0642", @@ -206,6 +208,7 @@ "All flags have been removed. To undo, uncheck the box.": "\u0634\u0645\u0645 \u0628\u0645\u0634\u0644\u0633 \u0627\u0634\u062f\u062b \u0632\u062b\u062b\u0631 \u0642\u062b\u0648\u062e\u062f\u062b\u064a. \u0641\u062e \u0639\u0631\u064a\u062e, \u0639\u0631\u0630\u0627\u062b\u0630\u0646 \u0641\u0627\u062b \u0632\u062e\u0637.", "All groups must have a name.": "\u0634\u0645\u0645 \u0644\u0642\u062e\u0639\u062d\u0633 \u0648\u0639\u0633\u0641 \u0627\u0634\u062f\u062b \u0634 \u0631\u0634\u0648\u062b.", "All groups must have a unique name.": "\u0634\u0645\u0645 \u0644\u0642\u062e\u0639\u062d\u0633 \u0648\u0639\u0633\u0641 \u0627\u0634\u062f\u062b \u0634 \u0639\u0631\u0647\u0636\u0639\u062b \u0631\u0634\u0648\u062b.", + "All learners in the {cohort_name} cohort": "\u0634\u0645\u0645 \u0645\u062b\u0634\u0642\u0631\u062b\u0642\u0633 \u0647\u0631 \u0641\u0627\u062b {cohort_name} \u0630\u062e\u0627\u062e\u0642\u0641", "All learners who are enrolled in this course": "\u0634\u0645\u0645 \u0645\u062b\u0634\u0642\u0631\u062b\u0642\u0633 \u0635\u0627\u062e \u0634\u0642\u062b \u062b\u0631\u0642\u062e\u0645\u0645\u062b\u064a \u0647\u0631 \u0641\u0627\u0647\u0633 \u0630\u062e\u0639\u0642\u0633\u062b", "All payment options are currently unavailable.": "\u0634\u0645\u0645 \u062d\u0634\u063a\u0648\u062b\u0631\u0641 \u062e\u062d\u0641\u0647\u062e\u0631\u0633 \u0634\u0642\u062b \u0630\u0639\u0642\u0642\u062b\u0631\u0641\u0645\u063a \u0639\u0631\u0634\u062f\u0634\u0647\u0645\u0634\u0632\u0645\u062b.", "All professional education courses are fee-based, and require payment to complete the enrollment process.": "\u0634\u0645\u0645 \u062d\u0642\u062e\u0628\u062b\u0633\u0633\u0647\u062e\u0631\u0634\u0645 \u062b\u064a\u0639\u0630\u0634\u0641\u0647\u062e\u0631 \u0630\u062e\u0639\u0642\u0633\u062b\u0633 \u0634\u0642\u062b \u0628\u062b\u062b-\u0632\u0634\u0633\u062b\u064a, \u0634\u0631\u064a \u0642\u062b\u0636\u0639\u0647\u0642\u062b \u062d\u0634\u063a\u0648\u062b\u0631\u0641 \u0641\u062e \u0630\u062e\u0648\u062d\u0645\u062b\u0641\u062b \u0641\u0627\u062b \u062b\u0631\u0642\u062e\u0645\u0645\u0648\u062b\u0631\u0641 \u062d\u0642\u062e\u0630\u062b\u0633\u0633.", @@ -476,7 +479,7 @@ "Custom...": "\u0630\u0639\u0633\u0641\u062e\u0648...", "Cut": "\u0630\u0639\u0641", "Cut row": "\u0630\u0639\u0641 \u0642\u062e\u0635", - "DISCUSSION HOME:": "\u064a\u0647\u0633\u0630\u0639\u0633\u0633\u0647\u062e\u0631 \u0627\u062e\u0648\u062b:", + "Dashboard": "\u064a\u0634\u0633\u0627\u0632\u062e\u0634\u0642\u064a", "Date": "\u064a\u0634\u0641\u062b", "Date Added": "\u064a\u0634\u0641\u062b \u0634\u064a\u064a\u062b\u064a", "Date added": "\u064a\u0634\u0641\u062b \u0634\u064a\u064a\u062b\u064a", @@ -515,6 +518,7 @@ "Discard Changes": "\u064a\u0647\u0633\u0630\u0634\u0642\u064a \u0630\u0627\u0634\u0631\u0644\u062b\u0633", "Discarding Changes": "\u064a\u0647\u0633\u0630\u0634\u0642\u064a\u0647\u0631\u0644 \u0630\u0627\u0634\u0631\u0644\u062b\u0633", "Discussion": "\u064a\u0647\u0633\u0630\u0639\u0633\u0633\u0647\u062e\u0631", + "Discussion Home": "\u064a\u0647\u0633\u0630\u0639\u0633\u0633\u0647\u062e\u0631 \u0627\u062e\u0648\u062b", "Discussion admins, moderators, and TAs can make their posts visible to all students or specify a single cohort.": "\u064a\u0647\u0633\u0630\u0639\u0633\u0633\u0647\u062e\u0631 \u0634\u064a\u0648\u0647\u0631\u0633, \u0648\u062e\u064a\u062b\u0642\u0634\u0641\u062e\u0642\u0633, \u0634\u0631\u064a \u0641\u0634\u0633 \u0630\u0634\u0631 \u0648\u0634\u0646\u062b \u0641\u0627\u062b\u0647\u0642 \u062d\u062e\u0633\u0641\u0633 \u062f\u0647\u0633\u0647\u0632\u0645\u062b \u0641\u062e \u0634\u0645\u0645 \u0633\u0641\u0639\u064a\u062b\u0631\u0641\u0633 \u062e\u0642 \u0633\u062d\u062b\u0630\u0647\u0628\u063a \u0634 \u0633\u0647\u0631\u0644\u0645\u062b \u0630\u062e\u0627\u062e\u0642\u0641.", "Discussion topics; currently listing: ": "\u064a\u0647\u0633\u0630\u0639\u0633\u0633\u0647\u062e\u0631 \u0641\u062e\u062d\u0647\u0630\u0633; \u0630\u0639\u0642\u0642\u062b\u0631\u0641\u0645\u063a \u0645\u0647\u0633\u0641\u0647\u0631\u0644: ", "Display Name": "\u064a\u0647\u0633\u062d\u0645\u0634\u063a \u0631\u0634\u0648\u062b", @@ -918,6 +922,7 @@ "Muted": "\u0648\u0639\u0641\u062b\u064a", "My Bookmarks": "\u0648\u063a \u0632\u062e\u062e\u0646\u0648\u0634\u0642\u0646\u0633", "My Notes": "\u0648\u063a \u0631\u062e\u0641\u062b\u0633", + "My Orders": "\u0648\u063a \u062e\u0642\u064a\u062b\u0642\u0633", "My Team": "\u0648\u063a \u0641\u062b\u0634\u0648", "N/A": "\u0631/\u0634", "Name": "\u0631\u0634\u0648\u062b", @@ -930,7 +935,6 @@ "New %(component_type)s": "\u0631\u062b\u0635 %(component_type)s", "New %(item_type)s": "\u0631\u062b\u0635 %(item_type)s", "New Address": "\u0631\u062b\u0635 \u0634\u064a\u064a\u0642\u062b\u0633\u0633", - "New Post": "\u0631\u062b\u0635 \u062d\u062e\u0633\u0641", "New document": "\u0631\u062b\u0635 \u064a\u062e\u0630\u0639\u0648\u062b\u0631\u0641", "New enrollment mode:": "\u0631\u062b\u0635 \u062b\u0631\u0642\u062e\u0645\u0645\u0648\u062b\u0631\u0641 \u0648\u062e\u064a\u062b:", "New to %(platformName)s?": "\u0631\u062b\u0635 \u0641\u062e %(platformName)s?", @@ -976,6 +980,9 @@ "Numbered List (Ctrl+O)": "\u0631\u0639\u0648\u0632\u062b\u0642\u062b\u064a \u0645\u0647\u0633\u0641 (\u0630\u0641\u0642\u0645+\u062e)", "Numbered list": "\u0631\u0639\u0648\u0632\u062b\u0642\u062b\u064a \u0645\u0647\u0633\u0641", "OK": "\u062e\u0646", + "ORDER NAME": "\u062e\u0642\u064a\u062b\u0642 \u0631\u0634\u0648\u062b", + "ORDER NUMBER": "\u062e\u0642\u064a\u062b\u0642 \u0631\u0639\u0648\u0632\u062b\u0642", + "ORDER PLACED": "\u062e\u0642\u064a\u062b\u0642 \u062d\u0645\u0634\u0630\u062b\u064a", "Ok": "\u062e\u0646", "Once in position, use the camera button {icon} to capture your ID": "\u062e\u0631\u0630\u062b \u0647\u0631 \u062d\u062e\u0633\u0647\u0641\u0647\u062e\u0631, \u0639\u0633\u062b \u0641\u0627\u062b \u0630\u0634\u0648\u062b\u0642\u0634 \u0632\u0639\u0641\u0641\u062e\u0631 {icon} \u0641\u062e \u0630\u0634\u062d\u0641\u0639\u0642\u062b \u063a\u062e\u0639\u0642 \u0647\u064a", "Once in position, use the camera button {icon} to capture your photo": "\u062e\u0631\u0630\u062b \u0647\u0631 \u062d\u062e\u0633\u0647\u0641\u0647\u062e\u0631, \u0639\u0633\u062b \u0641\u0627\u062b \u0630\u0634\u0648\u062b\u0642\u0634 \u0632\u0639\u0641\u0641\u062e\u0631 {icon} \u0641\u062e \u0630\u0634\u062d\u0641\u0639\u0642\u062b \u063a\u062e\u0639\u0642 \u062d\u0627\u062e\u0641\u062e", @@ -990,6 +997,8 @@ "Optional Characteristics": "\u062e\u062d\u0641\u0647\u062e\u0631\u0634\u0645 \u0630\u0627\u0634\u0642\u0634\u0630\u0641\u062b\u0642\u0647\u0633\u0641\u0647\u0630\u0633", "Optional long description": "\u062e\u062d\u0641\u0647\u062e\u0631\u0634\u0645 \u0645\u062e\u0631\u0644 \u064a\u062b\u0633\u0630\u0642\u0647\u062d\u0641\u0647\u062e\u0631", "Options for {license_name}": "\u062e\u062d\u0641\u0647\u062e\u0631\u0633 \u0628\u062e\u0642 {license_name}", + "Order Details": "\u062e\u0642\u064a\u062b\u0642 \u064a\u062b\u0641\u0634\u0647\u0645\u0633", + "Order History": "\u062e\u0642\u064a\u062b\u0642 \u0627\u0647\u0633\u0641\u062e\u0642\u063a", "Order No.": "\u062e\u0642\u064a\u062b\u0642 \u0631\u062e.", "Organization": "\u062e\u0642\u0644\u0634\u0631\u0647\u0638\u0634\u0641\u0647\u062e\u0631", "Organization ": "\u062e\u0642\u0644\u0634\u0631\u0647\u0638\u0634\u0641\u0647\u062e\u0631 ", @@ -1063,7 +1072,6 @@ "Please verify that you have uploaded a valid image (PNG and JPEG).": "\u062d\u0645\u062b\u0634\u0633\u062b \u062f\u062b\u0642\u0647\u0628\u063a \u0641\u0627\u0634\u0641 \u063a\u062e\u0639 \u0627\u0634\u062f\u062b \u0639\u062d\u0645\u062e\u0634\u064a\u062b\u064a \u0634 \u062f\u0634\u0645\u0647\u064a \u0647\u0648\u0634\u0644\u062b (\u062d\u0631\u0644 \u0634\u0631\u064a \u062a\u062d\u062b\u0644).", "Please verify that your webcam is connected and that you have allowed your browser to access it.": "\u062d\u0645\u062b\u0634\u0633\u062b \u062f\u062b\u0642\u0647\u0628\u063a \u0641\u0627\u0634\u0641 \u063a\u062e\u0639\u0642 \u0635\u062b\u0632\u0630\u0634\u0648 \u0647\u0633 \u0630\u062e\u0631\u0631\u062b\u0630\u0641\u062b\u064a \u0634\u0631\u064a \u0641\u0627\u0634\u0641 \u063a\u062e\u0639 \u0627\u0634\u062f\u062b \u0634\u0645\u0645\u062e\u0635\u062b\u064a \u063a\u062e\u0639\u0642 \u0632\u0642\u062e\u0635\u0633\u062b\u0642 \u0641\u062e \u0634\u0630\u0630\u062b\u0633\u0633 \u0647\u0641.", "Post": "\u062d\u062e\u0633\u0641", - "Post a response:": "\u062d\u062e\u0633\u0641 \u0634 \u0642\u062b\u0633\u062d\u062e\u0631\u0633\u062b:", "Post body": "\u062d\u062e\u0633\u0641 \u0632\u062e\u064a\u063a", "Post type:": "\u062d\u062e\u0633\u0641 \u0641\u063a\u062d\u062b:", "Poster": "\u062d\u062e\u0633\u0641\u062b\u0642", @@ -1203,6 +1211,7 @@ "Selected tab": "\u0633\u062b\u0645\u062b\u0630\u0641\u062b\u064a \u0641\u0634\u0632", "Send notification to mobile apps": "\u0633\u062b\u0631\u064a \u0631\u062e\u0641\u0647\u0628\u0647\u0630\u0634\u0641\u0647\u062e\u0631 \u0641\u062e \u0648\u062e\u0632\u0647\u0645\u062b \u0634\u062d\u062d\u0633", "Send push notification to mobile apps": "\u0633\u062b\u0631\u064a \u062d\u0639\u0633\u0627 \u0631\u062e\u0641\u0647\u0628\u0647\u0630\u0634\u0641\u0647\u062e\u0631 \u0641\u062e \u0648\u062e\u0632\u0647\u0645\u062b \u0634\u062d\u062d\u0633", + "Send to:": "\u0633\u062b\u0631\u064a \u0641\u062e:", "Sent By": "\u0633\u062b\u0631\u0641 \u0632\u063a", "Sent By:": "\u0633\u062b\u0631\u0641 \u0632\u063a:", "Sent To": "\u0633\u062b\u0631\u0641 \u0641\u062e", @@ -1285,6 +1294,7 @@ "Started entrance exam rescore task for student '{student_id}'. Click the 'Show Background Task History for Student' button to see the status of the task.": "\u0633\u0641\u0634\u0642\u0641\u062b\u064a \u062b\u0631\u0641\u0642\u0634\u0631\u0630\u062b \u062b\u0637\u0634\u0648 \u0642\u062b\u0633\u0630\u062e\u0642\u062b \u0641\u0634\u0633\u0646 \u0628\u062e\u0642 \u0633\u0641\u0639\u064a\u062b\u0631\u0641 '{student_id}'. \u0630\u0645\u0647\u0630\u0646 \u0641\u0627\u062b '\u0633\u0627\u062e\u0635 \u0632\u0634\u0630\u0646\u0644\u0642\u062e\u0639\u0631\u064a \u0641\u0634\u0633\u0646 \u0627\u0647\u0633\u0641\u062e\u0642\u063a \u0628\u062e\u0642 \u0633\u0641\u0639\u064a\u062b\u0631\u0641' \u0632\u0639\u0641\u0641\u062e\u0631 \u0641\u062e \u0633\u062b\u062b \u0641\u0627\u062b \u0633\u0641\u0634\u0641\u0639\u0633 \u062e\u0628 \u0641\u0627\u062b \u0641\u0634\u0633\u0646.", "Started rescore problem task for problem '<%= problem_id %>' and student '<%= student_id %>'. Click the 'Show Background Task History for Student' button to see the status of the task.": "\u0633\u0641\u0634\u0642\u0641\u062b\u064a \u0642\u062b\u0633\u0630\u062e\u0642\u062b \u062d\u0642\u062e\u0632\u0645\u062b\u0648 \u0641\u0634\u0633\u0646 \u0628\u062e\u0642 \u062d\u0642\u062e\u0632\u0645\u062b\u0648 '<%= problem_id %>' \u0634\u0631\u064a \u0633\u0641\u0639\u064a\u062b\u0631\u0641 '<%= student_id %>'. \u0630\u0645\u0647\u0630\u0646 \u0641\u0627\u062b '\u0633\u0627\u062e\u0635 \u0632\u0634\u0630\u0646\u0644\u0642\u062e\u0639\u0631\u064a \u0641\u0634\u0633\u0646 \u0627\u0647\u0633\u0641\u062e\u0642\u063a \u0628\u062e\u0642 \u0633\u0641\u0639\u064a\u062b\u0631\u0641' \u0632\u0639\u0641\u0641\u062e\u0631 \u0641\u062e \u0633\u062b\u062b \u0641\u0627\u062b \u0633\u0641\u0634\u0641\u0639\u0633 \u062e\u0628 \u0641\u0627\u062b \u0641\u0634\u0633\u0646.", "Starts": "\u0633\u0641\u0634\u0642\u0641\u0633", + "Starts %(start)s": "\u0633\u0641\u0634\u0642\u0641\u0633 %(start)s", "Starts: %(start)s": "\u0633\u0641\u0634\u0642\u0641\u0633: %(start)s", "Starts: %(start_date)s": "\u0633\u0641\u0634\u0642\u0641\u0633: %(start_date)s", "State": "\u0633\u0641\u0634\u0641\u062b", @@ -1319,6 +1329,7 @@ "Successfully started task to reset attempts for problem '<%= problem_id %>'. Click the 'Show Background Task History for Problem' button to see the status of the task.": "\u0633\u0639\u0630\u0630\u062b\u0633\u0633\u0628\u0639\u0645\u0645\u063a \u0633\u0641\u0634\u0642\u0641\u062b\u064a \u0641\u0634\u0633\u0646 \u0641\u062e \u0642\u062b\u0633\u062b\u0641 \u0634\u0641\u0641\u062b\u0648\u062d\u0641\u0633 \u0628\u062e\u0642 \u062d\u0642\u062e\u0632\u0645\u062b\u0648 '<%= problem_id %>'. \u0630\u0645\u0647\u0630\u0646 \u0641\u0627\u062b '\u0633\u0627\u062e\u0635 \u0632\u0634\u0630\u0646\u0644\u0642\u062e\u0639\u0631\u064a \u0641\u0634\u0633\u0646 \u0627\u0647\u0633\u0641\u062e\u0642\u063a \u0628\u062e\u0642 \u062d\u0642\u062e\u0632\u0645\u062b\u0648' \u0632\u0639\u0641\u0641\u062e\u0631 \u0641\u062e \u0633\u062b\u062b \u0641\u0627\u062b \u0633\u0641\u0634\u0641\u0639\u0633 \u062e\u0628 \u0641\u0627\u062b \u0641\u0634\u0633\u0646.", "Successfully unlinked.": "\u0633\u0639\u0630\u0630\u062b\u0633\u0633\u0628\u0639\u0645\u0645\u063a \u0639\u0631\u0645\u0647\u0631\u0646\u062b\u064a.", "Superscript": "\u0633\u0639\u062d\u062b\u0642\u0633\u0630\u0642\u0647\u062d\u0641", + "TOTAL": "\u0641\u062e\u0641\u0634\u0645", "Table": "\u0641\u0634\u0632\u0645\u062b", "Table properties": "\u0641\u0634\u0632\u0645\u062b \u062d\u0642\u062e\u062d\u062b\u0642\u0641\u0647\u062b\u0633", "Tags": "\u0641\u0634\u0644\u0633", @@ -1355,9 +1366,9 @@ "Textbook Name": "\u0641\u062b\u0637\u0641\u0632\u062e\u062e\u0646 \u0631\u0634\u0648\u062b", "Textbook information": "\u0641\u062b\u0637\u0641\u0632\u062e\u062e\u0646 \u0647\u0631\u0628\u062e\u0642\u0648\u0634\u0641\u0647\u062e\u0631", "Textbook name is required": "\u0641\u062b\u0637\u0641\u0632\u062e\u062e\u0646 \u0631\u0634\u0648\u062b \u0647\u0633 \u0642\u062b\u0636\u0639\u0647\u0642\u062b\u064a", + "Thank you %(full_name)s! We have received your payment for %(course_name)s.": "\u0641\u0627\u0634\u0631\u0646 \u063a\u062e\u0639 %(full_name)s! \u0635\u062b \u0627\u0634\u062f\u062b \u0642\u062b\u0630\u062b\u0647\u062f\u062b\u064a \u063a\u062e\u0639\u0642 \u062d\u0634\u063a\u0648\u062b\u0631\u0641 \u0628\u062e\u0642 %(course_name)s.", "Thank you for submitting your financial assistance application for {course_name}! You can expect a response in 2-4 business days.": "\u0641\u0627\u0634\u0631\u0646 \u063a\u062e\u0639 \u0628\u062e\u0642 \u0633\u0639\u0632\u0648\u0647\u0641\u0641\u0647\u0631\u0644 \u063a\u062e\u0639\u0642 \u0628\u0647\u0631\u0634\u0631\u0630\u0647\u0634\u0645 \u0634\u0633\u0633\u0647\u0633\u0641\u0634\u0631\u0630\u062b \u0634\u062d\u062d\u0645\u0647\u0630\u0634\u0641\u0647\u062e\u0631 \u0628\u062e\u0642 {course_name}! \u063a\u062e\u0639 \u0630\u0634\u0631 \u062b\u0637\u062d\u062b\u0630\u0641 \u0634 \u0642\u062b\u0633\u062d\u062e\u0631\u0633\u062b \u0647\u0631 2-4 \u0632\u0639\u0633\u0647\u0631\u062b\u0633\u0633 \u064a\u0634\u063a\u0633.", "Thank you for submitting your photos. We will review them shortly. You can now sign up for any %(platformName)s course that offers verified certificates. Verification is good for one year. After one year, you must submit photos for verification again.": "\u0641\u0627\u0634\u0631\u0646 \u063a\u062e\u0639 \u0628\u062e\u0642 \u0633\u0639\u0632\u0648\u0647\u0641\u0641\u0647\u0631\u0644 \u063a\u062e\u0639\u0642 \u062d\u0627\u062e\u0641\u062e\u0633. \u0635\u062b \u0635\u0647\u0645\u0645 \u0642\u062b\u062f\u0647\u062b\u0635 \u0641\u0627\u062b\u0648 \u0633\u0627\u062e\u0642\u0641\u0645\u063a. \u063a\u062e\u0639 \u0630\u0634\u0631 \u0631\u062e\u0635 \u0633\u0647\u0644\u0631 \u0639\u062d \u0628\u062e\u0642 \u0634\u0631\u063a %(platformName)s \u0630\u062e\u0639\u0642\u0633\u062b \u0641\u0627\u0634\u0641 \u062e\u0628\u0628\u062b\u0642\u0633 \u062f\u062b\u0642\u0647\u0628\u0647\u062b\u064a \u0630\u062b\u0642\u0641\u0647\u0628\u0647\u0630\u0634\u0641\u062b\u0633. \u062f\u062b\u0642\u0647\u0628\u0647\u0630\u0634\u0641\u0647\u062e\u0631 \u0647\u0633 \u0644\u062e\u062e\u064a \u0628\u062e\u0642 \u062e\u0631\u062b \u063a\u062b\u0634\u0642. \u0634\u0628\u0641\u062b\u0642 \u062e\u0631\u062b \u063a\u062b\u0634\u0642, \u063a\u062e\u0639 \u0648\u0639\u0633\u0641 \u0633\u0639\u0632\u0648\u0647\u0641 \u062d\u0627\u062e\u0641\u062e\u0633 \u0628\u062e\u0642 \u062f\u062b\u0642\u0647\u0628\u0647\u0630\u0634\u0641\u0647\u062e\u0631 \u0634\u0644\u0634\u0647\u0631.", - "Thank you! We have received your payment for %(course_name)s.": "\u0641\u0627\u0634\u0631\u0646 \u063a\u062e\u0639! \u0635\u062b \u0627\u0634\u062f\u062b \u0642\u062b\u0630\u062b\u0647\u062f\u062b\u064a \u063a\u062e\u0639\u0642 \u062d\u0634\u063a\u0648\u062b\u0631\u0641 \u0628\u062e\u0642 %(course_name)s.", "Thank you! We have received your payment for {courseName}.": "\u0641\u0627\u0634\u0631\u0646 \u063a\u062e\u0639! \u0635\u062b \u0627\u0634\u062f\u062b \u0642\u062b\u0630\u062b\u0647\u062f\u062b\u064a \u063a\u062e\u0639\u0642 \u062d\u0634\u063a\u0648\u062b\u0631\u0641 \u0628\u062e\u0642 {courseName}.", "Thanks for returning to verify your ID in: {courseName}": "\u0641\u0627\u0634\u0631\u0646\u0633 \u0628\u062e\u0642 \u0642\u062b\u0641\u0639\u0642\u0631\u0647\u0631\u0644 \u0641\u062e \u062f\u062b\u0642\u0647\u0628\u063a \u063a\u062e\u0639\u0642 \u0647\u064a \u0647\u0631: {courseName}", "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u0641\u0627\u062b \u0639\u0642\u0645 \u063a\u062e\u0639 \u062b\u0631\u0641\u062b\u0642\u062b\u064a \u0633\u062b\u062b\u0648\u0633 \u0641\u062e \u0632\u062b \u0634\u0631 \u062b\u0648\u0634\u0647\u0645 \u0634\u064a\u064a\u0642\u062b\u0633\u0633. \u064a\u062e \u063a\u062e\u0639 \u0635\u0634\u0631\u0641 \u0641\u062e \u0634\u064a\u064a \u0641\u0627\u062b \u0642\u062b\u0636\u0639\u0647\u0642\u062b\u064a \u0648\u0634\u0647\u0645\u0641\u062e: \u062d\u0642\u062b\u0628\u0647\u0637?", @@ -1470,6 +1481,7 @@ "This link will open in a modal window": "\u0641\u0627\u0647\u0633 \u0645\u0647\u0631\u0646 \u0635\u0647\u0645\u0645 \u062e\u062d\u062b\u0631 \u0647\u0631 \u0634 \u0648\u062e\u064a\u0634\u0645 \u0635\u0647\u0631\u064a\u062e\u0635", "This link will open in a new browser window/tab": "\u0641\u0627\u0647\u0633 \u0645\u0647\u0631\u0646 \u0635\u0647\u0645\u0645 \u062e\u062d\u062b\u0631 \u0647\u0631 \u0634 \u0631\u062b\u0635 \u0632\u0642\u062e\u0635\u0633\u062b\u0642 \u0635\u0647\u0631\u064a\u062e\u0635/\u0641\u0634\u0632", "This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.": "\u0641\u0627\u0647\u0633 \u0648\u0634\u063a \u0632\u062b \u0627\u0634\u062d\u062d\u062b\u0631\u0647\u0631\u0644 \u0632\u062b\u0630\u0634\u0639\u0633\u062b \u062e\u0628 \u0634\u0631 \u062b\u0642\u0642\u062e\u0642 \u0635\u0647\u0641\u0627 \u062e\u0639\u0642 \u0633\u062b\u0642\u062f\u062b\u0642 \u062e\u0642 \u063a\u062e\u0639\u0642 \u0647\u0631\u0641\u062b\u0642\u0631\u062b\u0641 \u0630\u062e\u0631\u0631\u062b\u0630\u0641\u0647\u062e\u0631. \u0641\u0642\u063a \u0642\u062b\u0628\u0642\u062b\u0633\u0627\u0647\u0631\u0644 \u0641\u0627\u062b \u062d\u0634\u0644\u062b \u062e\u0642 \u0648\u0634\u0646\u0647\u0631\u0644 \u0633\u0639\u0642\u062b \u063a\u062e\u0639 \u0634\u0642\u062b \u062e\u0631\u0645\u0647\u0631\u062b.", + "This page contains information about orders that you have placed with {platform_name}.": "\u0641\u0627\u0647\u0633 \u062d\u0634\u0644\u062b \u0630\u062e\u0631\u0641\u0634\u0647\u0631\u0633 \u0647\u0631\u0628\u062e\u0642\u0648\u0634\u0641\u0647\u062e\u0631 \u0634\u0632\u062e\u0639\u0641 \u062e\u0642\u064a\u062b\u0642\u0633 \u0641\u0627\u0634\u0641 \u063a\u062e\u0639 \u0627\u0634\u062f\u062b \u062d\u0645\u0634\u0630\u062b\u064a \u0635\u0647\u0641\u0627 {platform_name}.", "This post is visible only to %(group_name)s.": "\u0641\u0627\u0647\u0633 \u062d\u062e\u0633\u0641 \u0647\u0633 \u062f\u0647\u0633\u0647\u0632\u0645\u062b \u062e\u0631\u0645\u063a \u0641\u062e %(group_name)s.", "This post is visible to everyone.": "\u0641\u0627\u0647\u0633 \u062d\u062e\u0633\u0641 \u0647\u0633 \u062f\u0647\u0633\u0647\u0632\u0645\u062b \u0641\u062e \u062b\u062f\u062b\u0642\u063a\u062e\u0631\u062b.", "This short name for the assignment type (for example, HW or Midterm) appears next to assignments on a learner's Progress page.": "\u0641\u0627\u0647\u0633 \u0633\u0627\u062e\u0642\u0641 \u0631\u0634\u0648\u062b \u0628\u062e\u0642 \u0641\u0627\u062b \u0634\u0633\u0633\u0647\u0644\u0631\u0648\u062b\u0631\u0641 \u0641\u063a\u062d\u062b (\u0628\u062e\u0642 \u062b\u0637\u0634\u0648\u062d\u0645\u062b, \u0627\u0635 \u062e\u0642 \u0648\u0647\u064a\u0641\u062b\u0642\u0648) \u0634\u062d\u062d\u062b\u0634\u0642\u0633 \u0631\u062b\u0637\u0641 \u0641\u062e \u0634\u0633\u0633\u0647\u0644\u0631\u0648\u062b\u0631\u0641\u0633 \u062e\u0631 \u0634 \u0645\u062b\u0634\u0642\u0631\u062b\u0642'\u0633 \u062d\u0642\u062e\u0644\u0642\u062b\u0633\u0633 \u062d\u0634\u0644\u062b.", @@ -1492,7 +1504,6 @@ "Title:": "\u0641\u0647\u0641\u0645\u062b:", "Titles more than 100 characters may prevent students from printing their certificate on a single page.": "\u0641\u0647\u0641\u0645\u062b\u0633 \u0648\u062e\u0642\u062b \u0641\u0627\u0634\u0631 100 \u0630\u0627\u0634\u0642\u0634\u0630\u0641\u062b\u0642\u0633 \u0648\u0634\u063a \u062d\u0642\u062b\u062f\u062b\u0631\u0641 \u0633\u0641\u0639\u064a\u062b\u0631\u0641\u0633 \u0628\u0642\u062e\u0648 \u062d\u0642\u0647\u0631\u0641\u0647\u0631\u0644 \u0641\u0627\u062b\u0647\u0642 \u0630\u062b\u0642\u0641\u0647\u0628\u0647\u0630\u0634\u0641\u062b \u062e\u0631 \u0634 \u0633\u0647\u0631\u0644\u0645\u062b \u062d\u0634\u0644\u062b.", "To be sure all students can access the video, we recommend providing both an .mp4 and a .webm version of your video. Click below to add a URL for another version. These URLs cannot be YouTube URLs. The first listed video that's compatible with the student's computer will play.": "\u0641\u062e \u0632\u062b \u0633\u0639\u0642\u062b \u0634\u0645\u0645 \u0633\u0641\u0639\u064a\u062b\u0631\u0641\u0633 \u0630\u0634\u0631 \u0634\u0630\u0630\u062b\u0633\u0633 \u0641\u0627\u062b \u062f\u0647\u064a\u062b\u062e, \u0635\u062b \u0642\u062b\u0630\u062e\u0648\u0648\u062b\u0631\u064a \u062d\u0642\u062e\u062f\u0647\u064a\u0647\u0631\u0644 \u0632\u062e\u0641\u0627 \u0634\u0631 .\u0648\u062d4 \u0634\u0631\u064a \u0634 .\u0635\u062b\u0632\u0648 \u062f\u062b\u0642\u0633\u0647\u062e\u0631 \u062e\u0628 \u063a\u062e\u0639\u0642 \u062f\u0647\u064a\u062b\u062e. \u0630\u0645\u0647\u0630\u0646 \u0632\u062b\u0645\u062e\u0635 \u0641\u062e \u0634\u064a\u064a \u0634 \u0639\u0642\u0645 \u0628\u062e\u0642 \u0634\u0631\u062e\u0641\u0627\u062b\u0642 \u062f\u062b\u0642\u0633\u0647\u062e\u0631. \u0641\u0627\u062b\u0633\u062b \u0639\u0642\u0645\u0633 \u0630\u0634\u0631\u0631\u062e\u0641 \u0632\u062b \u063a\u062e\u0639\u0641\u0639\u0632\u062b \u0639\u0642\u0645\u0633. \u0641\u0627\u062b \u0628\u0647\u0642\u0633\u0641 \u0645\u0647\u0633\u0641\u062b\u064a \u062f\u0647\u064a\u062b\u062e \u0641\u0627\u0634\u0641'\u0633 \u0630\u062e\u0648\u062d\u0634\u0641\u0647\u0632\u0645\u062b \u0635\u0647\u0641\u0627 \u0641\u0627\u062b \u0633\u0641\u0639\u064a\u062b\u0631\u0641'\u0633 \u0630\u062e\u0648\u062d\u0639\u0641\u062b\u0642 \u0635\u0647\u0645\u0645 \u062d\u0645\u0634\u063a.", - "To complete the {program} XSeries and earn an XSeries Certificate you must successfully earn a Verified Certificate in all courses shown below.": "\u0641\u062e \u0630\u062e\u0648\u062d\u0645\u062b\u0641\u062b \u0641\u0627\u062b {program} \u0637\u0633\u062b\u0642\u0647\u062b\u0633 \u0634\u0631\u064a \u062b\u0634\u0642\u0631 \u0634\u0631 \u0637\u0633\u062b\u0642\u0647\u062b\u0633 \u0630\u062b\u0642\u0641\u0647\u0628\u0647\u0630\u0634\u0641\u062b \u063a\u062e\u0639 \u0648\u0639\u0633\u0641 \u0633\u0639\u0630\u0630\u062b\u0633\u0633\u0628\u0639\u0645\u0645\u063a \u062b\u0634\u0642\u0631 \u0634 \u062f\u062b\u0642\u0647\u0628\u0647\u062b\u064a \u0630\u062b\u0642\u0641\u0647\u0628\u0647\u0630\u0634\u0641\u062b \u0647\u0631 \u0634\u0645\u0645 \u0630\u062e\u0639\u0642\u0633\u062b\u0633 \u0633\u0627\u062e\u0635\u0631 \u0632\u062b\u0645\u062e\u0635.", "To finalize course credit, %(display_name)s requires %(platform_name)s learners to submit a credit request.": "\u0641\u062e \u0628\u0647\u0631\u0634\u0645\u0647\u0638\u062b \u0630\u062e\u0639\u0642\u0633\u062b \u0630\u0642\u062b\u064a\u0647\u0641, %(display_name)s \u0642\u062b\u0636\u0639\u0647\u0642\u062b\u0633 %(platform_name)s \u0645\u062b\u0634\u0642\u0631\u062b\u0642\u0633 \u0641\u062e \u0633\u0639\u0632\u0648\u0647\u0641 \u0634 \u0630\u0642\u062b\u064a\u0647\u0641 \u0642\u062b\u0636\u0639\u062b\u0633\u0641.", "To invalidate a certificate for a particular learner, add the username or email address below.": "\u0641\u062e \u0647\u0631\u062f\u0634\u0645\u0647\u064a\u0634\u0641\u062b \u0634 \u0630\u062b\u0642\u0641\u0647\u0628\u0647\u0630\u0634\u0641\u062b \u0628\u062e\u0642 \u0634 \u062d\u0634\u0642\u0641\u0647\u0630\u0639\u0645\u0634\u0642 \u0645\u062b\u0634\u0642\u0631\u062b\u0642, \u0634\u064a\u064a \u0641\u0627\u062b \u0639\u0633\u062b\u0642\u0631\u0634\u0648\u062b \u062e\u0642 \u062b\u0648\u0634\u0647\u0645 \u0634\u064a\u064a\u0642\u062b\u0633\u0633 \u0632\u062b\u0645\u062e\u0635.", "To receive a certificate, you must also verify your identity before %(date)s.": "\u0641\u062e \u0642\u062b\u0630\u062b\u0647\u062f\u062b \u0634 \u0630\u062b\u0642\u0641\u0647\u0628\u0647\u0630\u0634\u0641\u062b, \u063a\u062e\u0639 \u0648\u0639\u0633\u0641 \u0634\u0645\u0633\u062e \u062f\u062b\u0642\u0647\u0628\u063a \u063a\u062e\u0639\u0642 \u0647\u064a\u062b\u0631\u0641\u0647\u0641\u063a \u0632\u062b\u0628\u062e\u0642\u062b %(date)s.", @@ -1625,6 +1636,7 @@ "Video ID": "\u062f\u0647\u064a\u062b\u062e \u0647\u064a", "Video ended": "\u062f\u0647\u064a\u062b\u062e \u062b\u0631\u064a\u062b\u064a", "Video position": "\u062f\u0647\u064a\u062b\u062e \u062d\u062e\u0633\u0647\u0641\u0647\u062e\u0631", + "Video speed: ": "\u062f\u0647\u064a\u062b\u062e \u0633\u062d\u062b\u062b\u064a: ", "Video transcript": "\u062f\u0647\u064a\u062b\u062e \u0641\u0642\u0634\u0631\u0633\u0630\u0642\u0647\u062d\u0641", "VideoPlayer: Element corresponding to the given selector was not found.": "\u062f\u0647\u064a\u062b\u062e\u062d\u0645\u0634\u063a\u062b\u0642: \u062b\u0645\u062b\u0648\u062b\u0631\u0641 \u0630\u062e\u0642\u0642\u062b\u0633\u062d\u062e\u0631\u064a\u0647\u0631\u0644 \u0641\u062e \u0641\u0627\u062b \u0644\u0647\u062f\u062b\u0631 \u0633\u062b\u0645\u062b\u0630\u0641\u062e\u0642 \u0635\u0634\u0633 \u0631\u062e\u0641 \u0628\u062e\u0639\u0631\u064a.", "View": "\u062f\u0647\u062b\u0635", @@ -1707,6 +1719,7 @@ "You are a member of this team.": "\u063a\u062e\u0639 \u0634\u0642\u062b \u0634 \u0648\u062b\u0648\u0632\u062b\u0642 \u062e\u0628 \u0641\u0627\u0647\u0633 \u0641\u062b\u0634\u0648.", "You are currently sharing a limited profile.": "\u063a\u062e\u0639 \u0634\u0642\u062b \u0630\u0639\u0642\u0642\u062b\u0631\u0641\u0645\u063a \u0633\u0627\u0634\u0642\u0647\u0631\u0644 \u0634 \u0645\u0647\u0648\u0647\u0641\u062b\u064a \u062d\u0642\u062e\u0628\u0647\u0645\u062b.", "You are enrolling in: {courseName}": "\u063a\u062e\u0639 \u0634\u0642\u062b \u062b\u0631\u0642\u062e\u0645\u0645\u0647\u0631\u0644 \u0647\u0631: {courseName}", + "You are here": "\u063a\u062e\u0639 \u0634\u0642\u062b \u0627\u062b\u0642\u062b", "You are not currently a member of any team.": "\u063a\u062e\u0639 \u0634\u0642\u062b \u0631\u062e\u0641 \u0630\u0639\u0642\u0642\u062b\u0631\u0641\u0645\u063a \u0634 \u0648\u062b\u0648\u0632\u062b\u0642 \u062e\u0628 \u0634\u0631\u063a \u0641\u062b\u0634\u0648.", "You are not enrolled in any XSeries Programs yet.": "\u063a\u062e\u0639 \u0634\u0642\u062b \u0631\u062e\u0641 \u062b\u0631\u0642\u062e\u0645\u0645\u062b\u064a \u0647\u0631 \u0634\u0631\u063a \u0637\u0633\u062b\u0642\u0647\u062b\u0633 \u062d\u0642\u062e\u0644\u0642\u0634\u0648\u0633 \u063a\u062b\u0641.", "You are now enrolled as a verified student for:": "\u063a\u062e\u0639 \u0634\u0642\u062b \u0631\u062e\u0635 \u062b\u0631\u0642\u062e\u0645\u0645\u062b\u064a \u0634\u0633 \u0634 \u062f\u062b\u0642\u0647\u0628\u0647\u062b\u064a \u0633\u0641\u0639\u064a\u062b\u0631\u0641 \u0628\u062e\u0642:", @@ -1865,7 +1878,6 @@ "remove": "\u0642\u062b\u0648\u062e\u062f\u062b", "remove all": "\u0642\u062b\u0648\u062e\u062f\u062b \u0634\u0645\u0645", "section": "\u0633\u062b\u0630\u0641\u0647\u062e\u0631", - "section.subtitle": "\u0633\u062b\u0630\u0641\u0647\u062e\u0631.\u0633\u0639\u0632\u0641\u0647\u0641\u0645\u062b", "section.title": "\u0633\u062b\u0630\u0641\u0647\u062e\u0631.\u0641\u0647\u0641\u0645\u062b", "send an email message to {email}": "\u0633\u062b\u0631\u064a \u0634\u0631 \u062b\u0648\u0634\u0647\u0645 \u0648\u062b\u0633\u0633\u0634\u0644\u062b \u0641\u062e {email}", "status": "\u0633\u0641\u0634\u0641\u0639\u0633", @@ -1886,7 +1898,6 @@ "with %(release_date_from)s": "\u0635\u0647\u0641\u0627 %(release_date_from)s", "with %(section_or_subsection)s": "\u0635\u0647\u0641\u0627 %(section_or_subsection)s", "{browse_span_start}Browse teams in other topics{span_end} or {search_span_start}search teams{span_end} in this topic. If you still can't find a team to join, {create_span_start}create a new team in this topic{span_end}.": "{browse_span_start}\u0632\u0642\u062e\u0635\u0633\u062b \u0641\u062b\u0634\u0648\u0633 \u0647\u0631 \u062e\u0641\u0627\u062b\u0642 \u0641\u062e\u062d\u0647\u0630\u0633{span_end} \u062e\u0642 {search_span_start}\u0633\u062b\u0634\u0642\u0630\u0627 \u0641\u062b\u0634\u0648\u0633{span_end} \u0647\u0631 \u0641\u0627\u0647\u0633 \u0641\u062e\u062d\u0647\u0630. \u0647\u0628 \u063a\u062e\u0639 \u0633\u0641\u0647\u0645\u0645 \u0630\u0634\u0631'\u0641 \u0628\u0647\u0631\u064a \u0634 \u0641\u062b\u0634\u0648 \u0641\u062e \u062a\u062e\u0647\u0631, {create_span_start}\u0630\u0642\u062b\u0634\u0641\u062b \u0634 \u0631\u062b\u0635 \u0641\u062b\u0634\u0648 \u0647\u0631 \u0641\u0627\u0647\u0633 \u0641\u062e\u062d\u0647\u0630{span_end}.", - "{category}\\'s program": "{category}\\'\u0633 \u062d\u0642\u062e\u0644\u0642\u0634\u0648", "{email} is already on the {container} team. Recheck the email address if you want to add a new member.": "{email} \u0647\u0633 \u0634\u0645\u0642\u062b\u0634\u064a\u063a \u062e\u0631 \u0641\u0627\u062b {container} \u0641\u062b\u0634\u0648. \u0642\u062b\u0630\u0627\u062b\u0630\u0646 \u0641\u0627\u062b \u062b\u0648\u0634\u0647\u0645 \u0634\u064a\u064a\u0642\u062b\u0633\u0633 \u0647\u0628 \u063a\u062e\u0639 \u0635\u0634\u0631\u0641 \u0641\u062e \u0634\u064a\u064a \u0634 \u0631\u062b\u0635 \u0648\u062b\u0648\u0632\u062b\u0642.", "{hours}:{minutes} (current UTC time)": "{hours}:{minutes} (\u0630\u0639\u0642\u0642\u062b\u0631\u0641 \u0639\u0641\u0630 \u0641\u0647\u0648\u062b)", "{numMoved} student was removed from {oldCohort}": [ diff --git a/cms/static/js/i18n/ru/djangojs.js b/cms/static/js/i18n/ru/djangojs.js index 81952c027c..2fd30c31db 100644 --- a/cms/static/js/i18n/ru/djangojs.js +++ b/cms/static/js/i18n/ru/djangojs.js @@ -192,7 +192,6 @@ "Account Settings page.": "\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0443\u0447\u0451\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438", "Action": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435", "Actions": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f", - "Activate": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c", "Activate Your Account": "\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0439\u0442\u0435 \u0421\u0432\u043e\u044e \u0423\u0447\u0451\u0442\u043d\u0443\u044e \u0417\u0430\u043f\u0438\u0441\u044c", "Active Threads": "\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0442\u0435\u043c\u044b", "Active Uploads": "\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438", @@ -509,7 +508,6 @@ "Date Added": "\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f", "Date added": "\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f", "Date posted": "\u0414\u0430\u0442\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438", - "Deactivate": "\u0414\u0435\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c", "Decrease indent": "\u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043e\u0442\u0441\u0442\u0443\u043f", "Default": "\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e", "Default Timed Transcript": "\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e", diff --git a/cms/static/js/i18n/zh-cn/djangojs.js b/cms/static/js/i18n/zh-cn/djangojs.js index 025d92b0e4..9b10ea752d 100644 --- a/cms/static/js/i18n/zh-cn/djangojs.js +++ b/cms/static/js/i18n/zh-cn/djangojs.js @@ -83,8 +83,8 @@ "\uff08\u5305\u62ec %(student_count)s \u4e2a\u5b66\u751f\uff09" ], "A driver's license, passport, or government-issued ID with your name and photo.": "\u9a7e\u7167\u3001\u62a4\u7167\u6216\u8005\u7531\u653f\u5e9c\u7b7e\u53d1\u7684\u5e26\u6709\u4f60\u59d3\u540d\u548c\u7167\u7247\u7684\u8eab\u4efd\u8bc1\u4ef6\u3002", - "A driver's license, passport, or other government-issued ID with your name and photo": "\u9a7e\u7167\u3001\u62a4\u7167\u6216\u8005\u5176\u4ed6\u7531\u653f\u5e9c\u7b7e\u53d1\u7684\u5e26\u6709\u4f60\u59d3\u540d\u548c\u7167\u7247\u7684\u8eab\u4efd\u8bc1\u4ef6", - "A list of courses you have just enrolled in as a verified student": "\u4f60\u4ee5\u5df2\u8ba4\u8bc1\u5b66\u751f\u7684\u8eab\u4efd\u9009\u4fee\u7684\u8bfe\u7a0b\u5217\u8868", + "A driver's license, passport, or other government-issued ID with your name and photo": "\u9a7e\u7167\u3001\u62a4\u7167\u6216\u8005\u5176\u4ed6\u7531\u653f\u5e9c\u7b7e\u53d1\u7684\u5e26\u6709\u60a8\u59d3\u540d\u548c\u7167\u7247\u7684\u8eab\u4efd\u8bc1\u4ef6", + "A list of courses you have just enrolled in as a verified student": "\u4f60\u4ee5\u8ba4\u8bc1\u5b66\u751f\u7684\u8eab\u4efd\u9009\u4fee\u7684\u8bfe\u7a0b\u5217\u8868", "A valid email address is required": "\u9700\u8981\u4e00\u4e2a\u6709\u6548\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740", "Activate Your Account": "\u6fc0\u6d3b\u4f60\u7684\u8d26\u6237", "Add Cohort": "\u6dfb\u52a0\u7fa4\u7ec4", @@ -110,9 +110,9 @@ "Already a course team member": "\u5df2\u7ecf\u662f\u8bfe\u7a0b\u56e2\u961f\u6210\u5458", "Already a library team member": "\u5df2\u7ecf\u662f\u77e5\u8bc6\u5e93\u56e2\u961f\u6210\u5458", "Already a member": "\u5df2\u7ecf\u662f\u6210\u5458\u4e86", - "Already have an account?": "\u5df2\u7ecf\u6709\u8d26\u6237\u4e86\uff1f", + "Already have an account?": "\u5df2\u6709\u8d26\u6237\uff1f", "Alternative source": "\u5907\u7528\u6e90", - "Always cohort content-specific discussion topics": "\u603b\u662f\u7fa4\u7ec4\u5316\u7279\u5b9a\u4e8e\u5185\u5bb9\u7684\u8ba8\u8bba\u4e3b\u9898", + "Always cohort content-specific discussion topics": "\u603b\u662f\u6839\u636e\u7279\u5b9a\u5185\u5bb9\u7684\u8ba8\u8bba\u8bdd\u9898\u5206\u7ec4", "Amount": "\u91d1\u989d", "An error has occurred. Make sure that you are connected to the Internet, and then try refreshing the page.": "\u51fa\u73b0\u4e86\u4e00\u4e2a\u9519\u8bef\u3002\u8bf7\u786e\u4fdd\u4f60\u5df2\u8054\u7f51\uff0c\u7136\u540e\u5237\u65b0\u9875\u9762\u3002", "An error has occurred. Please try again later.": "\u53d1\u751f\u4e86\u4e00\u4e2a\u672a\u77e5\u9519\u8bef\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5\u3002", @@ -139,21 +139,21 @@ "Are you sure you want to revert to the last published version of the unit? You cannot undo this action.": "\u60a8\u786e\u5b9a\u8981\u6062\u590d\u5230\u8be5\u5355\u5143\u7684\u4e0a\u6b21\u53d1\u5e03\u7248\u672c\uff1f\u60a8\u65e0\u6cd5\u64a4\u6d88\u6b64\u64cd\u4f5c\u3002", "Are you sure you wish to delete this item. It cannot be reversed!\n\nAlso any content that links/refers to this item will no longer work (e.g. broken images and/or links)": "\u5220\u9664\u7684\u9879\u76ee\u4e0d\u80fd\u6062\u590d\uff01\u60a8\u786e\u5b9a\u8981\u5220\u9664\u8fd9\u4e2a\u9879\u76ee\u5417?\n\n\n\u4e0e\u8fd9\u4e2a\u9879\u76ee\u76f8\u5173\u7684\u4e00\u5207\u4fe1\u606f\uff08\u5982\u76f8\u5e94\u7684\u56fe\u7247\u548c\u94fe\u63a5\uff09\u90fd\u4f1a\u4e22\u5931\u3002", "Are you sure?": "\u60a8\u786e\u5b9a\u5417\uff1f", - "As part of the verification process, you take a photo of both your face and a government-issued photo ID. Our authorization service confirms your identity by comparing the photo you take with the photo on your ID.": "\u4f5c\u4e3a\u8ba4\u8bc1\u8fc7\u7a0b\u4e2d\u4e00\u90e8\u5206\uff0c\u4f60\u9700\u8981\u62cd\u6444\u4e24\u5f20\u7167\u7247\uff1a\u4e00\u5f20\u4f60\u7684\u9762\u90e8\u7167\u7247\uff0c\u4ee5\u53ca\u4e00\u5f20\u8eab\u4efd\u8bc1\u4ef6\u7684\u7167\u7247\uff08\u8be5\u8bc1\u4ef6\u987b\u7531\u653f\u5e9c\u7b7e\u53d1\u4e14\u6709\u4f60\u7684\u7167\u7247\uff09\u3002\u6211\u4eec\u7684\u6388\u6743\u670d\u52a1\u5c06\u901a\u8fc7\u5bf9\u6bd4\u4f60\u62cd\u6444\u7684\u7167\u7247\u548c\u4f60\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u7167\u7247\u6765\u786e\u8ba4\u4f60\u7684\u8eab\u4efd\u3002", + "As part of the verification process, you take a photo of both your face and a government-issued photo ID. Our authorization service confirms your identity by comparing the photo you take with the photo on your ID.": "\u4f5c\u4e3a\u8ba4\u8bc1\u8fc7\u7a0b\u4e2d\u4e00\u90e8\u5206\uff0c\u60a8\u9700\u8981\u62cd\u6444\u4e24\u5f20\u7167\u7247\uff1a\u60a8\u7684\u9762\u90e8\u4ee5\u53ca\u60a8\u7684\u8eab\u4efd\u8bc1\u4ef6\uff08\u8be5\u8bc1\u4ef6\u987b\u7531\u653f\u5e9c\u7b7e\u53d1\u4e14\u6709\u60a8\u7684\u7167\u7247\uff09\u3002\u6211\u4eec\u7684\u6388\u6743\u670d\u52a1\u90e8\u5c06\u901a\u8fc7\u5bf9\u6bd4\u60a8\u7684\u9762\u90e8\u7167\u7247\u548c\u60a8\u7684\u8bc1\u4ef6\u4e0a\u7684\u7167\u7247\u6765\u786e\u8ba4\u60a8\u7684\u8eab\u4efd\u3002", "Assign students to cohorts by uploading a CSV file": "\u901a\u8fc7\u4e0a\u4f20\u4e00\u4e2aCSV\u6587\u4ef6\u6765\u5c06\u5b66\u751f\u4eec\u5206\u914d\u5230\u7fa4\u7ec4\u4e2d\u3002", "Assign students to cohorts by uploading a CSV file.": "\u4e0a\u4f20\u4e00\u4e2a CSV \u6587\u4ef6\u4ee5\u5c06\u5b66\u751f\u5206\u914d\u5230\u7fa4\u7ec4\u4e2d\u3002", - "Associated Content Group": "\u5df2\u5173\u8054\u7684\u5185\u5bb9\u7ec4", + "Associated Content Group": "\u5df2\u52a0\u5165\u7684\u5185\u5bb9\u7ec4", "Author": "\u4f5c\u8005", "Automatic": "\u81ea\u52a8", "Average": "\u5e73\u5747", "Background color": "\u80cc\u666f\u8272", - "Be sure your entire face is inside the frame": "\u8bf7\u786e\u4fdd\u4f60\u7684\u6574\u5f20\u8138\u90fd\u5728\u65b9\u6846\u4ee5\u5185", + "Be sure your entire face is inside the frame": "\u8bf7\u786e\u4fdd\u60a8\u7684\u6574\u5f20\u8138\u90fd\u5728\u6846\u5185", "Before proceeding, please confirm that your details match": "\u5728\u8fdb\u884c\u4e0b\u4e00\u6b65\u4e4b\u524d\uff0c\u8bf7\u786e\u8ba4\u4f60\u63d0\u4f9b\u7684\u4fe1\u606f\u4e4b\u95f4\u76f8\u7b26", "Billed to": "\u8d26\u5355\u5bc4\u7ed9", "Blockquote": "\u5f15\u7528", "Blockquote (Ctrl+Q)": "\u5f15\u7528(Ctrl+Q)", "Blocks": "\u5757", - "Body": "Body \u6807\u7b7e", + "Body": "\u4e3b\u4f53", "Bold": "\u7c97\u4f53", "Bold (Ctrl+B)": "\u7c97\u4f53(Ctrl+B)", "Border": "\u8fb9\u6846", @@ -161,7 +161,7 @@ "Bottom": "\u5e95\u7aef", "Bullet list": "\u9879\u76ee\u7b26\u53f7\u5217\u8868", "Bulleted List (Ctrl+U)": "\u7b26\u53f7\u5217\u8868(Ctrl+U)", - "Can we match the photo you took with the one on your ID?": "\u6211\u4eec\u80fd\u5426\u5c06\u4f60\u62cd\u7684\u7167\u7247\u4e0e\u4f60\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u7167\u7247\u8fdb\u884c\u6bd4\u5bf9\uff1f", + "Can we match the photo you took with the one on your ID?": "\u6211\u4eec\u80fd\u5426\u5c06\u60a8\u62cd\u7684\u7167\u7247\u4e0e\u60a8\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u7167\u7247\u8fdb\u884c\u6bd4\u5bf9\uff1f", "Cancel": "\u53d6\u6d88", "Caption": "\u6807\u9898", "Cell": "\u5355\u5143\u683c", @@ -171,7 +171,7 @@ "Cell type": "\u5355\u5143\u683c\u7c7b\u578b", "Center": "\u5c45\u4e2d\u5bf9\u9f50", "Change Manually": "\u624b\u52a8\u66f4\u6539", - "Change My Email Address": "\u66f4\u6539\u6211\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740", + "Change My Email Address": "\u66f4\u6539\u6211\u7684\u7535\u5b50\u90ae\u4ef6", "Change the settings for %(display_name)s": "\u4fee\u6539%(display_name)s\u7684\u8bbe\u7f6e", "Check Your Email": "\u68c0\u67e5\u4f60\u7684\u7535\u5b50\u90ae\u4ef6", "Check the box to remove %(count)s flag.": [ @@ -200,8 +200,8 @@ "Code block": "\u4ee3\u7801\u5757", "Cohort Assignment Method": "\u5206\u914d\u7fa4\u7ec4\u7684\u65b9\u6cd5", "Cohort Name": "\u7fa4\u7ec4\u540d", - "Cohort selected content-specific discussion topics": "\u7fa4\u7ec4\u5316\u6240\u9009\u7684\u7279\u5b9a\u4e8e\u5185\u5bb9\u7684\u8ba8\u8bba\u4e3b\u9898", - "Cohorted": "\u5df2\u7fa4\u7ec4\u5316", + "Cohort selected content-specific discussion topics": "\u6839\u636e\u9009\u5b9a\u7684\u7279\u5b9a\u5185\u5bb9\u7684\u8ba8\u8bba\u8bdd\u9898\u5206\u7ec4", + "Cohorted": "\u5df2\u5206\u7ec4", "Cohorts Disabled": "\u7fa4\u7ec4\u5df2\u7981\u7528", "Cohorts Enabled": "\u7fa4\u7ec4\u5df2\u542f\u7528", "Collapse Instructions": "\u6298\u53e0\u8bf4\u660e", @@ -213,9 +213,9 @@ "Commentary": "\u8bc4\u6ce8", "Component": "\u7ec4\u4ef6", "Confirm": "\u786e\u8ba4", - "Congratulations! You are now verified on %(platformName)s!": "\u606d\u559c\uff01\u4f60\u5df2\u7ecf\u5728%(platformName)s\u4e0a\u8ba4\u8bc1\u6210\u529f\uff01", + "Congratulations! You are now verified on %(platformName)s!": "\u606d\u559c\uff01\u60a8\u5728%(platformName)s\u4e0a\u8ba4\u8bc1\u6210\u529f\uff01", "Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4", - "Content-Specific Discussion Topics": "\u7279\u5b9a\u4e8e\u5185\u5bb9\u7684\u8ba8\u8bba\u4e3b\u9898", + "Content-Specific Discussion Topics": "\u7279\u5b9a\u5185\u5bb9\u7684\u8ba8\u8bba\u8bdd\u9898", "Copy": "\u590d\u5236", "Copy Email To Editor": "\u590d\u5236\u90ae\u4ef6\u81f3\u7f16\u8f91\u5668", "Copy row": "\u590d\u5236\u884c", @@ -229,13 +229,13 @@ "Country": "\u56fd\u5bb6\uff0f\u5730\u533a", "Course": "\u8bfe\u7a0b", "Course Index": "\u8bfe\u7a0b\u7d22\u5f15", - "Course-Wide Discussion Topics": "\u5168\u8bfe\u7a0b\u8303\u56f4\u5185\u7684\u8ba8\u8bba\u4e3b\u9898", + "Course-Wide Discussion Topics": "\u5168\u8bfe\u7a0b\u8303\u56f4\u5185\u7684\u8ba8\u8bba\u8bdd\u9898", "Create Re-run": "\u521b\u5efa\u91cd\u542f", "Create a content group": "\u521b\u5efa\u4e00\u4e2a\u5185\u5bb9\u7ec4", "Create a new account": "\u521b\u5efa\u65b0\u8d26\u6237", "Create an account": "\u521b\u5efa\u8d26\u6237", "Create an account using": "\u4f7f\u7528\u4ee5\u4e0b\u65b9\u5f0f\u521b\u5efa\u8d26\u6237", - "Create your account": "\u521b\u5efa\u4f60\u7684\u8d26\u6237", + "Create your account": "\u521b\u5efa\u60a8\u7684\u8d26\u6237", "Creating missing groups": "\u6b63\u5728\u521b\u5efa\u7f3a\u5931\u7684\u7ec4\u3002", "Crossed out items have been refunded.": "\u5212\u6389\u7684\u9879\u76ee\u5df2\u9000\u6b3e\u3002", "Current conversation": "\u5f53\u524d\u5bf9\u8bdd", @@ -280,8 +280,8 @@ "Does the name on your ID match your account name: %(fullName)s?": "\u4f60\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u59d3\u540d\u548c\u4f60\u5728\u8d26\u6237\u4e2d\u586b\u5199\u7684\u59d3\u540d\u201c%(fullName)s\u201d\u76f8\u7b26\u5417\uff1f", "Does the photo of you match your ID photo?": "\u8fd9\u5f20\u7167\u7247\u548c\u4f60\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u7167\u7247\u76f8\u5339\u914d\u5417\uff1f", "Does the photo of you show your whole face?": "\u8fd9\u5f20\u7167\u7247\u4e2d\u6709\u4f60\u7684\u6574\u5f20\u8138\u5417\uff1f", - "Don't see your picture? Make sure to allow your browser to use your camera when it asks for permission.": "\u6ca1\u6709\u770b\u5230\u4f60\u81ea\u5df1\uff1f\u8bf7\u786e\u8ba4\u5f53\u6d4f\u89c8\u5668\u8bf7\u6c42\u4f7f\u7528\u6444\u50cf\u5934\u6743\u9650\u7684\u65f6\u5019\u4f60\u5141\u8bb8\u4e86\u8be5\u8bf7\u6c42\u3002", - "Donate": "\u6350\u52a9", + "Don't see your picture? Make sure to allow your browser to use your camera when it asks for permission.": "\u6ca1\u6709\u770b\u5230\u4f60\u81ea\u5df1\uff1f\u8bf7\u786e\u8ba4\u5f53\u6d4f\u89c8\u5668\u8bf7\u6c42\u4f7f\u7528\u6444\u50cf\u5934\u6743\u9650\u7684\u65f6\u5019\u4f60\u9009\u62e9\u4e86\u5141\u8bb8\u3002", + "Donate": "\u6350\u732e", "Double-check that your webcam is connected and working to continue.": "\u518d\u6b21\u786e\u8ba4\u4f60\u7684\u6444\u50cf\u5934\u5df2\u7ecf\u8fde\u63a5\u5e76\u4e14\u6b63\u5e38\u5de5\u4f5c\u4ee5\u7ee7\u7eed\u3002", "Drop target image": "\u62d6\u653e\u7684\u76ee\u6807\u56fe\u50cf", "Due Date": "\u622a\u6b62\u65e5\u671f", @@ -300,10 +300,10 @@ "Enable Cohorts": "\u542f\u7528\u7fa4\u7ec4", "Encoding": "\u7f16\u7801", "End": "\u7ed3\u675f", - "Ensure that you can see your photo and read your name": "\u8bf7\u786e\u4fdd\u4f60\u7684\u7167\u7247\u548c\u540d\u5b57\u6e05\u6670\u53ef\u89c1", + "Ensure that you can see your photo and read your name": "\u8bf7\u786e\u4fdd\u60a8\u7684\u7167\u7247\u548c\u540d\u5b57\u6e05\u6670\u53ef\u89c1", "Enter a student's username or email address.": "\u8f93\u5165\u5b66\u751f\u7684\u7528\u6237\u540d\u6216\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u3002", "Enter a username or email.": "\u8f93\u5165\u7528\u6237\u540d\u6216\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u3002", - "Enter email addresses and/or usernames, separated by new lines or commas, for the students you want to add. *": "\u8bf7\u8f93\u5165\u8981\u6dfb\u52a0\u7684\u5b66\u751f\u7684\u7535\u5b50\u5730\u5740\u548c\uff0f\u6216\u7528\u6237\u540d\uff0c\u6bcf\u884c\u4e00\u4e2a\u6216\u7528\u9017\u53f7\u9694\u5f00\u3002*", + "Enter email addresses and/or usernames, separated by new lines or commas, for the students you want to add. *": "\u8bf7\u8f93\u5165\u8981\u6dfb\u52a0\u7684\u5b66\u751f\u7684\u7535\u5b50\u5730\u5740\u548c\uff0f\u6216\u7528\u6237\u540d\uff0c\u5b66\u751f\u4e4b\u95f4\u7528\u65b0\u884c\u6216\u9017\u53f7\u9694\u5f00\u3002*", "Enter the name of the cohort": "\u8bf7\u8f93\u5165\u7fa4\u7ec4\u7684\u540d\u5b57", "Enter username or email": "\u8f93\u5165\u7528\u6237\u540d\u6216\u8005\u7535\u5b50\u90ae\u4ef6\u5730\u5740", "Entrance exam attempts is being reset for student '{student_id}'.": "\u6b63\u5728\u91cd\u7f6e\u5b66\u751f\u201c{student_id}\u201d\u7684\u5165\u5b66\u8003\u8bd5\u5c1d\u8bd5\u6b21\u6570\u3002", @@ -364,14 +364,14 @@ "Focus grabber": "\u7126\u70b9\u91c7\u96c6\u5668", "Font Family": "\u5b57\u4f53", "Font Sizes": "\u5b57\u53f7", - "Footer": "\u8868\u6ce8", + "Footer": "\u811a\u6ce8", "Forgot password?": "\u5fd8\u8bb0\u5bc6\u7801\uff1f", "Format": "\u683c\u5f0f", "Formats": "\u683c\u5f0f", "Frequently Asked Questions": "\u5e38\u89c1\u95ee\u9898", "Fullscreen": "\u5168\u5c4f", "General": "\u4e00\u822c", - "Go to your Dashboard": "\u524d\u5f80\u4f60\u7684\u8bfe\u7a0b\u9762\u677f", + "Go to your Dashboard": "\u524d\u5f80\u4f60\u7684\u63a7\u5236\u9762\u677f", "Government-Issued Photo ID": "\u653f\u5e9c\u7b7e\u53d1\u7684\u5e26\u6709\u7167\u7247\u7684\u8eab\u4efd\u8bc1\u4ef6", "Grace period must be specified in HH:MM format.": "\u5bbd\u9650\u65f6\u95f4\u5fc5\u987b\u4ee5 HH:MM \u683c\u5f0f\u8bbe\u5b9a\u3002", "Group %s": "%s\u7ec4", @@ -399,7 +399,7 @@ "Heading 5": "\u6807\u9898 5", "Heading 6": "\u6807\u9898 6", "Headings": "\u6807\u9898", - "Height": "\u9ad8", + "Height": "\u9ad8\u5ea6", "Hide Annotations": "\u9690\u85cf\u6279\u6ce8", "Hide Answer": "\u9690\u85cf\u7b54\u6848", "Hide Deprecated Settings": "\u9690\u85cf\u5df2\u8fc7\u65f6\u7684\u8bbe\u7f6e", @@ -413,9 +413,9 @@ "Horizontal line": "\u6c34\u5e73\u7ebf", "Horizontal space": "\u6c34\u5e73\u95f4\u8ddd", "Hyperlink (Ctrl+L)": "\u8d85\u94fe\u63a5(Ctrl+L)", - "ID-Verification is not required for this Professional Education course.": "\u8be5\u4e13\u4e1a\u6559\u80b2\u8bfe\u7a0b\u4e0d\u5f3a\u5236\u8981\u6c42\u9a8c\u8bc1\u8eab\u4efd\u8bc1\u4ef6\u3002", + "ID-Verification is not required for this Professional Education course.": "\u8be5\u4e13\u4e1a\u6559\u80b2\u8bfe\u7a0b\u4e0d\u5f3a\u5236\u8981\u6c42\u8eab\u4efd\u8ba4\u8bc1\u3002", "If the unit was previously published and released to students, any changes you made to the unit when it was hidden will now be visible to students. Do you want to proceed?": "\u5982\u679c\u6b64\u5355\u5143\u5148\u524d\u5df2\u88ab\u53d1\u5e03\u4e14\u5411\u5b66\u751f\u516c\u5f00\uff0c\u4efb\u4f55\u5728\u8be5\u5355\u5143\u5904\u4e8e\u9690\u85cf\u65f6\u7684\u6539\u52a8\u90fd\u5c06\u5bf9\u5b66\u751f\u53ef\u89c1\u3002\u60a8\u8981\u7ee7\u7eed\u5417\uff1f", - "If you don't verify your identity now, you can still explore your course from your dashboard. You will receive periodic reminders from %(platformName)s to verify your identity.": "\u5982\u679c\u4f60\u73b0\u5728\u4e0d\u9a8c\u8bc1\u4f60\u7684\u8eab\u4efd\uff0c\u4f60\u4ecd\u53ef\u4ee5\u901a\u8fc7\u8bfe\u7a0b\u9762\u677f\u6d4f\u89c8\u8bfe\u7a0b\u3002\u4f46\u4f60\u4f1a\u5b9a\u671f\u4ece%(platformName)s\u6536\u5230\u8eab\u4efd\u9a8c\u8bc1\u63d0\u9192\u3002", + "If you don't verify your identity now, you can still explore your course from your dashboard. You will receive periodic reminders from %(platformName)s to verify your identity.": "\u5982\u679c\u4f60\u73b0\u5728\u4e0d\u9a8c\u8bc1\u4f60\u7684\u8eab\u4efd\uff0c\u4f60\u4ecd\u53ef\u4ee5\u901a\u8fc7\u63a7\u5236\u9762\u677f\u6d4f\u89c8\u8bfe\u7a0b\u3002\u4f46\u4f60\u4f1a\u5b9a\u671f\u4ece%(platformName)s\u6536\u5230\u8eab\u4efd\u9a8c\u8bc1\u63d0\u9192\u3002", "If you use the Advanced Editor, this problem will be converted to XML and you will not be able to return to the Simple Editor Interface.\n\nProceed to the Advanced Editor and convert this problem to XML?": "\u5982\u679c\u4f60\u4f7f\u7528\u9ad8\u7ea7\u7f16\u8f91\u5668\uff0c\u8be5\u95ee\u9898\u5c06\u8f6c\u4e3aXML\uff0c\u540c\u65f6\u60a8\u4e5f\u65e0\u6cd5\u518d\u56de\u5230\u7b80\u6613\u7f16\u8f91\u5668\u754c\u9762\u3002\n\n\u8981\u7ee7\u7eed\u4f7f\u7528\u9ad8\u7ea7\u7f16\u8f91\u5668\u5e76\u5c06\u8be5\u95ee\u9898\u8f6c\u4e3aXML\u5417\uff1f", "Ignore": "\u5ffd\u7565", "Ignore all": "\u5168\u90e8\u5ffd\u7565", @@ -427,7 +427,7 @@ "Incorrect url format.": "\u65e0\u6548\u7684 URL \u683c\u5f0f\u3002", "Increase indent": "\u589e\u52a0\u7f29\u8fdb", "Inheriting Student Visibility": "\u7ee7\u627f\u5b66\u751f\u53ef\u89c1\u6027", - "Inline": "\u5185\u8054", + "Inline": "\u5bf9\u9f50", "Insert": "\u63d2\u5165", "Insert Hyperlink": "\u63d2\u5165\u8d85\u94fe\u63a5", "Insert Image (upload file or type URL)": "\u63d2\u5165\u56fe\u7247 (\u4e0a\u4f20\u6587\u4ef6\u6216\u8f93\u5165\u56fe\u7247URL)", @@ -445,7 +445,7 @@ "Insert/edit link": "\u63d2\u5165\uff0f\u7f16\u8f91\u94fe\u63a5", "Insert/edit video": "\u63d2\u5165\uff0f\u7f16\u8f91\u89c6\u9891", "Instructor": "\u4e3b\u8bb2\u6559\u5e08", - "Is your name on your ID readable?": "\u4f60\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u540d\u5b57\u662f\u6e05\u6670\u7684\u5417\uff1f", + "Is your name on your ID readable?": "\u4f60\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u540d\u5b57\u662f\u5426\u6e05\u6670\u53ef\u89c1\uff1f", "Italic": "\u659c\u4f53", "Italic (Ctrl+I)": "\u659c\u4f53(Ctrl+I)", "Justify": "\u4e24\u7aef\u5bf9\u9f50", @@ -466,7 +466,7 @@ "Load more": "\u8f7d\u5165\u66f4\u591a", "Load next %(numResponses)s responses": "\u52a0\u8f7d\u4e0b\u9762\u7684%(numResponses)s\u6761\u56de\u590d", "Load next %(num_items)s result": [ - "\u52a0\u8f7d\u968f\u540e %(num_items)s \u4e2a\u7ed3\u679c" + "\u52a0\u8f7d\u540e %(num_items)s \u4e2a\u7ed3\u679c" ], "Loading": "\u6b63\u5728\u52a0\u8f7d", "Loading content": "\u6b63\u5728\u52a0\u8f7d\u5185\u5bb9", @@ -482,7 +482,7 @@ "Make sure that the full name on your account matches the name on your ID.": "\u8bf7\u786e\u4fdd\u4f60\u5728\u8d26\u6237\u4e2d\u586b\u5199\u7684\u5168\u540d\u548c\u4f60\u8eab\u4efd\u8bc1\u4ef6\u4e2d\u7684\u540d\u5b57\u76f8\u4e00\u81f4\u3002", "Make sure we can verify your identity with the photos and information you have provided.": "\u8bf7\u786e\u4fdd\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4f60\u63d0\u4f9b\u7684\u7167\u7247\u53ca\u4fe1\u606f\u6765\u9a8c\u8bc1\u4f60\u7684\u8eab\u4efd\u3002", "Make sure your ID is well-lit": "\u8bf7\u786e\u4fdd\u4f60\u7684\u8eab\u4efd\u8bc1\u4ef6\u5149\u7ebf\u5145\u8db3", - "Make sure your face is well-lit": "\u8bf7\u786e\u4fdd\u4f60\u7684\u9762\u90e8\u5149\u7ebf\u5145\u8db3", + "Make sure your face is well-lit": "\u8bf7\u786e\u4fdd\u60a8\u7684\u9762\u90e8\u5149\u7ebf\u5145\u8db3", "Making Visible to Students": "\u6b63\u5728\u5bf9\u5b66\u751f\u53ef\u89c1", "Manage Students": "\u7ba1\u7406\u5b66\u751f", "Manual": "\u624b\u52a8", @@ -510,8 +510,8 @@ "No Content Group": "\u6ca1\u6709\u5185\u5bb9\u7ec4", "No Webcam Detected": "\u6ca1\u6709\u68c0\u6d4b\u5230\u6444\u50cf\u5934", "No color": "\u65e0\u989c\u8272", - "No content-specific discussion topics exist.": "\u4e0d\u5b58\u5728\u7279\u5b9a\u4e8e\u5185\u5bb9\u7684\u8ba8\u8bba\u4e3b\u9898\u3002", - "No receipt available": "\u6ca1\u6709\u53ef\u7528\u7684\u6536\u636e\u3002", + "No content-specific discussion topics exist.": "\u65e0\u7279\u5b9a\u5185\u5bb9\u7684\u8ba8\u8bba\u8bdd\u9898", + "No receipt available": "\u6ca1\u6709\u53ef\u63d0\u4f9b\u7684\u6536\u636e\u3002", "No results found for \"%(query_string)s\". Please try searching again.": "\u672a\u627e\u5230\u201c%(query_string)s\u201d\u3002\u8bf7\u91cd\u65b0\u641c\u7d22\u3002", "No results found for %(original_query)s. Showing results for %(suggested_query)s.": "\u672a\u627e\u5230\u4e0e %(original_query)s \u5339\u914d\u7684\u7ed3\u679c\u3002\u663e\u793a\u7684\u662f\u67e5\u627e %(suggested_query)s \u7684\u7ed3\u679c\u3002", "No sources": "\u6ca1\u6709\u6e90", @@ -522,7 +522,7 @@ "Not Graded": "\u5c1a\u672a\u8bc4\u5206", "Not in Use": "\u672a\u4f7f\u7528", "Not selected": "\u672a\u9009\u62e9", - "Note: Students can be in only one cohort. Adding students to this group overrides any previous group assignment.": "\u6ce8\u610f\uff1a\u6bcf\u4e2a\u5b66\u751f\u53ea\u80fd\u52a0\u5165\u4e00\u4e2a\u7fa4\u7ec4\uff0c\u5c06\u5b66\u751f\u52a0\u5165\u8be5\u7ec4\u4f1a\u8986\u76d6\u4e4b\u524d\u5bf9\u8be5\u5b66\u751f\u6240\u6709\u7684\u7fa4\u7ec4\u5206\u914d\u3002", + "Note: Students can be in only one cohort. Adding students to this group overrides any previous group assignment.": "\u6ce8\u610f\uff1a\u6bcf\u4e2a\u5b66\u751f\u53ea\u80fd\u52a0\u5165\u4e00\u4e2a\u7fa4\u7ec4\uff0c\u5c06\u5b66\u751f\u52a0\u5165\u8fd9\u4e2a\u7ec4\u4f1a\u8ba9\u4ed6\u4eec\u81ea\u52a8\u9000\u51fa\u524d\u4e00\u7ec4\u3002", "Notes hidden": "\u6ce8\u91ca\u5df2\u9690\u85cf", "Notes visible": "\u6ce8\u91ca\u53ef\u89c1", "Number Sent": "\u53d1\u9001\u6570\u76ee", @@ -539,10 +539,10 @@ "Order No.": "\u8ba2\u5355\u53f7\uff1a", "Page break": "\u5206\u9875\u7b26", "Pagination": "\u5206\u9875", - "Paragraph": "\u6bb5\u843d\u6837\u5f0f", + "Paragraph": "\u6bb5\u843d", "Password": "\u5bc6\u7801", "Password Reset Email Sent": "\u5bc6\u7801\u91cd\u7f6e\u90ae\u4ef6\u5df2\u53d1\u9001", - "Password assistance": "\u5bc6\u7801\u53d6\u56de\u5e2e\u52a9", + "Password assistance": "\u5bc6\u7801\u5e2e\u52a9", "Password reset email sent. Follow the link in the email to change your password.": "\u5bc6\u7801\u91cd\u7f6e\u90ae\u4ef6\u5df2\u7ecf\u53d1\u9001\u3002\u8bf7\u901a\u8fc7\u70b9\u51fb\u90ae\u4ef6\u4e2d\u7684\u94fe\u63a5\u66f4\u6539\u4f60\u7684\u5bc6\u7801\u3002", "Paste": "\u7c98\u8d34", "Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c", @@ -573,7 +573,7 @@ "Please enter an integer between 0 and 100.": "\u8bf7\u8f93\u5165\u4e00\u4e2a0\u5230100\u4e4b\u95f4\u7684\u6574\u6570\u3002", "Please enter an integer greater than 0.": "\u8bf7\u8f93\u5165\u4e00\u4e2a\u5927\u4e8e0\u7684\u6574\u6570\u3002", "Please enter non-negative integer.": "\u8bf7\u8f93\u5165\u975e\u8d1f\u6574\u6570\u3002", - "Please enter your email address below and we will send you instructions for setting a new password.": "\u8bf7\u5728\u4e0b\u9762\u8f93\u5165\u4f60\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u4ee5\u4fbf\u6211\u4eec\u7ed9\u4f60\u53d1\u9001\u5982\u4f55\u8bbe\u7f6e\u65b0\u5bc6\u7801\u7684\u8bf4\u660e\u3002", + "Please enter your email address below and we will send you instructions for setting a new password.": "\u8bf7\u5728\u4e0b\u9762\u8f93\u5165\u60a8\u7684\u7535\u5b50\u90ae\u4ef6\u4ee5\u4fbf\u6211\u4eec\u7ed9\u60a8\u53d1\u9001\u5982\u4f55\u8bbe\u7f6e\u65b0\u5bc6\u7801\u7684\u8bf4\u660e\u3002", "Please follow the instructions here to upload a file elsewhere and link to it: {maxFileSizeRedirectUrl}": "\u8bf7\u6309\u7167\u8fd9\u91cc\uff08{maxFileSizeRedirectUrl}\uff09\u7684\u8bf4\u660e\u4e0a\u4f20\u6587\u4ef6\u5230\u522b\u5904\u540e\u94fe\u63a5\u5230\u8be5\u6587\u4ef6\u3002", "Please print this page for your records; it serves as your receipt. You will also receive an email with the same information.": "\u8bf7\u6253\u5370\u6b64\u9875\u7559\u4f5c\u7eaa\u5f55\uff0c\u8fd9\u5c31\u662f\u4f60\u7684\u6536\u636e\uff1b\u4f60\u4e5f\u4f1a\u6536\u5230\u4e00\u5c01\u6709\u76f8\u540c\u4fe1\u606f\u7684\u7535\u5b50\u90ae\u4ef6\u3002", "Please provide a description of the link destination.": "\u8bf7\u63d0\u4f9b\u94fe\u63a5\u7684\u63cf\u8ff0\u3002", @@ -597,7 +597,7 @@ "Publish %(display_name)s": "\u53d1\u5e03%(display_name)s", "Publish all unpublished changes for this %(item)s?": "\u8981\u53d1\u5e03\u6b64%(item)s\u4e2d\u6240\u6709\u5c1a\u672a\u53d1\u5e03\u7684\u66f4\u6539\u5417\uff1f", "Publishing": "\u6b63\u5728\u53d1\u5e03", - "Questions raise issues that need answers. Discussions share ideas and start conversations.": "\u201c\u95ee\u9898\u201d\u63d0\u51fa\u9700\u8981\u7b54\u6848\u7684\u8bae\u9898\uff0c\u201c\u8ba8\u8bba\u201d\u5206\u4eab\u60f3\u6cd5\u5e76\u5f00\u59cb\u4f1a\u8bdd\u3002", + "Questions raise issues that need answers. Discussions share ideas and start conversations.": "\u201c\u95ee\u9898\u201d\u63d0\u51fa\u9700\u8981\u7b54\u6848\u7684\u8bae\u9898\uff0c\u201c\u8ba8\u8bba\u201d\u5206\u4eab\u60f3\u6cd5\u5e76\u5f00\u59cb\u4ea4\u6d41\u3002", "Queued": "\u5df2\u6392\u961f", "Recent Activity": "\u8fd1\u671f\u6d3b\u52a8", "Redo": "\u91cd\u505a", @@ -611,7 +611,7 @@ "Reply to Annotation": "\u56de\u590d\u6279\u6ce8", "Report annotation as inappropriate or offensive.": "\u62a5\u544a\u4e0d\u6070\u5f53\u7684\u6216\u5177\u6709\u653b\u51fb\u6027\u7684\u6279\u6ce8\u3002", "Requester": "\u8bf7\u6c42\u8005", - "Required field": "\u5fc5\u586b\u5b57\u6bb5", + "Required field": "\u5fc5\u586b\u9879\u76ee", "Rescore problem '<%= problem_id %>' for all students?": "\u786e\u8ba4\u5bf9\u6240\u6709\u5b66\u751f\u56de\u7b54\u95ee\u9898\u201c<%= problem_id %>\u201d\u91cd\u65b0\u8bc4\u5206\uff1f", "Reset Password": "\u91cd\u8bbe\u5bc6\u7801", "Reset attempts for all students on problem '<%= problem_id %>'?": "\u786e\u8ba4\u91cd\u7f6e\u6240\u6709\u5b66\u751f\u5728\u95ee\u9898\u201c<%= problem_id %>\u201d\u7684\u5c1d\u8bd5\u6b21\u6570\uff1f", @@ -622,7 +622,7 @@ "Return and add email address": "\u8fd4\u56de\u5e76\u6dfb\u52a0\u7535\u5b50\u90ae\u4ef6\u5730\u5740", "Return to Export": "\u8fd4\u56de\u81f3\u5bfc\u51fa\u9875\u9762", "Return to team listing": "\u8fd4\u56de\u56e2\u961f\u5217\u8868", - "Review Your Photos": "\u590d\u6838\u4f60\u7684\u7167\u7247", + "Review Your Photos": "\u68c0\u67e5\u4f60\u7684\u7167\u7247", "Revoke access": "\u53d6\u6d88\u6388\u6743", "Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u4e30\u5bcc\u6587\u672c\u533a\u57df\u3002\u6309 ALT-F9 \u6253\u5f00\u83dc\u5355\uff0c\u6309 ALT-F10 \u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309 ALT-0 \u67e5\u770b\u5e2e\u52a9", "Right": "\u53f3\u5bf9\u9f50", @@ -646,7 +646,7 @@ "Select a cohort": "\u9009\u62e9\u4e00\u4e2a\u7fa4\u7ec4", "Select a cohort to manage": "\u9009\u62e9\u8981\u7ba1\u7406\u7684\u7fa4\u7ec4", "Select all": "\u5168\u9009", - "Select the course-wide discussion topics that you want to divide by cohort.": "\u9009\u62e9\u60a8\u5e0c\u671b\u7531\u7fa4\u7ec4\u5212\u5206\u7684\u5168\u8bfe\u7a0b\u8303\u56f4\u5185\u7684\u8ba8\u8bba\u4e3b\u9898\u3002", + "Select the course-wide discussion topics that you want to divide by cohort.": "\u9009\u62e9\u60a8\u5e0c\u671b\u7531\u7fa4\u7ec4\u5212\u5206\u7684\u5168\u8bfe\u7a0b\u8303\u56f4\u5185\u7684\u8ba8\u8bba\u8bdd\u9898\u3002", "Selected tab": "\u9009\u4e2d\u7684\u6807\u7b7e", "Sent By": "\u53d1\u9001\u4eba", "Sent By:": "\u53d1\u4ef6\u4eba", @@ -675,8 +675,8 @@ "Source": "\u6e90", "Source code": "\u6e90\u4ee3\u7801", "Special character": "\u7279\u6b8a\u5b57\u7b26", - "Specify whether content-specific discussion topics are divided by cohort.": "\u6307\u5b9a\u662f\u5426\u8981\u7531\u7fa4\u7ec4\u5bf9\u7279\u5b9a\u4e8e\u5185\u5bb9\u7684\u8ba8\u8bba\u4e3b\u9898\u8fdb\u884c\u5212\u5206\u3002", - "Specify whether discussion topics are divided by cohort": "\u6307\u5b9a\u662f\u5426\u7531\u7fa4\u7ec4\u5bf9\u8ba8\u8bba\u4e3b\u9898\u8fdb\u884c\u5212\u5206\u3002", + "Specify whether content-specific discussion topics are divided by cohort.": "\u6307\u5b9a\u662f\u5426\u7531\u7fa4\u7ec4\u5212\u5206\u7279\u5b9a\u5185\u5bb9\u7684\u8ba8\u8bba\u8bdd\u9898\u3002", + "Specify whether discussion topics are divided by cohort": "\u6307\u5b9a\u662f\u5426\u6309\u7fa4\u7ec4\u5212\u5206\u8ba8\u8bba\u8bdd\u9898\u3002", "Speed": "\u901f\u5ea6", "Spellcheck": "\u62fc\u5199\u68c0\u67e5", "Split cell": "\u62c6\u5206\u5355\u5143\u683c", @@ -717,7 +717,7 @@ "Tags:": "\u6807\u7b7e\uff1a", "Take Photo": "\u62cd\u7167", "Take Your Photo": "\u7ed9\u81ea\u5df1\u62cd\u7167", - "Take a Photo of Your ID": "\u62cd\u6444\u4e00\u5f20\u4f60\u8eab\u4efd\u8bc1\u4ef6\u7684\u7167\u7247", + "Take a Photo of Your ID": "\u62cd\u6444\u60a8\u7684\u8eab\u4efd\u8bc1\u4ef6", "Take me to the main course page": "\u8df3\u8f6c\u81f3\u8bfe\u7a0b\u4e3b\u9875", "Take me to the main library page": "\u8df3\u8f6c\u81f3\u77e5\u8bc6\u5e93\u4e3b\u9875", "Target": "\u76ee\u6807", @@ -731,7 +731,7 @@ "Text": "\u6587\u672c", "Text color": "\u6587\u672c\u989c\u8272", "Text to display": "\u8981\u663e\u793a\u7684\u6587\u5b57", - "Thank you for submitting your photos. We will review them shortly. You can now sign up for any %(platformName)s course that offers verified certificates. Verification is good for one year. After one year, you must submit photos for verification again.": "\u611f\u8c22\u4f60\u63d0\u4ea4\u7167\u7247\uff0c\u6211\u4eec\u5c06\u4e8e\u7a0d\u540e\u8fdb\u884c\u5ba1\u6838\u3002\u4f60\u73b0\u5728\u5c31\u53ef\u4ee5\u6ce8\u518c%(platformName)s\u4e0a\u4efb\u610f\u63d0\u4f9b\u8ba4\u8bc1\u8bc1\u4e66\u7684\u8bfe\u7a0b\u3002\u8ba4\u8bc1\u53ea\u5728\u4e00\u5e74\u5185\u6709\u6548\uff0c\u4e00\u5e74\u540e\uff0c\u4f60\u5fc5\u987b\u8981\u63d0\u4ea4\u7167\u7247\u91cd\u65b0\u8ba4\u8bc1\u3002", + "Thank you for submitting your photos. We will review them shortly. You can now sign up for any %(platformName)s course that offers verified certificates. Verification is good for one year. After one year, you must submit photos for verification again.": "\u611f\u8c22\u63d0\u4ea4\u60a8\u7684\u7167\u7247\uff0c\u6211\u4eec\u5c06\u4e8e\u7a0d\u540e\u8fdb\u884c\u5ba1\u6838\u3002\u60a8\u73b0\u5728\u5c31\u53ef\u4ee5\u6ce8\u518c%(platformName)s\u4e0a\u4efb\u4e00\u63d0\u4f9b\u8ba4\u8bc1\u8bc1\u4e66\u7684\u8bfe\u7a0b\u3002\u8ba4\u8bc1\u6709\u6548\u671f\u4e3a\u4e00\u5e74\u3002\u4e00\u5e74\u540e\uff0c\u60a8\u5fc5\u987b\u8981\u63d0\u4ea4\u7167\u7247\u91cd\u65b0\u8ba4\u8bc1\u3002", "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u8f93\u5165\u7684URL\u4f3c\u4e4e\u662f\u4e00\u4e2a\u7535\u5b50\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0a\u201cmailto:\u201d\u524d\u7f00\u5417\uff1f", "The URL you entered seems to be an external link. Do you want to add the required http:// prefix?": "\u8f93\u5165\u7684 URL \u4f3c\u4e4e\u662f\u4e00\u4e2a\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0a\u201chttp://\u201d\u524d\u7f00\u5417\uff1f", "The cohort cannot be added": "\u8be5\u7fa4\u7ec4\u4e0d\u80fd\u6dfb\u52a0", @@ -758,7 +758,7 @@ "There has been an error with your export.": "\u5bfc\u51fa\u65f6\u53d1\u751f\u4e86\u9519\u8bef\u3002", "There is no email history for this course.": "\u672c\u8bfe\u7a0b\u5c1a\u65e0\u53d1\u9001\u7535\u5b50\u90ae\u4ef6\u8bb0\u5f55\u3002", "There must be at least one group.": "\u5fc5\u987b\u81f3\u5c11\u6709\u4e00\u4e2a\u7ec4\u3002", - "There must be one cohort to which students can automatically be assigned.": "\u5fc5\u987b\u5b58\u5728\u4e00\u4e2a\u53ef\u4ee5\u5c06\u5b66\u751f\u81ea\u52a8\u5206\u914d\u8fdb\u53bb\u7684\u7fa4\u7ec4\u3002", + "There must be one cohort to which students can automatically be assigned.": "\u5fc5\u987b\u5b58\u5728\u4e00\u4e2a\u5b66\u751f\u53ef\u88ab\u81ea\u52a8\u5206\u914d\u8fdb\u53bb\u7684\u7fa4\u7ec4\u3002", "There was an error changing the user's role": "\u66f4\u6539\u7528\u6237\u89d2\u8272\u8fc7\u7a0b\u4e2d\u51fa\u73b0\u9519\u8bef", "There was an error during the upload process.": "\u5728\u6587\u4ef6\u4e0a\u4f20\u8fc7\u7a0b\u4e2d\u53d1\u751f\u9519\u8bef\u3002", "There was an error obtaining email content history for this course.": "\u5b58\u5728\u80fd\u83b7\u53d6\u8be5\u8bfe\u7a0b\u90ae\u4ef6\u5386\u53f2\u5185\u5bb9\u7684\u9519\u8bef", @@ -818,7 +818,7 @@ "Upload File and Assign Students": "\u4e0a\u4f20\u6587\u4ef6\u5e76\u4e3a\u5b66\u751f\u5206\u7ec4", "Upload New File": "\u4e0a\u4f20\u65b0\u6587\u4ef6", "Upload a new PDF to \u201c<%= name %>\u201d": "\u4e0a\u4f20\u4e00\u4e2a\u65b0\u7684PDF\u6587\u4ef6\u81f3\u201c<%= name %>\u201d", - "Upload an image or capture one with your web or phone camera.": "\u4e0a\u4f20\u7167\u7247\u6216\u901a\u8fc7\u4f7f\u7528\u4f60\u7684\u7f51\u7edc\uff0f\u624b\u673a\u6444\u50cf\u5934\u62cd\u7167\u4e0a\u4f20\u3002", + "Upload an image or capture one with your web or phone camera.": "\u4e0a\u4f20\u7167\u7247\u6216\u901a\u8fc7\u4f7f\u7528\u60a8\u7684\u7f51\u7edc\uff0f\u624b\u673a\u6444\u50cf\u5934\u62cd\u7167\u4e0a\u4f20\u3002", "Upload completed": "\u4e0a\u4f20\u5b8c\u6210", "Upload failed": "\u4e0a\u4f20\u5931\u8d25", "Upload translation": "\u4e0a\u4f20\u8bd1\u6587", @@ -827,9 +827,9 @@ "Upper Alpha": "\u5927\u5199\u5b57\u6bcd", "Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd", "Url": "URL", - "Use the retake photo button if you are not pleased with your photo": "\u5982\u679c\u4f60\u5bf9\u7167\u7247\u4e0d\u6ee1\u610f\uff0c\u8bf7\u4f7f\u7528\u91cd\u62cd\u6309\u94ae\u91cd\u65b0\u62cd\u4e00\u5f20\u7167\u7247", - "Use your webcam to take a photo of your ID. We will match this photo with the photo of your face and the name on your account.": "\u8bf7\u7528\u6444\u50cf\u5934\u62cd\u6444\u4e00\u5f20\u4f60\u8eab\u4efd\u8bc1\u4ef6\u7684\u7167\u7247\uff0c\u6211\u4eec\u5c06\u7528\u8be5\u7167\u7247\u4e0e\u4f60\u7684\u9762\u90e8\u7167\u7247\u53ca\u4f60\u5728\u8d26\u6237\u4e2d\u586b\u5199\u7684\u59d3\u540d\u8fdb\u884c\u5339\u914d\u3002", - "Use your webcam to take a photo of your face. We will match this photo with the photo on your ID.": "\u8bf7\u7528\u6444\u50cf\u5934\u62cd\u6444\u4e00\u5f20\u4f60\u7684\u9762\u90e8\u7167\u7247\uff0c\u6211\u4eec\u5c06\u7528\u8be5\u7167\u7247\u4e0e\u4f60\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u7167\u7247\u8fdb\u884c\u5339\u914d\u3002", + "Use the retake photo button if you are not pleased with your photo": "\u5982\u679c\u60a8\u5bf9\u7167\u7247\u4e0d\u6ee1\u610f\uff0c\u8bf7\u4f7f\u7528\u91cd\u62cd\u6309\u94ae\u91cd\u65b0\u62cd\u4e00\u5f20\u7167\u7247", + "Use your webcam to take a photo of your ID. We will match this photo with the photo of your face and the name on your account.": "\u8bf7\u7528\u6444\u50cf\u5934\u62cd\u6444\u4e00\u5f20\u60a8\u8eab\u4efd\u8bc1\u4ef6\u7684\u7167\u7247\uff0c\u6211\u4eec\u5c06\u67e5\u770b\u8be5\u7167\u7247\u662f\u5426\u4e0e\u60a8\u7684\u9762\u90e8\u7167\u7247\u53ca\u60a8\u5728\u8d26\u6237\u4e2d\u586b\u5199\u7684\u59d3\u540d\u5339\u914d\u3002", + "Use your webcam to take a photo of your face. We will match this photo with the photo on your ID.": "\u8bf7\u7528\u6444\u50cf\u5934\u62cd\u6444\u4e00\u5f20\u60a8\u7684\u9762\u90e8\u7167\u7247\uff0c\u6211\u4eec\u5c06\u5bf9\u6bd4\u8be5\u7167\u7247\u4e0e\u60a8\u8eab\u4efd\u8bc1\u4ef6\u4e0a\u7684\u7167\u7247\u3002", "User": "\u7528\u6237", "Username": "\u7528\u6237\u540d", "Users": "\u7528\u6237", @@ -852,11 +852,11 @@ "View discussion": "\u67e5\u770b\u8ba8\u8bba", "Visual aids": "\u7f51\u683c\u7ebf", "Volume": "\u97f3\u91cf", - "Want to confirm your identity later?": "\u5e0c\u671b\u4ee5\u540e\u518d\u9a8c\u8bc1\u4f60\u7684\u8eab\u4efd\uff1f", + "Want to confirm your identity later?": "\u5e0c\u671b\u7a0d\u540e\u518d\u9a8c\u8bc1\u4f60\u7684\u8eab\u4efd\uff1f", "Warning": "\u8b66\u544a", "Warnings": "\u8b66\u544a", - "We couldn't create your account.": "\u6211\u4eec\u65e0\u6cd5\u521b\u5efa\u4f60\u7684\u8d26\u6237\u3002", - "We couldn't sign you in.": "\u6211\u4eec\u65e0\u6cd5\u8ba9\u60a8\u767b\u5f55\u3002", + "We couldn't create your account.": "\u6211\u4eec\u65e0\u6cd5\u521b\u5efa\u60a8\u7684\u8d26\u6237\u3002", + "We couldn't sign you in.": "\u767b\u5f55\u5931\u8d25\u3002", "We had some trouble closing this thread. Please try again.": "\u5173\u95ed\u8fd9\u4e2a\u5e16\u5b50\u65f6\u51fa\u73b0\u4e86\u4e00\u4e9b\u95ee\u9898\uff0c\u8bf7\u91cd\u8bd5\u3002", "We had some trouble deleting this comment. Please try again.": "\u5728\u5220\u9664\u8fd9\u6761\u8bc4\u8bba\u65f6\u51fa\u9519\uff0c\u8bf7\u518d\u8bd5\u4e00\u904d\u3002", "We had some trouble loading more responses. Please try again.": "\u8f7d\u5165\u56de\u590d\u65f6\u9047\u5230\u9ebb\u70e6\uff0c\u8bf7\u91cd\u8bd5\u3002", @@ -879,14 +879,14 @@ "We had some trouble subscribing you to this thread. Please try again.": "\u8ba2\u9605\u8fd9\u4e2a\u5e16\u5b50\u65f6\u51fa\u73b0\u4e86\u4e00\u4e9b\u95ee\u9898\uff0c\u8bf7\u91cd\u8bd5\u3002", "We had some trouble unpinning this thread. Please try again.": "\u53d6\u6d88\u7f6e\u9876\u8fd9\u4e2a\u5e16\u5b50\u65f6\u51fa\u73b0\u4e86\u4e00\u4e9b\u95ee\u9898\uff0c\u8bf7\u91cd\u8bd5\u3002", "We had some trouble unsubscribing you from this thread. Please try again.": "\u53d6\u6d88\u8ba2\u9605\u8fd9\u4e2a\u5e16\u5b50\u65f6\u51fa\u73b0\u4e86\u4e00\u4e9b\u95ee\u9898\uff0c\u8bf7\u91cd\u8bd5\u3002", - "We just need a little more information before you start learning with %(platformName)s.": "\u4f60\u53ea\u9700\u518d\u591a\u63d0\u4f9b\u4e00\u70b9\u4fe1\u606f\u5c31\u53ef\u4ee5\u5f00\u59cb\u5728%(platformName)s\u5b66\u4e60\u4e86\u3002", + "We just need a little more information before you start learning with %(platformName)s.": "\u60a8\u53ea\u9700\u518d\u591a\u63d0\u4f9b\u4e00\u70b9\u4fe1\u606f\u5c31\u53ef\u4ee5\u5f00\u59cb\u5728%(platformName)s\u5b66\u4e60\u4e86\u3002", "We use the highest levels of security available to encrypt your photo and send it to our authorization service for review. Your photo and information are not saved or visible anywhere on %(platformName)s after the verification process is complete.": "\u6211\u4eec\u4f1a\u91c7\u7528\u6700\u9ad8\u7ea7\u522b\u7684\u5b89\u5168\u6280\u672f\u6765\u52a0\u5bc6\u4f60\u7684\u7167\u7247\u5e76\u53d1\u9001\u5230\u6211\u4eec\u7684\u6388\u6743\u670d\u52a1\u7528\u4e8e\u5ba1\u6838\u76ee\u7684\uff1b\u4e00\u65e6\u5b8c\u6210\u4e86\u8ba4\u8bc1\u8fc7\u7a0b\uff0c%(platformName)s\u4e0d\u4f1a\u7ee7\u7eed\u4fdd\u5b58\u8fd9\u4e9b\u7167\u7247\u548c\u4fe1\u606f\u3002", "We weren't able to send you a password reset email.": "\u5bc6\u7801\u91cd\u7f6e\u90ae\u4ef6\u53d1\u9001\u5931\u8d25\u3002", "We're sorry, there was an error": "\u5f88\u62b1\u6b49\uff0c\u51fa\u73b0\u9519\u8bef", "We've encountered an error. Refresh your browser and then try again.": "\u6211\u4eec\u9047\u5230\u4e86\u4e00\u4e2a\u9519\u8bef\u3002\u8bf7\u5237\u65b0\u4f60\u7684\u6d4f\u89c8\u5668\u5e76\u91cd\u8bd5\u3002", - "We've sent instructions for resetting your password to the email address you provided.": "\u6211\u4eec\u5df2\u7ecf\u5411\u4f60\u63d0\u4f9b\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u53d1\u9001\u4e86\u91cd\u7f6e\u5bc6\u7801\u7684\u8bf4\u660e\u3002", + "We've sent instructions for resetting your password to the email address you provided.": "\u6211\u4eec\u5df2\u7ecf\u5411\u60a8\u63d0\u4f9b\u7684\u7535\u5b50\u90ae\u4ef6\u53d1\u9001\u4e86\u91cd\u7f6e\u5bc6\u7801\u7684\u8bf4\u660e\u3002", "Webcam": "\u6444\u50cf\u5934", - "What does %(platformName)s do with this photo?": "%(platformName)s\u7528\u8fd9\u4e9b\u7167\u7247\u505a\u4ec0\u4e48\uff1f", + "What does %(platformName)s do with this photo?": "%(platformName)s\u7528\u8fd9\u5f20\u7167\u7247\u505a\u4ec0\u4e48\uff1f", "What does this mean?": "\u8fd9\u662f\u4ec0\u4e48\u610f\u601d\uff1f", "Whole words": "\u5168\u5b57\u5339\u914d", "Why does %(platformName)s need my photo?": "\u4e3a\u4ec0\u4e48%(platformName)s\u9700\u8981\u6211\u7684\u7167\u7247\uff1f", @@ -896,10 +896,10 @@ "You are about to send an email titled '<%= subject %>' to ALL (everyone who is enrolled in this course as student, staff, or instructor). Is this OK?": "\u60a8\u5373\u5c06\u5411\u9009\u4fee\u8be5\u8bfe\u7a0b\u7684\u6240\u6709\u4eba(\u9009\u8bfe\u7684\u5b66\u751f\u3001\u6559\u5458\u548c\u4e3b\u8bb2\u6559\u5e08)\u53d1\u9001\u4e00\u5c01\u6807\u9898\u4e3a\u201c<%= subject %>\u201d\u7684\u90ae\u4ef6\uff0c\u786e\u8ba4\u5417\uff1f", "You are about to send an email titled '<%= subject %>' to everyone who is staff or instructor on this course. Is this OK?": "\u60a8\u51c6\u5907\u5411\u8be5\u8bfe\u7a0b\u7684\u6240\u6709\u6559\u5458\u548c\u4e3b\u8bb2\u6559\u5e08\u53d1\u9001\u4e00\u5c01\u6807\u9898\u4e3a\u201c<%= subject %>\u201d\u7684\u90ae\u4ef6\uff0c\u786e\u8ba4\u5417\uff1f", "You are about to send an email titled '<%= subject %>' to yourself. Is this OK?": "\u4f60\u51c6\u5907\u5411\u81ea\u5df1\u53d1\u9001\u4e00\u5c01\u6807\u9898\u4e3a\u201c<%= subject %>\u201d\u7684\u90ae\u4ef6\uff0c\u786e\u8ba4\u5417\uff1f", - "You are now enrolled as a verified student for:": "\u4f60\u73b0\u5728\u6b63\u4ee5\u5df2\u8ba4\u8bc1\u5b66\u751f\u7684\u8eab\u4efd\u9009\u4fee\uff1a", + "You are now enrolled as a verified student for:": "\u60a8\u5df2\u7ecf\u5df2\u8ba4\u8bc1\u5b66\u751f\u7684\u8eab\u4efd\u9009\u62e9\u4e86\u8bfe\u7a0b\uff1a", "You can now enter your payment information and complete your enrollment.": "\u4f60\u53ef\u4ee5\u73b0\u5728\u5c31\u8f93\u5165\u652f\u4ed8\u4fe1\u606f\u5e76\u5b8c\u6210\u9009\u8bfe\u3002", - "You can pay now even if you don't have the following items available, but you will need to have these by %(date)s to qualify to earn a Verified Certificate.": "\u5373\u4f7f\u4f60\u6ca1\u6709\u6ee1\u8db3\u4e0b\u9762\u8fd9\u4e9b\u8981\u6c42\uff0c\u4f60\u4e5f\u53ef\u4ee5\u73b0\u5728\u5c31\u4ed8\u6b3e\uff1b\u4f46\u662f\u4f60\u53ea\u6709\u5728%(date)s\u4e4b\u524d\u6ee1\u8db3\u8fd9\u4e9b\u8981\u6c42\u624d\u6709\u8d44\u683c\u83b7\u5f97\u4e00\u4efd\u5df2\u8ba4\u8bc1\u7684\u8bc1\u4e66\u3002", - "You can pay now even if you don't have the following items available, but you will need to have these to qualify to earn a Verified Certificate.": "\u5373\u4f7f\u4f60\u6ca1\u6709\u6ee1\u8db3\u4e0b\u9762\u8fd9\u4e9b\u8981\u6c42\uff0c\u4f60\u4e5f\u53ef\u4ee5\u73b0\u5728\u5c31\u4ed8\u6b3e\uff1b\u4f46\u662f\u4f60\u53ea\u6709\u6ee1\u8db3\u4e86\u8fd9\u4e9b\u8981\u6c42\u624d\u6709\u8d44\u683c\u83b7\u5f97\u4e00\u4efd\u5df2\u8ba4\u8bc1\u7684\u8bc1\u4e66\u3002", + "You can pay now even if you don't have the following items available, but you will need to have these by %(date)s to qualify to earn a Verified Certificate.": "\u5373\u4f7f\u4f60\u6ca1\u6709\u6ee1\u8db3\u4e0b\u9762\u8fd9\u4e9b\u8981\u6c42\uff0c\u4f60\u4e5f\u53ef\u4ee5\u73b0\u5728\u5c31\u4ed8\u6b3e\uff1b\u4f46\u662f\u4f60\u53ea\u6709\u5728%(date)s\u4e4b\u524d\u6ee1\u8db3\u8fd9\u4e9b\u8981\u6c42\u624d\u6709\u8d44\u683c\u83b7\u5f97\u8ba4\u8bc1\u8bc1\u4e66\u3002", + "You can pay now even if you don't have the following items available, but you will need to have these to qualify to earn a Verified Certificate.": "\u5373\u4f7f\u4f60\u6ca1\u6709\u6ee1\u8db3\u4e0b\u9762\u8fd9\u4e9b\u8981\u6c42\uff0c\u4f60\u4e5f\u53ef\u4ee5\u73b0\u5728\u5c31\u4ed8\u6b3e\uff1b\u4f46\u662f\u4f60\u53ea\u6709\u6ee1\u8db3\u4e86\u8fd9\u4e9b\u8981\u6c42\u624d\u6709\u8d44\u683c\u83b7\u5f97\u8ba4\u8bc1\u8bc1\u4e66\u3002", "You commented...": "\u4f60\u8bc4\u8bba\u7684\u2026", "You currently have no cohorts configured": "\u60a8\u76ee\u524d\u6ca1\u6709\u5df2\u914d\u7f6e\u7684\u7fa4\u7ec4", "You did not select a content group": "\u60a8\u672a\u9009\u53d6\u5185\u5bb9\u7ec4\u3002", @@ -914,7 +914,7 @@ "You must enter a valid email address in order to add a new team member": "\u60a8\u5fc5\u987b\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u4ee5\u4fbf\u6dfb\u52a0\u4e00\u4e2a\u65b0\u7684\u56e2\u961f\u6210\u5458", "You must specify a name": "\u60a8\u5fc5\u987b\u6307\u5b9a\u4e00\u4e2a\u540d\u79f0", "You must specify a name for the cohort": "\u60a8\u5fc5\u987b\u4e3a\u8be5\u7fa4\u7ec4\u547d\u540d\u3002", - "You need an ID with your name and photo. A driver's license, passport, or other government-issued IDs are all acceptable.": "\u4f60\u9700\u8981\u4e00\u4efd\u5e26\u6709\u4f60\u59d3\u540d\u548c\u7167\u7247\u7684\u8bc1\u4ef6\uff0c\u6211\u4eec\u53ef\u4ee5\u63a5\u53d7\u9a7e\u7167\u3001\u62a4\u7167\u4ee5\u53ca\u5176\u4ed6\u7531\u653f\u5e9c\u7b7e\u53d1\u7684\u8eab\u4efd\u8bc1\u4ef6\u3002", + "You need an ID with your name and photo. A driver's license, passport, or other government-issued IDs are all acceptable.": "\u60a8\u9700\u8981\u4e00\u4efd\u5e26\u6709\u60a8\u59d3\u540d\u548c\u7167\u7247\u7684\u8eab\u4efd\u8bc1\u4ef6\uff0c\u6211\u4eec\u53ef\u4ee5\u63a5\u53d7\u9a7e\u7167\u3001\u62a4\u7167\u4ee5\u53ca\u5176\u4ed6\u7531\u653f\u5e9c\u7b7e\u53d1\u7684\u8eab\u4efd\u8bc1\u4ef6\u3002", "You need to activate your account before you can enroll in courses. Check your inbox for an activation email.": "\u5728\u9009\u8bfe\u4e4b\u524d\u4f60\u9700\u8981\u5148\u6fc0\u6d3b\u4f60\u7684\u8d26\u6237\uff0c\u8bf7\u68c0\u67e5\u6536\u4ef6\u7bb1\u4e2d\u7684\u6fc0\u6d3b\u90ae\u4ef6\u3002", "You need to activate your account before you can enroll in courses. Check your inbox for an activation email. After you complete activation you can return and refresh this page.": "\u5728\u9009\u8bfe\u4e4b\u524d\u4f60\u9700\u8981\u5148\u6fc0\u6d3b\u4f60\u7684\u8d26\u6237\uff0c\u8bf7\u68c0\u67e5\u6536\u4ef6\u7bb1\u4e2d\u7684\u6fc0\u6d3b\u90ae\u4ef6\u3002\u5f53\u4f60\u5b8c\u6210\u6fc0\u6d3b\u540e\uff0c\u4f60\u53ef\u4ee5\u8fd4\u56de\u5e76\u5237\u65b0\u672c\u9875\u9762\u3002", "You will not receive notification for emails that bounce, so double-check your spelling.": "\u60a8\u4e0d\u4f1a\u6536\u5230\u90ae\u4ef6\u672a\u9001\u8fbe\u7684\u901a\u77e5\uff0c\u56e0\u6b64\u8bf7\u4ed4\u7ec6\u68c0\u67e5\u4ee5\u786e\u4fdd\u62fc\u5199\u65e0\u8bef\u3002", diff --git a/cms/static/js/spec/views/group_configuration_spec.js b/cms/static/js/spec/views/group_configuration_spec.js index 0f53baad57..38aaaf401d 100644 --- a/cms/static/js/spec/views/group_configuration_spec.js +++ b/cms/static/js/spec/views/group_configuration_spec.js @@ -34,10 +34,10 @@ define([ usageUnit: '.group-configuration-usage-unit', usageUnitAnchor: '.group-configuration-usage-unit a', usageUnitMessage: '.group-configuration-validation-message', - usageUnitWarningIcon: '.group-configuration-usage-unit i.fa-warning', - usageUnitErrorIcon: '.group-configuration-usage-unit i.fa-exclamation-circle', + usageUnitWarningIcon: '.group-configuration-usage-unit .fa-warning', + usageUnitErrorIcon: '.group-configuration-usage-unit .fa-exclamation-circle', warningMessage: '.group-configuration-validation-text', - warningIcon: '.wrapper-group-configuration-validation > i', + warningIcon: '.wrapper-group-configuration-validation > .fa-warning', note: '.wrapper-delete-button' }; diff --git a/cms/static/js/spec/views/pages/container_spec.js b/cms/static/js/spec/views/pages/container_spec.js index 43d36f2376..b307111536 100644 --- a/cms/static/js/spec/views/pages/container_spec.js +++ b/cms/static/js/spec/views/pages/container_spec.js @@ -519,7 +519,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja var getButtonIcon, getButtonText; getButtonIcon = function (containerPage) { - return containerPage.$('.action-toggle-preview i'); + return containerPage.$('.action-toggle-preview .fa'); }; getButtonText = function (containerPage) { diff --git a/cms/static/js/spec/views/pages/container_subviews_spec.js b/cms/static/js/spec/views/pages/container_subviews_spec.js index 1d5385bc98..1f518342cc 100644 --- a/cms/static/js/spec/views/pages/container_subviews_spec.js +++ b/cms/static/js/spec/views/pages/container_subviews_spec.js @@ -443,9 +443,9 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja verifyExplicitStaffOnly = function(isStaffOnly) { if (isStaffOnly) { - expect(containerPage.$('.action-staff-lock i')).toHaveClass('fa-check-square-o'); + expect(containerPage.$('.action-staff-lock .fa')).toHaveClass('fa-check-square-o'); } else { - expect(containerPage.$('.action-staff-lock i')).toHaveClass('fa-square-o'); + expect(containerPage.$('.action-staff-lock .fa')).toHaveClass('fa-square-o'); } }; diff --git a/cms/static/js/views/course_rerun.js b/cms/static/js/views/course_rerun.js index aed115cdcc..b256e158e5 100644 --- a/cms/static/js/views/course_rerun.js +++ b/cms/static/js/views/course_rerun.js @@ -50,7 +50,7 @@ define(["domReady", "jquery", "underscore", "js/views/utils/create_course_utils" // Go into creating re-run state $('.rerun-course-save').addClass('is-disabled').attr('aria-disabled', true).addClass('is-processing').html( - '' + gettext('Processing Re-run Request') + '' + gettext('Processing Re-run Request') //jshint ignore:line ); $('.action-cancel').addClass('is-hidden'); }; diff --git a/cms/static/js/views/metadata.js b/cms/static/js/views/metadata.js index e8aca4b5d4..f9148b3f7e 100644 --- a/cms/static/js/views/metadata.js +++ b/cms/static/js/views/metadata.js @@ -287,8 +287,8 @@ function(BaseView, _, MetadataModel, AbstractEditor, FileUpload, UploadDialog, _.each(value, function(ele, index) { var template = _.template( '
  • ' + - '' + - 'Remove' + + '' + + '' + gettext('Remove') + '' + //jshint ignore:line '
  • ' ); list.append($(template({'ele': ele, 'index': index}))); @@ -455,7 +455,7 @@ function(BaseView, _, MetadataModel, AbstractEditor, FileUpload, UploadDialog, '
  • ' + '' + '' + - 'Remove' + + 'Remove' + //jshint ignore:line '
  • ' ); diff --git a/cms/static/js/views/overview_assignment_grader.js b/cms/static/js/views/overview_assignment_grader.js deleted file mode 100644 index 8d6aeaa9be..0000000000 --- a/cms/static/js/views/overview_assignment_grader.js +++ /dev/null @@ -1,87 +0,0 @@ -define(["js/views/baseview", "underscore", "gettext", "js/models/assignment_grade", "common/js/components/views/feedback_notification"], - function(BaseView, _, gettext, AssignmentGrade, NotificationView) { - var l10nNotGraded = gettext('Not Graded'); - var OverviewAssignmentGrader = BaseView.extend({ - // instantiate w/ { graders : CourseGraderCollection, el : } - events : { - "click .menu-toggle" : "showGradeMenu", - "click .menu li" : "selectGradeType" - }, - initialize : function() { - // call template w/ {assignmentType : formatname, graders : CourseGraderCollection instance } - this.template = _.template( - // TODO move to a template file - '

    <%= assignmentType %>

    ' + - '' + - '<% if (!hideSymbol) {%><%};%>' + - '' + - ''); - this.assignmentGrade = new AssignmentGrade({ - locator : this.$el.closest('.id-holder').data('locator'), - graderType : this.$el.data('initial-status')}); - // TODO throw exception if graders is null - this.graders = this.options['graders']; - var cachethis = this; - // defining here to get closure around this - this.removeMenu = function(e) { - e.preventDefault(); - cachethis.$el.removeClass('is-active'); - $(document).off('click', cachethis.removeMenu); - }; - this.hideSymbol = this.options['hideSymbol']; - this.render(); - }, - render : function() { - var graderType = this.assignmentGrade.get('graderType'); - this.$el.html(this.template( - { - assignmentType : (graderType == 'notgraded') ? l10nNotGraded : graderType, - graders : this.graders, - hideSymbol : this.hideSymbol - } - )); - if (this.assignmentGrade.has('graderType') && this.assignmentGrade.get('graderType') != "notgraded") { - this.$el.addClass('is-set'); - } - else { - this.$el.removeClass('is-set'); - } - }, - showGradeMenu : function(e) { - e.preventDefault(); - // I sure hope this doesn't break anything but it's needed to keep the removeMenu from activating - e.stopPropagation(); - // nasty global event trap :-( - $(document).on('click', this.removeMenu); - this.$el.addClass('is-active'); - }, - selectGradeType : function(e) { - e.preventDefault(); - - this.removeMenu(e); - - var saving = new NotificationView.Mini({ - title: gettext('Saving') - }); - saving.show(); - - // TODO I'm not happy with this string fetch via the html for what should be an id. I'd rather use the id attr - // of the CourseGradingPolicy model or null for notgraded (NOTE, change template's if check for is-selected accordingly) - this.assignmentGrade.save( - 'graderType', - ($(e.target).hasClass('gradable-status-notgraded')) ? 'notgraded' : $(e.target).text(), - {success: function () { saving.hide(); }} - ); - - this.render(); - } - }); - return OverviewAssignmentGrader; -}); diff --git a/cms/static/js/views/tabs.js b/cms/static/js/views/tabs.js new file mode 100644 index 0000000000..9f83edeb19 --- /dev/null +++ b/cms/static/js/views/tabs.js @@ -0,0 +1,203 @@ +(function(analytics, course_location_analytics) { + 'use strict'; + + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { + var key; + for (key in parent) { + if (__hasProp.call(parent, key)) { + child[key] = parent[key]; + } + } + function Ctor() { + this.constructor = child; + } + Ctor.prototype = parent.prototype; + child.prototype = new Ctor(); + child.__super__ = parent.prototype; + return child; + }; + + define(['underscore', 'jquery', 'jquery.ui', 'backbone', 'common/js/components/views/feedback_prompt', + 'common/js/components/views/feedback_notification', 'coffee/src/views/module_edit', + 'js/models/module_info', 'js/utils/module'], + function(_, $, ui, Backbone, PromptView, NotificationView, ModuleEditView, ModuleModel, ModuleUtils) { + var TabsEdit; + TabsEdit = (function(_super) { + + __extends(TabsEdit, _super); + + function TabsEdit() { + var self = this; + this.deleteTab = function() { + return TabsEdit.prototype.deleteTab.apply(self, arguments); + }; + this.addNewTab = function() { + return TabsEdit.prototype.addNewTab.apply(self, arguments); + }; + this.tabMoved = function() { + return TabsEdit.prototype.tabMoved.apply(self, arguments); + }; + this.toggleVisibilityOfTab = function() { + return TabsEdit.prototype.toggleVisibilityOfTab.apply(self, arguments); + }; + this.initialize = function() { + return TabsEdit.prototype.initialize.apply(self, arguments); + }; + return TabsEdit.__super__.constructor.apply(this, arguments); + } + + TabsEdit.prototype.initialize = function(options) { + var self = this; + this.$('.component').each(function(idx, element) { + var model; + model = new ModuleModel({ + id: $(element).data('locator') + }); + return new ModuleEditView({ + el: element, + onDelete: self.deleteTab, + model: model + }); + }); + this.options = _.extend({}, options); + this.options.mast.find('.new-tab').on('click', this.addNewTab); + $('.add-pages .new-tab').on('click', this.addNewTab); + $('.toggle-checkbox').on('click', this.toggleVisibilityOfTab); + return this.$('.course-nav-list').sortable({ + handle: '.drag-handle', + update: this.tabMoved, + helper: 'clone', + opacity: '0.5', + placeholder: 'component-placeholder', + forcePlaceholderSize: true, + axis: 'y', + items: '> .is-movable' + }); + }; + + TabsEdit.prototype.toggleVisibilityOfTab = function(event) { + var checkbox_element, saving, tab_element; + checkbox_element = event.target; + tab_element = $(checkbox_element).parents('.course-tab')[0]; + saving = new NotificationView.Mini({ + title: gettext('Saving') + }); + saving.show(); + return $.ajax({ + type: 'POST', + url: this.model.url(), + data: JSON.stringify({ + tab_id_locator: { + tab_id: $(tab_element).data('tab-id'), + tab_locator: $(tab_element).data('locator') + }, + is_hidden: $(checkbox_element).is(':checked') + }), + contentType: 'application/json' + }).success(function() { + return saving.hide(); + }); + }; + + TabsEdit.prototype.tabMoved = function() { + var saving, tabs; + tabs = []; + this.$('.course-tab').each(function(idx, element) { + return tabs.push({ + tab_id: $(element).data('tab-id'), + tab_locator: $(element).data('locator') + }); + }); + analytics.track('Reordered Pages', { + course: course_location_analytics + }); + saving = new NotificationView.Mini({ + title: gettext('Saving') + }); + saving.show(); + return $.ajax({ + type: 'POST', + url: this.model.url(), + data: JSON.stringify({ + tabs: tabs + }), + contentType: 'application/json' + }).success(function() { + return saving.hide(); + }); + }; + + TabsEdit.prototype.addNewTab = function(event) { + var editor; + event.preventDefault(); + editor = new ModuleEditView({ + onDelete: this.deleteTab, + model: new ModuleModel() + }); + $('.new-component-item').before(editor.$el); + editor.$el.addClass('course-tab is-movable'); + editor.$el.addClass('new'); + setTimeout(function() { + return editor.$el.removeClass('new'); + }, 1000); + $('html, body').animate({ + scrollTop: $('.new-component-item').offset().top + }, 500); + editor.createItem(this.model.get('id'), { + category: 'static_tab' + }); + return analytics.track('Added Page', { + course: course_location_analytics + }); + }; + + TabsEdit.prototype.deleteTab = function(event) { + var confirm; + confirm = new PromptView.Warning({ + title: gettext('Delete Page Confirmation'), + message: gettext('Are you sure you want to delete this page? This action cannot be undone.'), + actions: { + primary: { + text: gettext('OK'), + click: function(view) { + var $component, deleting; + view.hide(); + $component = $(event.currentTarget).parents('.component'); + analytics.track('Deleted Page', { + course: course_location_analytics, + id: $component.data('locator') + }); + deleting = new NotificationView.Mini({ + title: gettext('Deleting') + }); + deleting.show(); + return $.ajax({ + type: 'DELETE', + url: ModuleUtils.getUpdateUrl($component.data('locator')) + }).success(function() { + $component.remove(); + return deleting.hide(); + }); + } + }, + secondary: [ + { + text: gettext('Cancel'), + click: function(view) { + return view.hide(); + } + } + ] + } + }); + return confirm.show(); + }; + + return TabsEdit; + + })(Backbone.View); + return TabsEdit; + }); + +}).call(this, analytics, course_location_analytics); //jshint ignore:line diff --git a/cms/static/sass/_base.scss b/cms/static/sass/_base.scss index a8fefa28d5..8da5903138 100644 --- a/cms/static/sass/_base.scss +++ b/cms/static/sass/_base.scss @@ -36,6 +36,11 @@ body, input, button { font-family: 'Open Sans', sans-serif; } +// we want to hide the outline on the focusable
    element +main { + outline: none; +} + a { @include transition(color $tmg-f2 ease-in-out 0s); text-decoration: none; diff --git a/cms/templates/asset_index.html b/cms/templates/asset_index.html index 1fe9b7d251..48a6559ecd 100644 --- a/cms/templates/asset_index.html +++ b/cms/templates/asset_index.html @@ -44,7 +44,7 @@

    ${_("Page Actions")}

    @@ -56,7 +56,7 @@
    -

    ${_("Loading")}

    +

    ${_("Loading")}

    @@ -88,7 +88,7 @@ @@ -191,7 +191,7 @@ - + ${_("close modal")} @@ -204,7 +204,7 @@ - + ${_("close modal")} diff --git a/cms/templates/html_error.html b/cms/templates/html_error.html index 5cfdafb575..6b80a6a1ff 100644 --- a/cms/templates/html_error.html +++ b/cms/templates/html_error.html @@ -7,7 +7,7 @@

    - + ${_("We're having trouble rendering your component")}

    diff --git a/cms/templates/import.html b/cms/templates/import.html index b00db006d2..dc9bf72725 100644 --- a/cms/templates/import.html +++ b/cms/templates/import.html @@ -69,7 +69,7 @@ else:

    - + ${_("Choose a File to Import")} @@ -102,8 +102,8 @@ else:
    1. - - + +
      @@ -117,8 +117,8 @@ else:
    2. - - + +
      @@ -130,8 +130,8 @@ else:
    3. - - + +
      @@ -142,8 +142,8 @@ else:
    4. - - + +
      @@ -165,7 +165,7 @@ else:
    5. - +
      diff --git a/cms/templates/index.html b/cms/templates/index.html index 76d63a924a..daf518d8a6 100644 --- a/cms/templates/index.html +++ b/cms/templates/index.html @@ -28,19 +28,19 @@ from openedx.core.djangolib.markup import HTML, Text
        @@ -220,7 +220,7 @@ from openedx.core.djangolib.markup import HTML, Text
        ${_("This course run is currently being created.")}
        - + ## Translators: This is a status message, used to inform the user of ## what the system is doing. This status means that the user has ## requested to re-run an existing course, and the system is currently @@ -270,7 +270,7 @@ from openedx.core.djangolib.markup import HTML, Text ## the process will follow this text.
        ${_("This re-run processing status:")}
        - + ${_("Configuration Error")}
        @@ -282,7 +282,7 @@ from openedx.core.djangolib.markup import HTML, Text
      @@ -381,7 +381,7 @@ from openedx.core.djangolib.markup import HTML, Text %if course_creator_status == "unrequested":

      - ${_('Becoming a Course Creator in {studio_name}').format(studio_name=settings.STUDIO_SHORT_NAME)} + ${_('Becoming a Course Creator in {studio_name}').format(studio_name=settings.STUDIO_SHORT_NAME)}

      @@ -395,7 +395,7 @@ from openedx.core.djangolib.markup import HTML, Text
      - +
      @@ -405,7 +405,7 @@ from openedx.core.djangolib.markup import HTML, Text %elif course_creator_status == "denied":

      - ${_('Your Course Creator Request Status')} + ${_('Your Course Creator Request Status')}

      @@ -433,7 +433,7 @@ from openedx.core.djangolib.markup import HTML, Text %elif course_creator_status == "pending":

      - ${_('Your Course Creator Request Status')} + ${_('Your Course Creator Request Status')}

      @@ -508,7 +508,7 @@ from openedx.core.djangolib.markup import HTML, Text
      @@ -553,7 +553,7 @@ from openedx.core.djangolib.markup import HTML, Text diff --git a/cms/templates/js/access-editor.underscore b/cms/templates/js/access-editor.underscore index a4fc348aa1..7b1b7c09b9 100644 --- a/cms/templates/js/access-editor.underscore +++ b/cms/templates/js/access-editor.underscore @@ -35,8 +35,8 @@
    6. diff --git a/cms/templates/js/asset-library.underscore b/cms/templates/js/asset-library.underscore index 3ab3cfc6eb..d199bdfb4c 100644 --- a/cms/templates/js/asset-library.underscore +++ b/cms/templates/js/asset-library.underscore @@ -26,7 +26,7 @@ <%- gettext("Type") %> Filter - +
      -

      <%- gettext("You haven't added any assets to this course yet.") %> <%- gettext("Upload your first asset") %>

      +

      <%- gettext("You haven't added any assets to this course yet.") %> <%- gettext("Upload your first asset") %>

      diff --git a/cms/templates/js/asset-upload-modal.underscore b/cms/templates/js/asset-upload-modal.underscore index 3b146affd5..17101b0325 100644 --- a/cms/templates/js/asset-upload-modal.underscore +++ b/cms/templates/js/asset-upload-modal.underscore @@ -1,5 +1,5 @@
    - <%= gettext("Add") %> <%= model.get('display_name')%> + <%= gettext("Add") %> <%= model.get('display_name')%>
    diff --git a/cms/templates/js/metadata-number-entry.underscore b/cms/templates/js/metadata-number-entry.underscore index b30e5b84e5..8621ab528c 100644 --- a/cms/templates/js/metadata-number-entry.underscore +++ b/cms/templates/js/metadata-number-entry.underscore @@ -2,7 +2,7 @@ <%= model.get('help') %> diff --git a/cms/templates/js/metadata-option-entry.underscore b/cms/templates/js/metadata-option-entry.underscore index 952e914248..71132c66ff 100644 --- a/cms/templates/js/metadata-option-entry.underscore +++ b/cms/templates/js/metadata-option-entry.underscore @@ -10,7 +10,7 @@ <% }) %> <%= model.get('help') %> diff --git a/cms/templates/js/metadata-string-entry.underscore b/cms/templates/js/metadata-string-entry.underscore index cef204e0bd..538528afc2 100644 --- a/cms/templates/js/metadata-string-entry.underscore +++ b/cms/templates/js/metadata-string-entry.underscore @@ -2,7 +2,7 @@ <%= model.get('help') %> diff --git a/cms/templates/js/mock/mock-collapsible-view.underscore b/cms/templates/js/mock/mock-collapsible-view.underscore index 78f55f2784..556fcb61cc 100644 --- a/cms/templates/js/mock/mock-collapsible-view.underscore +++ b/cms/templates/js/mock/mock-collapsible-view.underscore @@ -1,4 +1,4 @@
    - Expand/Collapse + Expand/Collapse
    Mock Content
    diff --git a/cms/templates/js/mock/mock-container-page.underscore b/cms/templates/js/mock/mock-container-page.underscore index d5356605f2..620f8995f0 100644 --- a/cms/templates/js/mock/mock-container-page.underscore +++ b/cms/templates/js/mock/mock-container-page.underscore @@ -28,20 +28,20 @@ % else: % endif @@ -59,7 +59,7 @@
    - diff --git a/lms/templates/static_pdfbook.html b/lms/templates/static_pdfbook.html index e6b6cb25f0..4b1079250b 100644 --- a/lms/templates/static_pdfbook.html +++ b/lms/templates/static_pdfbook.html @@ -26,10 +26,11 @@ $(function(){ }); -
    +
    +
    %if 'chapters' in textbook:
    -
      +
        % for (index, entry) in enumerate(textbook['chapters']):
      • ${entry.get('title')} @@ -39,16 +40,15 @@ $(function(){
    %endif -
    - -
    -
    +
    + +
    +
    + diff --git a/lms/templates/staticbook.html b/lms/templates/staticbook.html index 92e618c973..7112cf40ce 100644 --- a/lms/templates/staticbook.html +++ b/lms/templates/staticbook.html @@ -76,6 +76,7 @@ $("#open_close_accordion a").click(function(){ <%include file="/courseware/course_navigation.html" args="active_page='textbook/{0}'.format(book_index)" />
    +
    @@ -130,4 +131,5 @@ $("#open_close_accordion a").click(function(){
    + diff --git a/lms/templates/student_account/account_settings.html b/lms/templates/student_account/account_settings.html index 5580a9b0ed..c8653c0a9b 100644 --- a/lms/templates/student_account/account_settings.html +++ b/lms/templates/student_account/account_settings.html @@ -32,12 +32,14 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_str <%block name="js_extra"> <%static:require_module module_name="js/student_account/views/account_settings_factory" class_name="AccountSettingsFactory"> - var fieldsData = ${ fields | n, dump_js_escaped_json }; - var authData = ${ auth | n, dump_js_escaped_json }; - var platformName = '${ static.get_platform_name() | n, js_escaped_string }'; + var fieldsData = ${ fields | n, dump_js_escaped_json }, + ordersHistoryData = ${ order_history | n, dump_js_escaped_json }, + authData = ${ auth | n, dump_js_escaped_json }, + platformName = '${ static.get_platform_name() | n, js_escaped_string }'; AccountSettingsFactory( fieldsData, + ordersHistoryData, authData, '${ user_accounts_api_url | n, js_escaped_string }', '${ user_preferences_api_url | n, js_escaped_string }', diff --git a/lms/templates/student_account/account_settings_section.underscore b/lms/templates/student_account/account_settings_section.underscore index e6f763d21d..0370c6ad51 100644 --- a/lms/templates/student_account/account_settings_section.underscore +++ b/lms/templates/student_account/account_settings_section.underscore @@ -1,7 +1,7 @@ <% _.each(sections, function(section) { %>
    <% if (section.subtitle) { %> - + <% } %>

    <%- gettext(section.title) %>

    +
    diff --git a/lms/templates/wiki/base.html b/lms/templates/wiki/base.html index fe6112a369..f19e6c20b8 100644 --- a/lms/templates/wiki/base.html +++ b/lms/templates/wiki/base.html @@ -2,7 +2,9 @@ {% with online_help_token="wiki" %} {% load pipeline %}{% load sekizai_tags i18n microsite %}{% load url from future %}{% load staticfiles %} -{% block title %}{% block pagetitle %}{% endblock %} | {% trans "Wiki" %} | {% platform_name %}{% endblock %} +{% block title %} + {% block pagetitle %}{% endblock %} | {% trans "Wiki" %} | {% platform_name %} +{% endblock %} {% block bodyclass %}view-in-course view-wiki{% endblock %} diff --git a/lms/urls.py b/lms/urls.py index 3aabc1d0c2..3a100daba5 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -15,6 +15,7 @@ from config_models.views import ConfigurationModelCurrentAPIView from courseware.views.index import CoursewareIndex from openedx.core.djangoapps.programs.models import ProgramsApiConfig from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration +from student.views import LogoutView # Uncomment the next two lines to enable the admin: if settings.DEBUG or settings.FEATURES.get('ENABLE_DJANGO_ADMIN_SITE'): @@ -42,7 +43,7 @@ urlpatterns = ( url(r'^accounts/disable_account_ajax$', 'student.views.disable_account_ajax', name="disable_account_ajax"), - url(r'^logout$', 'student.views.logout_user', name='logout'), + url(r'^logout$', LogoutView.as_view(), name='logout'), url(r'^create_account$', 'student.views.create_account', name='create_account'), url(r'^activate/(?P[^/]*)$', 'student.views.activate_account', name="activate"), diff --git a/openedx/core/djangoapps/api_admin/models.py b/openedx/core/djangoapps/api_admin/models.py index eb5c2600e4..57c16338d4 100644 --- a/openedx/core/djangoapps/api_admin/models.py +++ b/openedx/core/djangoapps/api_admin/models.py @@ -17,6 +17,7 @@ from edxmako.shortcuts import render_to_string from simple_history.models import HistoricalRecords from config_models.models import ConfigurationModel +from openedx.core.djangoapps.theming.helpers import get_value as get_themed_value log = logging.getLogger(__name__) @@ -161,7 +162,7 @@ def _send_decision_email(instance): 'authentication_docs_url': settings.AUTH_DOCUMENTATION_URL, 'api_docs_url': settings.API_DOCUMENTATION_URL, 'support_email_address': settings.API_ACCESS_FROM_EMAIL, - 'platform_name': settings.PLATFORM_NAME + 'platform_name': get_themed_value('PLATFORM_NAME', settings.PLATFORM_NAME) } message = render_to_string( diff --git a/openedx/core/djangoapps/api_admin/tests/test_views.py b/openedx/core/djangoapps/api_admin/tests/test_views.py index 512b07a059..c9e25c50d4 100644 --- a/openedx/core/djangoapps/api_admin/tests/test_views.py +++ b/openedx/core/djangoapps/api_admin/tests/test_views.py @@ -1,15 +1,14 @@ -#pylint: disable=missing-docstring -import unittest +""" Tests for the api_admin app's views. """ + import json -from urlparse import urljoin +import unittest import ddt +import httpretty from django.conf import settings from django.core.urlresolvers import reverse from django.test import TestCase from django.test.utils import override_settings -from edx_oauth2_provider.tests.factories import ClientFactory -import httpretty from oauth2_provider.models import get_application_model from openedx.core.djangoapps.api_admin.models import ApiAccessRequest, ApiAccessConfig @@ -19,14 +18,10 @@ from openedx.core.djangoapps.api_admin.tests.factories import ( from openedx.core.djangoapps.api_admin.tests.utils import VALID_DATA from student.tests.factories import UserFactory - Application = get_application_model() # pylint: disable=invalid-name -MOCK_CATALOG_API_URL_ROOT = 'https://api.example.com/' - class ApiAdminTest(TestCase): - def setUp(self): super(ApiAdminTest, self).setUp() ApiAccessConfig(enabled=True).save() @@ -34,7 +29,6 @@ class ApiAdminTest(TestCase): @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') class ApiRequestViewTest(ApiAdminTest): - def setUp(self): super(ApiRequestViewTest, self).setUp() self.url = reverse('api_admin:api-request') @@ -103,7 +97,6 @@ class ApiRequestViewTest(ApiAdminTest): @override_settings(PLATFORM_NAME='edX') @ddt.ddt class ApiRequestStatusViewTest(ApiAdminTest): - def setUp(self): super(ApiRequestStatusViewTest, self).setUp() password = 'abc123' @@ -207,7 +200,6 @@ class ApiRequestStatusViewTest(ApiAdminTest): @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') class ApiTosViewTest(ApiAdminTest): - def test_get_api_tos(self): """Verify that the terms of service can be read.""" url = reverse('api_admin:api-tos') @@ -217,20 +209,23 @@ class ApiTosViewTest(ApiAdminTest): class CatalogTest(ApiAdminTest): - def setUp(self): super(CatalogTest, self).setUp() password = 'abc123' self.user = UserFactory(password=password, is_staff=True) self.client.login(username=self.user.username, password=password) - ClientFactory(user=self.user, name='course-discovery', url=MOCK_CATALOG_API_URL_ROOT) - def mock_catalog_api(self, url, data, method=httpretty.GET, status_code=200): + def mock_catalog_endpoint(self, data, catalog_id=None, method=httpretty.GET, status_code=200): + """ Mock the Course Catalog API's catalog endpoint. """ self.assertTrue(httpretty.is_enabled(), msg='httpretty must be enabled to mock Catalog API calls.') - httpretty.reset() + + url = '{root}/catalogs/'.format(root=settings.COURSE_CATALOG_API_URL.rstrip('/')) + if catalog_id: + url += '{id}/'.format(id=catalog_id) + httpretty.register_uri( method, - urljoin(MOCK_CATALOG_API_URL_ROOT, url), + url, body=json.dumps(data), content_type='application/json', status=status_code @@ -239,7 +234,6 @@ class CatalogTest(ApiAdminTest): @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') class CatalogSearchViewTest(CatalogTest): - def setUp(self): super(CatalogSearchViewTest, self).setUp() self.url = reverse('api_admin:catalog-search') @@ -251,7 +245,7 @@ class CatalogSearchViewTest(CatalogTest): @httpretty.activate def test_post(self): catalog_user = UserFactory() - self.mock_catalog_api('api/v1/catalogs/', {'results': []}) + self.mock_catalog_endpoint({'results': []}) response = self.client.post(self.url, {'username': catalog_user.username}) self.assertRedirects(response, reverse('api_admin:catalog-list', kwargs={'username': catalog_user.username})) @@ -262,7 +256,6 @@ class CatalogSearchViewTest(CatalogTest): @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') class CatalogListViewTest(CatalogTest): - def setUp(self): super(CatalogListViewTest, self).setUp() self.catalog_user = UserFactory() @@ -271,13 +264,18 @@ class CatalogListViewTest(CatalogTest): @httpretty.activate def test_get(self): catalog = CatalogFactory(viewers=[self.catalog_user.username]) - self.mock_catalog_api('api/v1/catalogs/', { - 'results': [catalog.attributes] - }) + self.mock_catalog_endpoint({'results': [catalog.attributes]}) response = self.client.get(self.url) self.assertEqual(response.status_code, 200) self.assertIn(catalog.name, response.content.decode('utf-8')) + @httpretty.activate + def test_get_no_catalogs(self): + """Verify that the view works when no catalogs are set up.""" + self.mock_catalog_endpoint({}, status_code=404) + response = self.client.get(self.url) + self.assertEqual(response.status_code, 200) + @httpretty.activate def test_post(self): catalog_data = { @@ -286,18 +284,16 @@ class CatalogListViewTest(CatalogTest): 'viewers': [self.catalog_user.username] } catalog_id = 123 - self.mock_catalog_api('api/v1/catalogs/', dict(catalog_data, id=catalog_id), method=httpretty.POST) + self.mock_catalog_endpoint(dict(catalog_data, id=catalog_id), method=httpretty.POST) response = self.client.post(self.url, catalog_data) self.assertEqual(httpretty.last_request().method, 'POST') - self.mock_catalog_api('api/v1/catalogs/{}/'.format(catalog_id), CatalogFactory().attributes) + self.mock_catalog_endpoint(CatalogFactory().attributes, catalog_id=catalog_id) self.assertRedirects(response, reverse('api_admin:catalog-edit', kwargs={'catalog_id': catalog_id})) @httpretty.activate def test_post_invalid(self): catalog = CatalogFactory(viewers=[self.catalog_user.username]) - self.mock_catalog_api('api/v1/catalogs/', { - 'results': [catalog.attributes] - }) + self.mock_catalog_endpoint({'results': [catalog.attributes]}) response = self.client.post(self.url, { 'name': '', 'query': '*', @@ -310,7 +306,6 @@ class CatalogListViewTest(CatalogTest): @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') class CatalogEditViewTest(CatalogTest): - def setUp(self): super(CatalogEditViewTest, self).setUp() self.catalog_user = UserFactory() @@ -319,17 +314,17 @@ class CatalogEditViewTest(CatalogTest): @httpretty.activate def test_get(self): - self.mock_catalog_api('api/v1/catalogs/{}/'.format(self.catalog.id), self.catalog.attributes) + self.mock_catalog_endpoint(self.catalog.attributes, catalog_id=self.catalog.id) response = self.client.get(self.url) self.assertEqual(response.status_code, 200) self.assertIn(self.catalog.name, response.content.decode('utf-8')) @httpretty.activate def test_delete(self): - self.mock_catalog_api( - 'api/v1/catalogs/{}/'.format(self.catalog.id), + self.mock_catalog_endpoint( self.catalog.attributes, - method=httpretty.DELETE + method=httpretty.DELETE, + catalog_id=self.catalog.id ) response = self.client.post(self.url, {'delete-catalog': 'on'}) self.assertRedirects(response, reverse('api_admin:catalog-search')) @@ -342,18 +337,15 @@ class CatalogEditViewTest(CatalogTest): @httpretty.activate def test_edit(self): - self.mock_catalog_api( - 'api/v1/catalogs/{}/'.format(self.catalog.id), - self.catalog.attributes, method=httpretty.PATCH - ) + self.mock_catalog_endpoint(self.catalog.attributes, method=httpretty.PATCH, catalog_id=self.catalog.id) new_attributes = dict(self.catalog.attributes, **{'delete-catalog': 'off', 'name': 'changed'}) response = self.client.post(self.url, new_attributes) - self.mock_catalog_api('api/v1/catalogs/{}/'.format(self.catalog.id), new_attributes) + self.mock_catalog_endpoint(new_attributes, catalog_id=self.catalog.id) self.assertRedirects(response, reverse('api_admin:catalog-edit', kwargs={'catalog_id': self.catalog.id})) @httpretty.activate def test_edit_invalid(self): - self.mock_catalog_api('api/v1/catalogs/{}/'.format(self.catalog.id), self.catalog.attributes) + self.mock_catalog_endpoint(self.catalog.attributes, catalog_id=self.catalog.id) new_attributes = dict(self.catalog.attributes, **{'delete-catalog': 'off', 'name': ''}) response = self.client.post(self.url, new_attributes) self.assertEqual(response.status_code, 400) @@ -363,7 +355,6 @@ class CatalogEditViewTest(CatalogTest): @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') class CatalogPreviewViewTest(CatalogTest): - def setUp(self): super(CatalogPreviewViewTest, self).setUp() self.url = reverse('api_admin:catalog-preview') @@ -371,7 +362,12 @@ class CatalogPreviewViewTest(CatalogTest): @httpretty.activate def test_get(self): data = {'count': 1, 'results': ['test data'], 'next': None, 'prev': None} - self.mock_catalog_api('api/v1/courses/', data) + httpretty.register_uri( + httpretty.GET, + '{root}/courses/'.format(root=settings.COURSE_CATALOG_API_URL.rstrip('/')), + body=json.dumps(data), + content_type='application/json' + ) response = self.client.get(self.url, {'q': '*'}) self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(response.content), data) diff --git a/openedx/core/djangoapps/api_admin/utils.py b/openedx/core/djangoapps/api_admin/utils.py index a19eabf98c..07a7f2a0f1 100644 --- a/openedx/core/djangoapps/api_admin/utils.py +++ b/openedx/core/djangoapps/api_admin/utils.py @@ -1,16 +1,13 @@ """ Course Discovery API Service. """ import datetime +import jwt from django.conf import settings from edx_rest_api_client.client import EdxRestApiClient -import jwt from openedx.core.djangoapps.theming import helpers -from provider.oauth2.models import Client from student.models import UserProfile, anonymous_id_for_user -CLIENT_NAME = 'course-discovery' - def get_id_token(user): """ @@ -44,10 +41,9 @@ def get_id_token(user): } secret_key = helpers.get_value('JWT_AUTH', settings.JWT_AUTH)['JWT_SECRET_KEY'] - return jwt.encode(payload, secret_key) + return jwt.encode(payload, secret_key).decode('utf-8') def course_discovery_api_client(user): """ Returns a Course Discovery API client setup with authentication for the specified user. """ - course_discovery_client = Client.objects.get(name=CLIENT_NAME) - return EdxRestApiClient(course_discovery_client.url, jwt=get_id_token(user)) + return EdxRestApiClient(settings.COURSE_CATALOG_API_URL, jwt=get_id_token(user)) diff --git a/openedx/core/djangoapps/api_admin/views.py b/openedx/core/djangoapps/api_admin/views.py index c9b87cd963..4bd78ffdc3 100644 --- a/openedx/core/djangoapps/api_admin/views.py +++ b/openedx/core/djangoapps/api_admin/views.py @@ -6,13 +6,13 @@ from django.contrib.sites.shortcuts import get_current_site from django.core.urlresolvers import reverse_lazy, reverse from django.http.response import JsonResponse from django.shortcuts import redirect -from django.utils.translation import ugettext as _ from django.views.generic import View from django.views.generic.base import TemplateView from django.views.generic.edit import CreateView from oauth2_provider.generators import generate_client_secret, generate_client_id from oauth2_provider.models import get_application_model from oauth2_provider.views import ApplicationRegistration +from slumber.exceptions import HttpNotFoundError from edxmako.shortcuts import render_to_response from openedx.core.djangoapps.api_admin.decorators import require_api_access @@ -140,73 +140,80 @@ class CatalogListView(View): template = 'api_admin/catalogs/list.html' + def _get_catalogs(self, client, username): + """Retrieve catalogs for a user. Returns the empty list if none are found.""" + try: + response = client.catalogs.get(username=username) + return [Catalog(attributes=catalog) for catalog in response['results']] + except HttpNotFoundError: + return [] + + def get_context_data(self, client, username, form): + """ Retrieve context data for the template. """ + + return { + 'username': username, + 'catalogs': self._get_catalogs(client, username), + 'form': form, + 'preview_url': reverse('api_admin:catalog-preview'), + 'catalog_api_catalog_endpoint': client.catalogs.url().rstrip('/'), + 'catalog_api_url': client.courses.url(), + } + def get(self, request, username): """Display a list of a user's catalogs.""" client = course_discovery_api_client(request.user) - response = client.api.v1.catalogs.get(username=username) - catalogs = [Catalog(attributes=catalog) for catalog in response['results']] - return render_to_response(self.template, { - 'username': username, - 'catalogs': catalogs, - 'form': CatalogForm(initial={'viewers': [username]}), - 'preview_url': reverse('api_admin:catalog-preview'), - 'catalog_api_url': client.api.v1.courses.url(), - }) + form = CatalogForm(initial={'viewers': [username]}) + return render_to_response(self.template, self.get_context_data(client, username, form)) def post(self, request, username): """Create a new catalog for a user.""" form = CatalogForm(request.POST) client = course_discovery_api_client(request.user) - if not form.is_valid(): - response = client.api.v1.catalogs.get(username=username) - catalogs = [Catalog(attributes=catalog) for catalog in response['results']] - return render_to_response(self.template, { - 'form': form, - 'catalogs': catalogs, - 'username': username, - 'preview_url': reverse('api_admin:catalog-preview'), - 'catalog_api_url': client.api.v1.courses.url(), - }, status=400) + return render_to_response(self.template, self.get_context_data(client, username, form), status=400) attrs = form.instance.attributes - catalog = client.api.v1.catalogs.post(attrs) + catalog = client.catalogs.post(attrs) return redirect(reverse('api_admin:catalog-edit', kwargs={'catalog_id': catalog['id']})) class CatalogEditView(View): """View to edit an individual catalog.""" - def get(self, request, catalog_id): - """Display a form to edit this catalog.""" - client = course_discovery_api_client(request.user) - response = client.api.v1.catalogs(catalog_id).get() - catalog = Catalog(attributes=response) - form = CatalogForm(instance=catalog) - return render_to_response('api_admin/catalogs/edit.html', { + template_name = 'api_admin/catalogs/edit.html' + + def get_context_data(self, catalog, form, client): + """ Retrieve context data for the template. """ + + return { 'catalog': catalog, 'form': form, 'preview_url': reverse('api_admin:catalog-preview'), - 'catalog_api_url': client.api.v1.courses.url(), - }) + 'catalog_api_url': client.courses.url(), + 'catalog_api_catalog_endpoint': client.catalogs.url().rstrip('/'), + } + + def get(self, request, catalog_id): + """Display a form to edit this catalog.""" + client = course_discovery_api_client(request.user) + response = client.catalogs(catalog_id).get() + catalog = Catalog(attributes=response) + form = CatalogForm(instance=catalog) + return render_to_response(self.template_name, self.get_context_data(catalog, form, client)) def post(self, request, catalog_id): """Update or delete this catalog.""" client = course_discovery_api_client(request.user) if request.POST.get('delete-catalog') == 'on': - client.api.v1.catalogs(catalog_id).delete() + client.catalogs(catalog_id).delete() return redirect(reverse('api_admin:catalog-search')) form = CatalogForm(request.POST) if not form.is_valid(): - response = client.api.v1.catalogs(catalog_id).get() + response = client.catalogs(catalog_id).get() catalog = Catalog(attributes=response) - return render_to_response('api_admin/catalogs/edit.html', { - 'catalog': catalog, - 'form': form, - 'preview_url': reverse('api_admin:catalog-preview'), - 'catalog_api_url': client.api.v1.courses.url(), - }, status=400) - catalog = client.api.v1.catalogs(catalog_id).patch(form.instance.attributes) + return render_to_response(self.template_name, self.get_context_data(catalog, form, client), status=400) + catalog = client.catalogs(catalog_id).patch(form.instance.attributes) return redirect(reverse('api_admin:catalog-edit', kwargs={'catalog_id': catalog['id']})) @@ -221,7 +228,7 @@ class CatalogPreviewView(View): client = course_discovery_api_client(request.user) # Just pass along the request params including limit/offset pagination if 'q' in request.GET: - results = client.api.v1.courses.get(**request.GET) + results = client.courses.get(**request.GET) # Ensure that we don't just return all the courses if no query is given else: results = {'count': 0, 'results': [], 'next': None, 'prev': None} diff --git a/openedx/core/djangoapps/api_admin/widgets.py b/openedx/core/djangoapps/api_admin/widgets.py index 0b1e5f4600..f51800f09b 100644 --- a/openedx/core/djangoapps/api_admin/widgets.py +++ b/openedx/core/djangoapps/api_admin/widgets.py @@ -7,6 +7,7 @@ from django.forms.widgets import CheckboxInput from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.translation import ugettext as _ +from openedx.core.djangoapps.theming.helpers import get_value as get_themed_value class TermsOfServiceCheckboxInput(CheckboxInput): @@ -23,7 +24,7 @@ class TermsOfServiceCheckboxInput(CheckboxInput): # Translators: link_start and link_end are HTML tags for a link to the terms of service. # platform_name is the name of this Open edX installation. label = _('I, and my company, accept the {link_start}{platform_name} API Terms of Service{link_end}.').format( - platform_name=settings.PLATFORM_NAME, + platform_name=get_themed_value('PLATFORM_NAME', settings.PLATFORM_NAME), link_start=''.format(url=reverse('api_admin:api-tos')), link_end='', ) diff --git a/openedx/core/djangoapps/content/__init__.py b/openedx/core/djangoapps/content/__init__.py index 762719f3ef..8bf6ec2753 100644 --- a/openedx/core/djangoapps/content/__init__.py +++ b/openedx/core/djangoapps/content/__init__.py @@ -2,3 +2,4 @@ Setup the signals on startup. """ import openedx.core.djangoapps.content.course_structures.signals +import openedx.core.djangoapps.content.block_structure.signals diff --git a/openedx/core/djangoapps/content/block_structure/__init__.py b/openedx/core/djangoapps/content/block_structure/__init__.py new file mode 100644 index 0000000000..3b81c1b750 --- /dev/null +++ b/openedx/core/djangoapps/content/block_structure/__init__.py @@ -0,0 +1,5 @@ +""" +This code exists in openedx/core/djangoapp because it needs access to django signaling mechanisms + +Most of the underlying functionality is implemented in openedx/core/lib/block_structure/ +""" diff --git a/openedx/core/djangoapps/content/block_structure/api.py b/openedx/core/djangoapps/content/block_structure/api.py new file mode 100644 index 0000000000..4d70fd234c --- /dev/null +++ b/openedx/core/djangoapps/content/block_structure/api.py @@ -0,0 +1,58 @@ +""" +Higher order functions built on the BlockStructureManager to interact with a django cache. +""" +from django.core.cache import cache +from openedx.core.lib.block_structure.manager import BlockStructureManager +from xmodule.modulestore.django import modulestore + + +def get_course_in_cache(course_key): + """ + A higher order function implemented on top of the + block_structure.get_collected function that returns the block + structure in the cache for the given course_key. + + Returns: + BlockStructureBlockData - The collected block structure, + starting at root_block_usage_key. + """ + return get_block_structure_manager(course_key).get_collected() + + +def update_course_in_cache(course_key): + """ + A higher order function implemented on top of the + block_structure.updated_collected function that updates the block + structure in the cache for the given course_key. + """ + return get_block_structure_manager(course_key).update_collected() + + +def clear_course_from_cache(course_key): + """ + A higher order function implemented on top of the + block_structure.clear_block_cache function that clears the block + structure from the cache for the given course_key. + + Note: See Note in get_course_blocks. Even after MA-1604 is + implemented, this implementation should still be valid since the + entire block structure of the course is cached, even though + arbitrary access to an intermediate block will be supported. + """ + get_block_structure_manager(course_key).clear() + + +def get_block_structure_manager(course_key): + """ + Returns the manager for managing Block Structures for the given course. + """ + store = modulestore() + course_usage_key = store.make_course_usage_key(course_key) + return BlockStructureManager(course_usage_key, store, get_cache()) + + +def get_cache(): + """ + Returns the storage for caching Block Structures. + """ + return cache diff --git a/lms/djangoapps/course_blocks/signals.py b/openedx/core/djangoapps/content/block_structure/signals.py similarity index 100% rename from lms/djangoapps/course_blocks/signals.py rename to openedx/core/djangoapps/content/block_structure/signals.py diff --git a/lms/djangoapps/course_blocks/tasks.py b/openedx/core/djangoapps/content/block_structure/tasks.py similarity index 86% rename from lms/djangoapps/course_blocks/tasks.py rename to openedx/core/djangoapps/content/block_structure/tasks.py index d86fdf5243..1ec5ec23ed 100644 --- a/lms/djangoapps/course_blocks/tasks.py +++ b/openedx/core/djangoapps/content/block_structure/tasks.py @@ -5,13 +5,12 @@ import logging from celery.task import task from opaque_keys.edx.keys import CourseKey -from . import api - +from openedx.core.djangoapps.content.block_structure import api log = logging.getLogger('edx.celery.task') -@task() +@task def update_course_in_cache(course_key): """ Updates the course blocks (in the database) for the specified course. diff --git a/openedx/core/djangoapps/content/block_structure/tests/__init__.py b/openedx/core/djangoapps/content/block_structure/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/djangoapps/course_blocks/tests/helpers.py b/openedx/core/djangoapps/content/block_structure/tests/helpers.py similarity index 91% rename from lms/djangoapps/course_blocks/tests/helpers.py rename to openedx/core/djangoapps/content/block_structure/tests/helpers.py index 820b93986b..34b6f4f809 100644 --- a/lms/djangoapps/course_blocks/tests/helpers.py +++ b/openedx/core/djangoapps/content/block_structure/tests/helpers.py @@ -4,7 +4,7 @@ Helpers for Course Blocks tests. from openedx.core.lib.block_structure.cache import BlockStructureCache from openedx.core.lib.block_structure.transformer_registry import TransformerRegistry -from ..api import _get_cache +from ..api import get_cache class EnableTransformerRegistryMixin(object): @@ -30,4 +30,4 @@ def is_course_in_block_structure_cache(course_key, store): Returns whether the given course is in the Block Structure cache. """ course_usage_key = store.make_course_usage_key(course_key) - return BlockStructureCache(_get_cache()).get(course_usage_key) is not None + return BlockStructureCache(get_cache()).get(course_usage_key) is not None diff --git a/lms/djangoapps/course_blocks/tests/test_signals.py b/openedx/core/djangoapps/content/block_structure/tests/test_signals.py similarity index 57% rename from lms/djangoapps/course_blocks/tests/test_signals.py rename to openedx/core/djangoapps/content/block_structure/tests/test_signals.py index 9887087024..b9003ef331 100644 --- a/lms/djangoapps/course_blocks/tests/test_signals.py +++ b/openedx/core/djangoapps/content/block_structure/tests/test_signals.py @@ -6,8 +6,7 @@ from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory -from ..api import get_course_blocks, _get_block_structure_manager -from ..transformers.visibility import VisibilityTransformer +from ..api import get_block_structure_manager from .helpers import is_course_in_block_structure_cache, EnableTransformerRegistryMixin @@ -22,26 +21,30 @@ class CourseBlocksSignalTest(EnableTransformerRegistryMixin, ModuleStoreTestCase self.course = CourseFactory.create() self.course_usage_key = self.store.make_course_usage_key(self.course.id) - def test_course_publish(self): - # course is not visible to staff only - self.assertFalse(self.course.visible_to_staff_only) - orig_block_structure = get_course_blocks(self.user, self.course_usage_key) - self.assertFalse( - VisibilityTransformer.get_visible_to_staff_only(orig_block_structure, self.course_usage_key) + def test_course_update(self): + test_display_name = "Lightsabers 101" + + # Course exists in cache initially + bs_manager = get_block_structure_manager(self.course.id) + orig_block_structure = bs_manager.get_collected() + self.assertTrue(is_course_in_block_structure_cache(self.course.id, self.store)) + self.assertNotEqual( + test_display_name, + orig_block_structure.get_xblock_field(self.course_usage_key, 'display_name') ) - # course becomes visible to staff only - self.course.visible_to_staff_only = True + self.course.display_name = test_display_name self.store.update_item(self.course, self.user.id) - updated_block_structure = get_course_blocks(self.user, self.course_usage_key) - self.assertTrue( - VisibilityTransformer.get_visible_to_staff_only(updated_block_structure, self.course_usage_key) + # Cached version of course has been updated + updated_block_structure = bs_manager.get_collected() + self.assertEqual( + test_display_name, + updated_block_structure.get_xblock_field(self.course_usage_key, 'display_name') ) def test_course_delete(self): - get_course_blocks(self.user, self.course_usage_key) - bs_manager = _get_block_structure_manager(self.course.id) + bs_manager = get_block_structure_manager(self.course.id) self.assertIsNotNone(bs_manager.get_collected()) self.assertTrue(is_course_in_block_structure_cache(self.course.id, self.store)) diff --git a/openedx/core/djangoapps/content/course_structures/tasks.py b/openedx/core/djangoapps/content/course_structures/tasks.py index f206eb1b5e..aa56ff01cf 100644 --- a/openedx/core/djangoapps/content/course_structures/tasks.py +++ b/openedx/core/djangoapps/content/course_structures/tasks.py @@ -96,13 +96,3 @@ def update_course_structure(course_key): structure_model.structure_json = structure_json structure_model.discussion_id_map_json = discussion_id_map_json structure_model.save() - - # TODO (TNL-4630) For temporary hotfix to delete the block_structure cache. - # Should be moved to proper location. - from django.core.cache import cache - from openedx.core.lib.block_structure.manager import BlockStructureManager - - store = modulestore() - course_usage_key = store.make_course_usage_key(course_key) - block_structure_manager = BlockStructureManager(course_usage_key, store, cache) - block_structure_manager.clear() diff --git a/openedx/core/djangoapps/credit/email_utils.py b/openedx/core/djangoapps/credit/email_utils.py index 263cee2fce..3cdef8955c 100644 --- a/openedx/core/djangoapps/credit/email_utils.py +++ b/openedx/core/djangoapps/credit/email_utils.py @@ -73,7 +73,7 @@ def send_credit_notifications(username, course_key): providers_string = make_providers_strings(providers_names) context = { 'full_name': user.get_full_name(), - 'platform_name': settings.PLATFORM_NAME, + 'platform_name': theming_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME), 'course_name': course_display_name, 'branded_logo': logo_image_id, 'dashboard_link': dashboard_link, diff --git a/openedx/core/djangoapps/models/tests/__init__.py b/openedx/core/djangoapps/models/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openedx/core/djangoapps/programs/tasks/v1/tasks.py b/openedx/core/djangoapps/programs/tasks/v1/tasks.py index 8e8227cfde..b80a8111b5 100644 --- a/openedx/core/djangoapps/programs/tasks/v1/tasks.py +++ b/openedx/core/djangoapps/programs/tasks/v1/tasks.py @@ -10,7 +10,7 @@ from edx_rest_api_client.client import EdxRestApiClient from openedx.core.djangoapps.credentials.models import CredentialsApiConfig from openedx.core.djangoapps.credentials.utils import get_user_credentials from openedx.core.djangoapps.programs.models import ProgramsApiConfig -from openedx.core.djangoapps.programs.utils import get_completed_courses +from openedx.core.djangoapps.programs.utils import ProgramProgressMeter from openedx.core.lib.token_utils import get_id_token @@ -35,21 +35,20 @@ def get_api_client(api_config, student): return EdxRestApiClient(api_config.internal_api_url, jwt=id_token) -def get_completed_programs(client, course_certificates): +def get_completed_programs(student): """ Given a set of completed courses, determine which programs are completed. Args: - client: - programs API client (EdxRestApiClient) - course_certificates: - iterable of dicts with structure {'course_id': course_key, 'mode': cert_type} + student (User): Representing the student whose completed programs to check for. Returns: list of program ids """ - return client.programs.complete.post({'completed_courses': course_certificates})['program_ids'] + meter = ProgramProgressMeter(student) + + return meter.completed_programs def get_awarded_certificate_programs(student): @@ -147,29 +146,9 @@ def award_program_certificates(self, username): # Don't retry for this case - just conclude the task. return - # Fetch the set of all course runs for which the user has earned a - # certificate. - course_certs = get_completed_courses(student) - if not course_certs: - # Highly unlikely, since at present the only trigger for this task - # is the earning of a new course certificate. However, it could be - # that the transaction in which a course certificate was awarded - # was subsequently rolled back, which could lead to an empty result - # here, so we'll at least log that this happened before exiting. - # - # If this task is ever updated to support revocation of program - # certs, this branch should be removed, since it could make sense - # in that case to call this task for a user without any (valid) - # course certs. - LOGGER.warning('Task award_program_certificates was called for user %s with no completed courses', username) - return - - # Invoke the Programs API completion check endpoint to identify any - # programs that are satisfied by these course completions. - programs_client = get_api_client(config, student) - program_ids = get_completed_programs(programs_client, course_certs) + program_ids = get_completed_programs(student) if not program_ids: - # Again, no reason to continue beyond this point unless/until this + # No reason to continue beyond this point unless/until this # task gets updated to support revocation of program certs. LOGGER.info('Task award_program_certificates was called for user %s with no completed programs', username) return diff --git a/openedx/core/djangoapps/programs/tasks/v1/tests/test_tasks.py b/openedx/core/djangoapps/programs/tasks/v1/tests/test_tasks.py index e3bafd27e8..cbd75a13da 100644 --- a/openedx/core/djangoapps/programs/tasks/v1/tests/test_tasks.py +++ b/openedx/core/djangoapps/programs/tasks/v1/tests/test_tasks.py @@ -1,26 +1,31 @@ """ Tests for programs celery tasks. """ - -import ddt -import httpretty import json -import mock import unittest from celery.exceptions import MaxRetriesExceededError +import ddt from django.conf import settings +from django.core.cache import cache from django.test import override_settings, TestCase from edx_rest_api_client.client import EdxRestApiClient from edx_oauth2_provider.tests.factories import ClientFactory +import httpretty +import mock +from provider.constants import CONFIDENTIAL +from lms.djangoapps.certificates.api import MODES from openedx.core.djangoapps.credentials.tests.mixins import CredentialsApiConfigMixin +from openedx.core.djangoapps.programs.tests import factories from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin from openedx.core.djangoapps.programs.tasks.v1 import tasks +from openedx.core.djangolib.testing.utils import CacheIsolationTestCase from student.tests.factories import UserFactory TASKS_MODULE = 'openedx.core.djangoapps.programs.tasks.v1.tasks' +UTILS_MODULE = 'openedx.core.djangoapps.programs.utils' @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @@ -48,31 +53,65 @@ class GetApiClientTestCase(TestCase, ProgramsApiConfigMixin): self.assertEqual(api_client._store['session'].auth.token, 'test-token') # pylint: disable=protected-access +@httpretty.activate @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') -class GetCompletedProgramsTestCase(TestCase): +class GetCompletedProgramsTestCase(ProgramsApiConfigMixin, CacheIsolationTestCase): """ Test the get_completed_programs function """ + ENABLED_CACHES = ['default'] - @httpretty.activate - def test_get_completed_programs(self): + def setUp(self): + super(GetCompletedProgramsTestCase, self).setUp() + + self.user = UserFactory() + self.programs_config = self.create_programs_config(cache_ttl=5) + + ClientFactory(name=self.programs_config.OAUTH2_CLIENT_NAME, client_type=CONFIDENTIAL) + + cache.clear() + + def _mock_programs_api(self, data): + """Helper for mocking out Programs API URLs.""" + self.assertTrue(httpretty.is_enabled(), msg='httpretty must be enabled to mock Programs API calls.') + + url = self.programs_config.internal_api_url.strip('/') + '/programs/' + body = json.dumps({'results': data}) + + httpretty.register_uri(httpretty.GET, url, body=body, content_type='application/json') + + def _assert_num_requests(self, count): + """DRY helper for verifying request counts.""" + self.assertEqual(len(httpretty.httpretty.latest_requests), count) + + @mock.patch(UTILS_MODULE + '.get_completed_courses') + def test_get_completed_programs(self, mock_get_completed_courses): """ - Ensure the correct API call gets made + Verify that completed programs are found, using the cache when possible. """ - test_client = EdxRestApiClient('http://test-server', jwt='test-token') - httpretty.register_uri( - httpretty.POST, - 'http://test-server/programs/complete/', - body='{"program_ids": [1, 2, 3]}', - content_type='application/json', - ) - payload = [ - {'course_id': 'test-course-1', 'mode': 'verified'}, - {'course_id': 'test-course-2', 'mode': 'prof-ed'}, + course_id = 'org/course/run' + data = [ + factories.Program( + organizations=[factories.Organization()], + course_codes=[ + factories.CourseCode(run_modes=[ + factories.RunMode(course_key=course_id), + ]), + ] + ), ] - result = tasks.get_completed_programs(test_client, payload) - self.assertEqual(json.loads(httpretty.last_request().body), {'completed_courses': payload}) - self.assertEqual(result, [1, 2, 3]) + self._mock_programs_api(data) + + mock_get_completed_courses.return_value = [ + {'course_id': course_id, 'mode': MODES.verified} + ] + + for _ in range(2): + result = tasks.get_completed_programs(self.user) + self.assertEqual(result, [data[0]['id']]) + + # Verify that only one request to programs was made (i.e., the cache was hit). + self._assert_num_requests(1) @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @@ -150,7 +189,6 @@ class AwardProgramCertificateTestCase(TestCase): @mock.patch(TASKS_MODULE + '.award_program_certificate') @mock.patch(TASKS_MODULE + '.get_awarded_certificate_programs') @mock.patch(TASKS_MODULE + '.get_completed_programs') -@mock.patch(TASKS_MODULE + '.get_completed_courses') @override_settings(CREDENTIALS_SERVICE_USERNAME='test-service-username') class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, CredentialsApiConfigMixin): """ @@ -169,7 +207,6 @@ class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, Credent def test_completion_check( self, - mock_get_completed_courses, mock_get_completed_programs, mock_get_awarded_certificate_programs, # pylint: disable=unused-argument mock_award_program_certificate, # pylint: disable=unused-argument @@ -178,18 +215,8 @@ class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, Credent Checks that the Programs API is used correctly to determine completed programs. """ - completed_courses = [ - {'course_id': 'course-1', 'type': 'verified'}, - {'course_id': 'course-2', 'type': 'prof-ed'}, - ] - mock_get_completed_courses.return_value = completed_courses - tasks.award_program_certificates.delay(self.student.username).get() - - self.assertEqual( - mock_get_completed_programs.call_args[0][1], - completed_courses - ) + mock_get_completed_programs.assert_called_once_with(self.student) @ddt.data( ([1], [2, 3]), @@ -201,7 +228,6 @@ class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, Credent self, already_awarded_program_ids, expected_awarded_program_ids, - mock_get_completed_courses, # pylint: disable=unused-argument mock_get_completed_programs, mock_get_awarded_certificate_programs, mock_award_program_certificate, @@ -252,30 +278,8 @@ class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, Credent for mock_helper in mock_helpers: self.assertFalse(mock_helper.called) - def test_abort_if_no_completed_courses( - self, - mock_get_completed_courses, - mock_get_completed_programs, - mock_get_awarded_certificate_programs, - mock_award_program_certificate, - ): - """ - Checks that the task will be aborted without further action if the - student does not have any completed courses, but that a warning is - logged. - """ - mock_get_completed_courses.return_value = [] - with mock.patch(TASKS_MODULE + '.LOGGER.warning') as mock_warning: - tasks.award_program_certificates.delay(self.student.username).get() - self.assertTrue(mock_warning.called) - self.assertTrue(mock_get_completed_courses.called) - self.assertFalse(mock_get_completed_programs.called) - self.assertFalse(mock_get_awarded_certificate_programs.called) - self.assertFalse(mock_award_program_certificate.called) - def test_abort_if_no_completed_programs( self, - mock_get_completed_courses, mock_get_completed_programs, mock_get_awarded_certificate_programs, mock_award_program_certificate, @@ -286,7 +290,6 @@ class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, Credent """ mock_get_completed_programs.return_value = [] tasks.award_program_certificates.delay(self.student.username).get() - self.assertTrue(mock_get_completed_courses.called) self.assertTrue(mock_get_completed_programs.called) self.assertFalse(mock_get_awarded_certificate_programs.called) self.assertFalse(mock_award_program_certificate.called) @@ -312,7 +315,6 @@ class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, Credent def test_continue_awarding_certs_if_error( self, - mock_get_completed_courses, # pylint: disable=unused-argument mock_get_completed_programs, mock_get_awarded_certificate_programs, mock_award_program_certificate, @@ -336,24 +338,8 @@ class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, Credent mock_info.assert_any_call(mock.ANY, 1, self.student.username) mock_info.assert_any_call(mock.ANY, 2, self.student.username) - def test_retry_on_certificates_api_errors( - self, - mock_get_completed_courses, - *_mock_helpers # pylint: disable=unused-argument - ): - """ - Ensures that any otherwise-unhandled errors that arise while trying - to get existing course certificates (e.g. network issues or other - transient API errors) will cause the task to be failed and queued for - retry. - """ - mock_get_completed_courses.side_effect = self._make_side_effect([Exception('boom'), None]) - tasks.award_program_certificates.delay(self.student.username).get() - self.assertEqual(mock_get_completed_courses.call_count, 2) - def test_retry_on_programs_api_errors( self, - mock_get_completed_courses, # pylint: disable=unused-argument mock_get_completed_programs, *_mock_helpers # pylint: disable=unused-argument ): @@ -369,7 +355,6 @@ class AwardProgramCertificatesTestCase(TestCase, ProgramsApiConfigMixin, Credent def test_retry_on_credentials_api_errors( self, - mock_get_completed_courses, # pylint: disable=unused-argument mock_get_completed_programs, mock_get_awarded_certificate_programs, mock_award_program_certificate, diff --git a/openedx/core/djangoapps/programs/tests/test_utils.py b/openedx/core/djangoapps/programs/tests/test_utils.py index acaa5d5115..dee459c686 100644 --- a/openedx/core/djangoapps/programs/tests/test_utils.py +++ b/openedx/core/djangoapps/programs/tests/test_utils.py @@ -284,8 +284,9 @@ class GetCompletedCoursesTestCase(TestCase): ]) -@skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @attr('shard_2') +@httpretty.activate +@skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): """Tests of the program progress utility class.""" def setUp(self): @@ -307,7 +308,8 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): def _create_enrollments(self, *course_ids): """Variadic helper used to create course enrollments.""" - return [CourseEnrollmentFactory(user=self.user, course_id=c) for c in course_ids] + for course_id in course_ids: + CourseEnrollmentFactory(user=self.user, course_id=course_id) def _assert_progress(self, meter, *progresses): """Variadic helper used to verify progress calculations.""" @@ -317,7 +319,6 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): """Construct a list containing the display names of the indicated course codes.""" return [program['course_codes'][cc]['display_name'] for cc in course_codes] - @httpretty.activate def test_no_enrollments(self): """Verify behavior when programs exist, but no relevant enrollments do.""" data = [ @@ -330,23 +331,23 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): ] self._mock_programs_api(data) - meter = utils.ProgramProgressMeter(self.user, []) + meter = utils.ProgramProgressMeter(self.user) self.assertEqual(meter.engaged_programs, []) self._assert_progress(meter) + self.assertEqual(meter.completed_programs, []) - @httpretty.activate def test_no_programs(self): """Verify behavior when enrollments exist, but no matching programs do.""" self._mock_programs_api([]) - enrollments = self._create_enrollments('org/course/run') - meter = utils.ProgramProgressMeter(self.user, enrollments) + self._create_enrollments('org/course/run') + meter = utils.ProgramProgressMeter(self.user) self.assertEqual(meter.engaged_programs, []) self._assert_progress(meter) + self.assertEqual(meter.completed_programs, []) - @httpretty.activate def test_single_program_engagement(self): """ Verify that correct program is returned when the user has a single enrollment @@ -371,8 +372,8 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): ] self._mock_programs_api(data) - enrollments = self._create_enrollments(course_id) - meter = utils.ProgramProgressMeter(self.user, enrollments) + self._create_enrollments(course_id) + meter = utils.ProgramProgressMeter(self.user) program = data[0] self.assertEqual(meter.engaged_programs, [program]) @@ -383,8 +384,8 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): in_progress=self._extract_names(program, 0) ) ) + self.assertEqual(meter.completed_programs, []) - @httpretty.activate def test_mutiple_program_engagement(self): """ Verify that correct programs are returned in the correct order when the user @@ -417,8 +418,8 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): ] self._mock_programs_api(data) - enrollments = self._create_enrollments(second_course_id, first_course_id) - meter = utils.ProgramProgressMeter(self.user, enrollments) + self._create_enrollments(second_course_id, first_course_id) + meter = utils.ProgramProgressMeter(self.user) programs = data[:2] self.assertEqual(meter.engaged_programs, programs) @@ -427,8 +428,8 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): factories.Progress(id=programs[0]['id'], in_progress=self._extract_names(programs[0], 0)), factories.Progress(id=programs[1]['id'], in_progress=self._extract_names(programs[1], 0)) ) + self.assertEqual(meter.completed_programs, []) - @httpretty.activate def test_shared_enrollment_engagement(self): """ Verify that correct programs are returned when the user has a single enrollment @@ -470,8 +471,8 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): self._mock_programs_api(data) # Enrollment for the shared course ID created last (most recently). - enrollments = self._create_enrollments(solo_course_id, shared_course_id) - meter = utils.ProgramProgressMeter(self.user, enrollments) + self._create_enrollments(solo_course_id, shared_course_id) + meter = utils.ProgramProgressMeter(self.user) programs = data[:3] self.assertEqual(meter.engaged_programs, programs) @@ -481,8 +482,8 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): factories.Progress(id=programs[1]['id'], in_progress=self._extract_names(programs[1], 0)), factories.Progress(id=programs[2]['id'], in_progress=self._extract_names(programs[2], 0)) ) + self.assertEqual(meter.completed_programs, []) - @httpretty.activate @mock.patch(UTILS_MODULE + '.get_completed_courses') def test_simulate_progress(self, mock_get_completed_courses): """Simulate the entirety of a user's progress through a program.""" @@ -499,16 +500,23 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): ]), ] ), + factories.Program( + organizations=[factories.Organization()], + course_codes=[ + factories.CourseCode(run_modes=[factories.RunMode()]), + ] + ), ] self._mock_programs_api(data) # No enrollments, no program engaged. - meter = utils.ProgramProgressMeter(self.user, []) + meter = utils.ProgramProgressMeter(self.user) self._assert_progress(meter) + self.assertEqual(meter.completed_programs, []) # One enrollment, program engaged. - enrollments = self._create_enrollments(first_course_id) - meter = utils.ProgramProgressMeter(self.user, enrollments) + self._create_enrollments(first_course_id) + meter = utils.ProgramProgressMeter(self.user) program, program_id = data[0], data[0]['id'] self._assert_progress( meter, @@ -518,10 +526,11 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): not_started=self._extract_names(program, 1) ) ) + self.assertEqual(meter.completed_programs, []) # Two enrollments, program in progress. - enrollments += self._create_enrollments(second_course_id) - meter = utils.ProgramProgressMeter(self.user, enrollments) + self._create_enrollments(second_course_id) + meter = utils.ProgramProgressMeter(self.user) self._assert_progress( meter, factories.Progress( @@ -529,11 +538,13 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): in_progress=self._extract_names(program, 0, 1) ) ) + self.assertEqual(meter.completed_programs, []) # One valid certificate earned, one course code complete. mock_get_completed_courses.return_value = [ {'course_id': first_course_id, 'mode': MODES.verified}, ] + meter = utils.ProgramProgressMeter(self.user) self._assert_progress( meter, factories.Progress( @@ -542,12 +553,14 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): in_progress=self._extract_names(program, 1) ) ) + self.assertEqual(meter.completed_programs, []) # Invalid certificate earned, still one course code to complete. mock_get_completed_courses.return_value = [ {'course_id': first_course_id, 'mode': MODES.verified}, {'course_id': second_course_id, 'mode': MODES.honor}, ] + meter = utils.ProgramProgressMeter(self.user) self._assert_progress( meter, factories.Progress( @@ -556,12 +569,14 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): in_progress=self._extract_names(program, 1) ) ) + self.assertEqual(meter.completed_programs, []) # Second valid certificate obtained, all course codes complete. mock_get_completed_courses.return_value = [ {'course_id': first_course_id, 'mode': MODES.verified}, {'course_id': second_course_id, 'mode': MODES.verified}, ] + meter = utils.ProgramProgressMeter(self.user) self._assert_progress( meter, factories.Progress( @@ -569,12 +584,12 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): completed=self._extract_names(program, 0, 1) ) ) + self.assertEqual(meter.completed_programs, [program_id]) - @httpretty.activate @mock.patch(UTILS_MODULE + '.get_completed_courses') def test_nonstandard_run_mode_completion(self, mock_get_completed_courses): """ - A valid run mode isn't necessarily verified. Verify that the program can + A valid run mode isn't necessarily verified. Verify that a program can still be completed when this is the case. """ course_id = 'org/course/run' @@ -587,24 +602,70 @@ class TestProgramProgressMeter(ProgramsApiConfigMixin, TestCase): course_key=course_id, mode_slug=MODES.honor ), + factories.RunMode(), ]), ] ), + factories.Program( + organizations=[factories.Organization()], + course_codes=[ + factories.CourseCode(run_modes=[factories.RunMode()]), + ] + ), ] self._mock_programs_api(data) - enrollments = self._create_enrollments(course_id) - meter = utils.ProgramProgressMeter(self.user, enrollments) - + self._create_enrollments(course_id) mock_get_completed_courses.return_value = [ {'course_id': course_id, 'mode': MODES.honor}, ] + meter = utils.ProgramProgressMeter(self.user) - program = data[0] + program, program_id = data[0], data[0]['id'] self._assert_progress( meter, - factories.Progress(id=program['id'], completed=self._extract_names(program, 0)) + factories.Progress(id=program_id, completed=self._extract_names(program, 0)) ) + self.assertEqual(meter.completed_programs, [program_id]) + + @mock.patch(UTILS_MODULE + '.get_completed_courses') + def test_completed_programs(self, mock_get_completed_courses): + """Verify that completed programs are correctly identified.""" + program_count, course_code_count, run_mode_count = 3, 2, 2 + data = [ + factories.Program( + organizations=[factories.Organization()], + course_codes=[ + factories.CourseCode(run_modes=[factories.RunMode() for _ in range(run_mode_count)]) + for _ in range(course_code_count) + ] + ) + for _ in range(program_count) + ] + self._mock_programs_api(data) + + program_ids = [] + course_ids = [] + for program in data: + program_ids.append(program['id']) + + for course_code in program['course_codes']: + for run_mode in course_code['run_modes']: + course_ids.append(run_mode['course_key']) + + # Verify that no programs are complete. + meter = utils.ProgramProgressMeter(self.user) + self.assertEqual(meter.completed_programs, []) + + # "Complete" all programs. + self._create_enrollments(*course_ids) + mock_get_completed_courses.return_value = [ + {'course_id': course_id, 'mode': MODES.verified} for course_id in course_ids + ] + + # Verify that all programs are complete. + meter = utils.ProgramProgressMeter(self.user) + self.assertEqual(meter.completed_programs, program_ids) @ddt.ddt diff --git a/openedx/core/djangoapps/programs/utils.py b/openedx/core/djangoapps/programs/utils.py index cf58feeecc..6ca9a842df 100644 --- a/openedx/core/djangoapps/programs/utils.py +++ b/openedx/core/djangoapps/programs/utils.py @@ -5,6 +5,7 @@ import logging from django.core.urlresolvers import reverse from django.utils import timezone +from django.utils.functional import cached_property from opaque_keys.edx.keys import CourseKey import pytz @@ -170,29 +171,27 @@ class ProgramProgressMeter(object): Arguments: user (User): The user for which to find programs. - enrollments (list): The user's active enrollments. """ - def __init__(self, user, enrollments): + def __init__(self, user): self.user = user + self.course_ids = None - enrollments = sorted(enrollments, key=lambda e: e.created, reverse=True) - # enrollment.course_id is really a course key ಠ_ಠ - self.course_ids = [unicode(e.course_id) for e in enrollments] + self.programs = get_programs(self.user) + self.course_certs = get_completed_courses(self.user) - self.engaged_programs = self._find_engaged_programs(self.user) - self.course_certs = None - - def _find_engaged_programs(self, user): + @cached_property + def engaged_programs(self): """Derive a list of programs in which the given user is engaged. - Arguments: - user (User): The user for which to find engaged programs. - Returns: list of program dicts, ordered by most recent enrollment. """ - programs = get_programs(user) - flattened = flatten_programs(programs, self.course_ids) + enrollments = CourseEnrollment.enrollments_for_user(self.user) + enrollments = sorted(enrollments, key=lambda e: e.created, reverse=True) + # enrollment.course_id is really a course key ಠ_ಠ + self.course_ids = [unicode(e.course_id) for e in enrollments] + + flattened = flatten_programs(self.programs, self.course_ids) engaged_programs = [] for course_id in self.course_ids: @@ -210,8 +209,6 @@ class ProgramProgressMeter(object): list of dict, each containing information about a user's progress towards completing a program. """ - self.course_certs = get_completed_courses(self.user) - progress = [] for program in self.engaged_programs: completed, in_progress, not_started = [], [], [] @@ -219,9 +216,9 @@ class ProgramProgressMeter(object): for course_code in program['course_codes']: name = course_code['display_name'] - if self._is_complete(course_code): + if self._is_course_code_complete(course_code): completed.append(name) - elif self._is_in_progress(course_code): + elif self._is_course_code_in_progress(course_code): in_progress.append(name) else: not_started.append(name) @@ -235,11 +232,33 @@ class ProgramProgressMeter(object): return progress - def _is_complete(self, course_code): + @property + def completed_programs(self): + """Identify programs completed by the student. + + Returns: + list of int, each the ID of a completed program. + """ + return [program['id'] for program in self.programs if self._is_program_complete(program)] + + def _is_program_complete(self, program): + """Check if a user has completed a program. + + A program is completed if the user has completed all nested course codes. + + Arguments: + program (dict): Representing the program whose completion to assess. + + Returns: + bool, whether the program is complete. + """ + return all(self._is_course_code_complete(course_code) for course_code in program['course_codes']) + + def _is_course_code_complete(self, course_code): """Check if a user has completed a course code. - A course code qualifies as completed if the user has earned a - certificate in the right mode for any nested run. + A course code is completed if the user has earned a certificate + in the right mode for any nested run. Arguments: course_code (dict): Containing nested run modes. @@ -247,12 +266,9 @@ class ProgramProgressMeter(object): Returns: bool, whether the course code is complete. """ - return any([ - self._parse(run_mode) in self.course_certs - for run_mode in course_code['run_modes'] - ]) + return any(self._parse(run_mode) in self.course_certs for run_mode in course_code['run_modes']) - def _is_in_progress(self, course_code): + def _is_course_code_in_progress(self, course_code): """Check if a user is in the process of completing a course code. A user is in the process of completing a course code if they're @@ -264,10 +280,7 @@ class ProgramProgressMeter(object): Returns: bool, whether the course code is in progress. """ - return any([ - run_mode['course_key'] in self.course_ids - for run_mode in course_code['run_modes'] - ]) + return any(run_mode['course_key'] in self.course_ids for run_mode in course_code['run_modes']) def _parse(self, run_mode): """Modify the structure of a run mode dict. diff --git a/openedx/core/djangoapps/user_api/management/commands/email_opt_in_list.py b/openedx/core/djangoapps/user_api/management/commands/email_opt_in_list.py index 61c2d3e483..86d8a6bd7b 100644 --- a/openedx/core/djangoapps/user_api/management/commands/email_opt_in_list.py +++ b/openedx/core/djangoapps/user_api/management/commands/email_opt_in_list.py @@ -237,7 +237,9 @@ class Command(BaseCommand): email, full_name, course_id, is_opted_in, pref_set_datetime = row writer.writerow({ "email": email.encode('utf-8'), - "full_name": full_name.encode('utf-8'), + # There should not be a case where users are without full_names. We only need this safe check because + # of ECOM-1995. + "full_name": full_name.encode('utf-8') if full_name else '', "course_id": course_id.encode('utf-8'), "is_opted_in_for_email": is_opted_in if is_opted_in else "True", "preference_set_datetime": pref_set_datetime if pref_set_datetime else self.DEFAULT_DATETIME_STR, diff --git a/openedx/core/djangoapps/user_api/management/tests/test_email_opt_in_list.py b/openedx/core/djangoapps/user_api/management/tests/test_email_opt_in_list.py index ca8f54ea42..ab6b71c5f1 100644 --- a/openedx/core/djangoapps/user_api/management/tests/test_email_opt_in_list.py +++ b/openedx/core/djangoapps/user_api/management/tests/test_email_opt_in_list.py @@ -10,6 +10,7 @@ from unittest import skipUnless import ddt from django.conf import settings +from django.contrib.auth.models import User from django.core.management.base import CommandError from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase @@ -257,6 +258,24 @@ class EmailOptInListTest(ModuleStoreTestCase): with self.assertRaisesRegexp(CommandError, "^File already exists"): email_opt_in_list.Command().handle(temp_file.name, self.TEST_ORG) + def test_no_user_profile(self): + """ + Tests that command does not break if a user has no profile. + """ + self._create_courses_and_enrollments((self.TEST_ORG, True)) + self._set_opt_in_pref(self.user, self.TEST_ORG, True) + + # Remove the user profile, and re-fetch user + self.assertTrue(hasattr(self.user, 'profile')) + self.user.profile.delete() + user = User.objects.get(id=self.user.id) + + # Test that user do not have profile + self.assertFalse(hasattr(user, 'profile')) + + output = self._run_command(self.TEST_ORG) + self._assert_output(output, (user, self.courses[0].id, True)) + def _create_courses_and_enrollments(self, *args): """Create courses and enrollments. @@ -393,7 +412,11 @@ class EmailOptInListTest(ModuleStoreTestCase): for user, course_id, opt_in_pref in args: self.assertIn({ "email": user.email.encode('utf-8'), - "full_name": user.profile.name.encode('utf-8'), + "full_name": ( + user.profile.name.encode('utf-8') + if hasattr(user, 'profile') + else '' + ), "course_id": unicode(course_id).encode('utf-8'), "is_opted_in_for_email": unicode(opt_in_pref), "preference_set_datetime": ( diff --git a/openedx/core/djangoapps/user_api/views.py b/openedx/core/djangoapps/user_api/views.py index 63bd3518a8..1328863772 100644 --- a/openedx/core/djangoapps/user_api/views.py +++ b/openedx/core/djangoapps/user_api/views.py @@ -77,7 +77,7 @@ class LoginSessionView(APIView): # Translators: These instructions appear on the login form, immediately # below a field meant to hold the user's email address. email_instructions = _("The email address you used to register with {platform_name}").format( - platform_name=settings.PLATFORM_NAME + platform_name=get_themed_value('PLATFORM_NAME', settings.PLATFORM_NAME) ) form_desc.add_field( @@ -586,7 +586,7 @@ class RegistrationView(APIView): # Translators: This phrase appears above a field on the registration form # meant to hold the user's reasons for registering with edX. goals_label = _(u"Tell us why you're interested in {platform_name}").format( - platform_name=settings.PLATFORM_NAME + platform_name=get_themed_value("PLATFORM_NAME", settings.PLATFORM_NAME) ) form_desc.add_field( @@ -920,7 +920,7 @@ class PasswordResetView(APIView): # Translators: These instructions appear on the password reset form, # immediately below a field meant to hold the user's email address. email_instructions = _(u"The email address you used to register with {platform_name}").format( - platform_name=settings.PLATFORM_NAME + platform_name=get_themed_value('PLATFORM_NAME', settings.PLATFORM_NAME) ) form_desc.add_field( diff --git a/openedx/core/lib/celery/__init__.py b/openedx/core/lib/celery/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/openedx/core/lib/celery/routers.py b/openedx/core/lib/celery/routers.py new file mode 100644 index 0000000000..c8f6b4196b --- /dev/null +++ b/openedx/core/lib/celery/routers.py @@ -0,0 +1,51 @@ +""" +Custom routers used by both lms and cms when routing tasks to worker queues. + +For more, see http://celery.readthedocs.io/en/latest/userguide/routing.html#routers +""" +from abc import ABCMeta, abstractproperty +from django.conf import settings + + +class AlternateEnvironmentRouter(object): + """ + A custom Router class for use in routing celery tasks to non-default queues. + """ + # this is an abstract base class, implementations must provide alternate_env_tasks + __metaclass__ = ABCMeta + + @abstractproperty + def alternate_env_tasks(self): + """ + Defines the task -> alternate worker environment queue to be used when routing. + + Subclasses must override this property with their own specific mappings. + """ + return {} + + def route_for_task(self, task, args=None, kwargs=None): # pylint: disable=unused-argument + """ + Celery-defined method allowing for custom routing logic. + + If None is returned from this method, default routing logic is used. + """ + alternate_env = self.alternate_env_tasks.get(task, None) + if alternate_env: + return self.ensure_queue_env(alternate_env) + return None + + def ensure_queue_env(self, desired_env): + """ + Helper method to get the desired type of queue. + + If no such queue is defined, default routing logic is used. + """ + queues = getattr(settings, 'CELERY_QUEUES', None) + return next( + ( + queue + for queue in queues + if '.{}.'.format(desired_env) in queue + ), + None + ) diff --git a/openedx/core/lib/edx_api_utils.py b/openedx/core/lib/edx_api_utils.py index b9f607aa1a..f9aff9c410 100644 --- a/openedx/core/lib/edx_api_utils.py +++ b/openedx/core/lib/edx_api_utils.py @@ -11,7 +11,8 @@ from openedx.core.lib.token_utils import get_id_token log = logging.getLogger(__name__) -def get_edx_api_data(api_config, user, resource, resource_id=None, querystring=None, cache_key=None): +def get_edx_api_data(api_config, user, resource, + api=None, resource_id=None, querystring=None, cache_key=None): """GET data from an edX REST API. DRY utility for handling caching and pagination. @@ -22,6 +23,7 @@ def get_edx_api_data(api_config, user, resource, resource_id=None, querystring=N resource (str): Name of the API resource being requested. Keyword Arguments: + api (APIClient): API client to use for requesting data. resource_id (int or str): Identifies a specific resource to be retrieved. querystring (dict): Optional query string parameters. cache_key (str): Where to cache retrieved data. The cache will be ignored if this is omitted @@ -45,8 +47,9 @@ def get_edx_api_data(api_config, user, resource, resource_id=None, querystring=N return cached try: - jwt = get_id_token(user, api_config.OAUTH2_CLIENT_NAME) - api = EdxRestApiClient(api_config.internal_api_url, jwt=jwt) + if not api: + jwt = get_id_token(user, api_config.OAUTH2_CLIENT_NAME) + api = EdxRestApiClient(api_config.internal_api_url, jwt=jwt) except: # pylint: disable=bare-except log.exception('Failed to initialize the %s API client.', api_config.API_NAME) return no_data diff --git a/openedx/core/lib/tests/test_edx_api_utils.py b/openedx/core/lib/tests/test_edx_api_utils.py index 8f5f1cee5c..df050ca1b4 100644 --- a/openedx/core/lib/tests/test_edx_api_utils.py +++ b/openedx/core/lib/tests/test_edx_api_utils.py @@ -3,12 +3,14 @@ import json import unittest from django.core.cache import cache +from django.test.utils import override_settings import httpretty import mock from nose.plugins.attrib import attr from edx_oauth2_provider.tests.factories import ClientFactory from provider.constants import CONFIDENTIAL +from openedx.core.djangoapps.commerce.utils import ecommerce_api_client from openedx.core.djangoapps.programs.models import ProgramsApiConfig from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin from openedx.core.djangolib.testing.utils import CacheIsolationTestCase @@ -17,6 +19,8 @@ from student.tests.factories import UserFactory UTILITY_MODULE = 'openedx.core.lib.edx_api_utils' +TEST_API_URL = 'http://www-internal.example.com/api' +TEST_API_SIGNING_KEY = 'edx' @attr('shard_2') @@ -195,3 +199,15 @@ class TestGetEdxApiData(ProgramsApiConfigMixin, CacheIsolationTestCase): self.assertTrue(mock_exception.called) self.assertEqual(actual, []) + + @override_settings(JWT_AUTH={'JWT_ISSUER': 'http://example.com/oauth', 'JWT_EXPIRATION': 30}, + ECOMMERCE_API_SIGNING_KEY=TEST_API_SIGNING_KEY, ECOMMERCE_API_URL=TEST_API_URL) + def test_client_passed(self): + """ Verify that when API client is passed edx_rest_api_client is not + used. + """ + program_config = self.create_programs_config() + api = ecommerce_api_client(self.user) + with mock.patch('openedx.core.lib.edx_api_utils.EdxRestApiClient.__init__') as mock_init: + get_edx_api_data(program_config, self.user, 'orders', api=api) + self.assertFalse(mock_init.called) diff --git a/pavelib/utils/envs.py b/pavelib/utils/envs.py index 4fa56bdf57..11c27dc1fb 100644 --- a/pavelib/utils/envs.py +++ b/pavelib/utils/envs.py @@ -106,6 +106,11 @@ class Env(object): 'programs': { 'port': 8090, 'log': BOK_CHOY_LOG_DIR / "bok_choy_programs.log", + }, + + 'ecommerce': { + 'port': 8043, + 'log': BOK_CHOY_LOG_DIR / "bok_choy_ecommerce.log", } } diff --git a/pavelib/utils/test/suites/nose_suite.py b/pavelib/utils/test/suites/nose_suite.py index 1544ccaaaa..61d2225552 100644 --- a/pavelib/utils/test/suites/nose_suite.py +++ b/pavelib/utils/test/suites/nose_suite.py @@ -133,7 +133,7 @@ class SystemTestSuite(NoseTestSuite): self.processes = int(self.processes) if self.randomize is None: - self.randomize = False + self.randomize = self.root == 'lms' if self.processes != 0 and self.verbosity > 1: print colorize( @@ -158,9 +158,12 @@ class SystemTestSuite(NoseTestSuite): self.extra_args, '--with-xunitmp', '--xunitmp-file={}'.format(self.report_dir / "nosetests.xml"), - '--processes={}'.format(self.processes), '--with-database-isolation', ] + + if self.processes != 0: + cmd.append('--processes={}'.format(self.processes)) + if self.randomize: cmd.append('--with-randomly') diff --git a/pavelib/utils/test/utils.py b/pavelib/utils/test/utils.py index 88681696f0..8e3e3e62b1 100644 --- a/pavelib/utils/test/utils.py +++ b/pavelib/utils/test/utils.py @@ -30,7 +30,7 @@ def clean_test_files(): def clean_dir(directory): """ - Clean coverage files, to ensure that we don't use stale data to generate reports. + Delete all the files from the specified directory. """ # We delete the files but preserve the directory structure # so that coverage.py has a place to put the reports. diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 313557b6c2..d222f905e2 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -41,9 +41,9 @@ djangorestframework-oauth==1.1.0 edx-ccx-keys==0.1.2 edx-drf-extensions==0.5.1 edx-lint==0.4.3 -edx-django-oauth2-provider==1.0.3 +edx-django-oauth2-provider==1.1.1 edx-django-sites-extensions==2.0.1 -edx-oauth2-provider==1.0.1 +edx-oauth2-provider==1.1.1 edx-opaque-keys==0.2.1 edx-organizations==0.4.1 edx-rest-api-client==1.2.1 @@ -142,7 +142,7 @@ django_debug_toolbar==1.3.2 # Used for testing before_after==0.1.3 -bok-choy==0.5.2 +bok-choy==0.5.3 chrono==1.0.2 coverage==4.0.2 ddt==0.8.0 @@ -180,3 +180,6 @@ jsonfield==1.0.3 # Inlines CSS styles into HTML for email notifications. pynliner==0.5.2 + +# for sailthru integration +sailthru-client==2.2.3 \ No newline at end of file diff --git a/requirements/edx/github.txt b/requirements/edx/github.txt index b6e4b86318..3ef76c490c 100644 --- a/requirements/edx/github.txt +++ b/requirements/edx/github.txt @@ -67,7 +67,7 @@ git+https://github.com/edx/rfc6266.git@v0.0.5-edx#egg=rfc6266==0.0.5-edx # Used for testing git+https://github.com/edx/lettuce.git@0.2.20.002#egg=lettuce==0.2.20.002 -git+https://github.com/edx/pa11ycrawler.git@a963bbb7c4f861b24b5f66bfc5259d3fa207cca8#egg=pa11ycrawler +git+https://github.com/edx/pa11ycrawler.git@a963bbb7c4f861b24b5f66bfc5259d3fa207cca8#egg=pa11ycrawler==0.1a # Our libraries: git+https://github.com/edx/XBlock.git@xblock-0.4.10#egg=XBlock==0.4.10 @@ -78,9 +78,9 @@ git+https://github.com/edx/XBlock.git@xblock-0.4.10#egg=XBlock==0.4.10 git+https://github.com/edx/edx-ora2.git@1.1.5#egg=ora2==1.1.5 -e git+https://github.com/edx/edx-submissions.git@1.1.0#egg=edx-submissions==1.1.0 git+https://github.com/edx/ease.git@release-2015-07-14#egg=ease==0.1.3 -git+https://github.com/edx/i18n-tools.git@v0.3.1#egg=i18n-tools==v0.3.1 +git+https://github.com/edx/i18n-tools.git@v0.3.2#egg=i18n-tools==v0.3.2 git+https://github.com/edx/edx-val.git@0.0.9#egg=edxval==0.0.9 --e git+https://github.com/pmitros/RecommenderXBlock.git@518234bc354edbfc2651b9e534ddb54f96080779#egg=recommender-xblock +git+https://github.com/pmitros/RecommenderXBlock.git@v1.1#egg=recommender-xblock==1.1 git+https://github.com/solashirai/crowdsourcehinter.git@518605f0a95190949fe77bd39158450639e2e1dc#egg=crowdsourcehinter-xblock==0.1 -e git+https://github.com/pmitros/RateXBlock.git@367e19c0f6eac8a5f002fd0f1559555f8e74bfff#egg=rate-xblock -e git+https://github.com/pmitros/DoneXBlock.git@857bf365f19c904d7e48364428f6b93ff153fabd#egg=done-xblock @@ -89,10 +89,10 @@ git+https://github.com/edx/xblock-utils.git@v1.0.2#egg=xblock-utils==1.0.2 -e git+https://github.com/edx-solutions/xblock-google-drive.git@138e6fa0bf3a2013e904a085b9fed77dab7f3f21#egg=xblock-google-drive -e git+https://github.com/edx/edx-reverification-block.git@0.0.5#egg=edx-reverification-block==0.0.5 git+https://github.com/edx/edx-user-state-client.git@1.0.1#egg=edx-user-state-client==1.0.1 -git+https://github.com/edx/xblock-lti-consumer.git@v1.0.7#egg=xblock-lti-consumer==1.0.7 -git+https://github.com/edx/edx-proctoring.git@0.12.18#egg=edx-proctoring==0.12.18 +git+https://github.com/edx/xblock-lti-consumer.git@v1.0.9#egg=xblock-lti-consumer==1.0.9 +git+https://github.com/edx/edx-proctoring.git@0.12.19#egg=edx-proctoring==0.12.19 # Third Party XBlocks -e git+https://github.com/mitodl/edx-sga@172a90fd2738f8142c10478356b2d9ed3e55334a#egg=edx-sga -e git+https://github.com/open-craft/xblock-poll@v1.1#egg=xblock-poll==1.1 -git+https://github.com/edx-solutions/xblock-drag-and-drop-v2@v2.0.6#egg=xblock-drag-and-drop-v2==2.0.6 +git+https://github.com/edx-solutions/xblock-drag-and-drop-v2@v2.0.7#egg=xblock-drag-and-drop-v2==2.0.7 diff --git a/scripts/safe_template_linter.py b/scripts/safe_template_linter.py index f7c1cca6b4..7885fdde73 100755 --- a/scripts/safe_template_linter.py +++ b/scripts/safe_template_linter.py @@ -2376,8 +2376,8 @@ class MakoTemplateLinter(BaseLinter): r""" | # script tag start | # script tag end - <%static:require_module.*?> | # require js script tag start - | # require js script tag end + <%static:require_module(_async)?.*?> | # require js script tag start (optionally the _async version) + | # require js script tag end (optionally the _async version) <%block[ ]*name=['"]requirejs['"]\w*> | # require js tag start # require js tag end """, diff --git a/scripts/safelint_thresholds.json b/scripts/safelint_thresholds.json index 5fe22e3bda..b3d7a25672 100644 --- a/scripts/safelint_thresholds.json +++ b/scripts/safelint_thresholds.json @@ -1,19 +1,19 @@ { "rules": { - "javascript-concat-html": 229, + "javascript-concat-html": 205, "javascript-escape": 7, - "javascript-interpolate": 65, - "javascript-jquery-append": 113, - "javascript-jquery-html": 303, + "javascript-interpolate": 51, + "javascript-jquery-append": 110, + "javascript-jquery-html": 274, "javascript-jquery-insert-into-target": 26, "javascript-jquery-insertion": 28, "javascript-jquery-prepend": 12, "mako-html-entities": 0, - "mako-invalid-html-filter": 33, - "mako-invalid-js-filter": 222, + "mako-invalid-html-filter": 29, + "mako-invalid-js-filter": 209, "mako-js-html-string": 0, "mako-js-missing-quotes": 0, - "mako-missing-default": 231, + "mako-missing-default": 215, "mako-multiple-page-tags": 0, "mako-unknown-context": 0, "mako-unparseable-expression": 0, @@ -21,12 +21,12 @@ "python-close-before-format": 0, "python-concat-html": 27, "python-custom-escape": 13, - "python-deprecated-display-name": 57, + "python-deprecated-display-name": 54, "python-interpolate-html": 68, "python-parse-error": 0, "python-requires-html-or-text": 0, - "python-wrap-html": 297, - "underscore-not-escaped": 709 + "python-wrap-html": 266, + "underscore-not-escaped": 659 }, - "total": 2426 + "total": 2237 } diff --git a/themes/edx.org/cms/templates/widgets/sock.html b/themes/edx.org/cms/templates/widgets/sock.html index d5df159c7a..44f059a569 100644 --- a/themes/edx.org/cms/templates/widgets/sock.html +++ b/themes/edx.org/cms/templates/widgets/sock.html @@ -6,7 +6,7 @@ from django.core.urlresolvers import reverse