Merge branch 'wip-MDL-41676-master' of git://github.com/marinaglancy/moodle
authorSam Hemelryk <sam@moodle.com>
Mon, 30 Sep 2013 21:14:04 +0000 (10:14 +1300)
committerSam Hemelryk <sam@moodle.com>
Mon, 30 Sep 2013 21:14:04 +0000 (10:14 +1300)
63 files changed:
admin/settings/courses.php
admin/webservice/service.php
admin/webservice/service_users.php
backup/moodle2/backup_activity_task.class.php
backup/moodle2/backup_course_task.class.php
backup/moodle2/backup_root_task.class.php
backup/util/dbops/backup_controller_dbops.class.php
backup/util/helper/backup_cron_helper.class.php
course/lib.php
course/yui/toolboxes/toolboxes.js
enrol/imsenterprise/lib.php
grade/edit/tree/lib.php
grade/tests/edittreelib_test.php
lang/en/backup.php
lang/en/webservice.php
lib/classes/event/webservice_function_called.php [new file with mode: 0644]
lib/classes/event/webservice_login_failed.php [new file with mode: 0644]
lib/classes/event/webservice_service_created.php [new file with mode: 0644]
lib/classes/event/webservice_service_deleted.php [new file with mode: 0644]
lib/classes/event/webservice_service_updated.php [new file with mode: 0644]
lib/classes/event/webservice_service_user_added.php [new file with mode: 0644]
lib/classes/event/webservice_service_user_removed.php [new file with mode: 0644]
lib/classes/event/webservice_token_created.php [new file with mode: 0644]
lib/classes/event/webservice_token_sent.php [new file with mode: 0644]
lib/classes/user.php
lib/coursecatlib.php
lib/db/install.xml
lib/db/upgrade.php
lib/filestorage/file_storage.php
lib/filestorage/stored_file.php
lib/moodlelib.php
lib/navigationlib.php
lib/questionlib.php
lib/upgrade.txt
login/token.php
mod/quiz/lib.php
mod/quiz/report/statistics/classes/calculated.php [new file with mode: 0644]
mod/quiz/report/statistics/classes/calculator.php [new file with mode: 0644]
mod/quiz/report/statistics/report.php
mod/quiz/report/statistics/statistics_graph.php
mod/quiz/report/statistics/tests/stats_from_steps_walkthrough_test.php
mod/scorm/lib.php
mod/upgrade.txt
mod/workshop/eval/best/lib.php
mod/workshop/eval/best/tests/lib_test.php
question/type/multianswer/questiontype.php
question/type/multichoice/backup/moodle2/backup_qtype_multichoice_plugin.class.php
question/type/multichoice/backup/moodle2/restore_qtype_multichoice_plugin.class.php
question/type/multichoice/db/install.xml
question/type/multichoice/db/upgrade.php
question/type/multichoice/questiontype.php
question/type/multichoice/tests/questiontype_test.php
question/type/multichoice/version.php
question/upgrade.txt
repository/upgrade.txt
theme/base/style/course.css
theme/bootstrapbase/less/moodle/course.less
theme/bootstrapbase/style/moodle.css
user/edit.php
user/editadvanced.php
version.php
webservice/lib.php
webservice/tests/events.php [new file with mode: 0644]

index 377034b..4005c7c 100644 (file)
@@ -162,6 +162,7 @@ if ($hassiteconfig
     $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_userscompletion', new lang_string('generaluserscompletion','backup'), new lang_string('configgeneraluserscompletion','backup'), array('value'=>1, 'locked'=>0)));
     $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_logs', new lang_string('generallogs','backup'), new lang_string('configgenerallogs','backup'), array('value'=>0, 'locked'=>0)));
     $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_histories', new lang_string('generalhistories','backup'), new lang_string('configgeneralhistories','backup'), array('value'=>0, 'locked'=>0)));
+    $temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_questionbank', new lang_string('generalquestionbank','backup'), new lang_string('configgeneralquestionbank','backup'), array('value'=>1, 'locked'=>0)));
     $ADMIN->add('backups', $temp);
 
     // Create a page for general import configuration and defaults.
@@ -236,6 +237,7 @@ if ($hassiteconfig
     $temp->add(new admin_setting_configcheckbox('backup/backup_auto_userscompletion', new lang_string('generaluserscompletion','backup'), new lang_string('configgeneraluserscompletion','backup'), 1));
     $temp->add(new admin_setting_configcheckbox('backup/backup_auto_logs', new lang_string('generallogs', 'backup'), new lang_string('configgenerallogs', 'backup'), 0));
     $temp->add(new admin_setting_configcheckbox('backup/backup_auto_histories', new lang_string('generalhistories','backup'), new lang_string('configgeneralhistories','backup'), 0));
+    $temp->add(new admin_setting_configcheckbox('backup/backup_auto_questionbank', new lang_string('generalquestionbank','backup'), new lang_string('configgeneralquestionbank','backup'), 1));
 
 
     //$temp->add(new admin_setting_configcheckbox('backup/backup_auto_messages', new lang_string('messages', 'message'), new lang_string('backupmessageshelp','message'), 0));
index a933ec4..13f3c8d 100644 (file)
@@ -58,7 +58,12 @@ if ($action == 'delete' and confirm_sesskey() and $service and empty($service->c
     }
     //The user has confirmed the deletion, delete and redirect
     $webservicemanager->delete_service($service->id);
-    add_to_log(SITEID, 'webservice', 'delete', $returnurl, get_string('deleteservice', 'webservice', $service));
+    $params = array(
+        'objectid' => $service->id
+    );
+    $event = \core\event\webservice_service_deleted::create($params);
+    $event->add_record_snapshot('external_services', $service);
+    $event->trigger();
     redirect($returnurl);
 }
 
@@ -75,7 +80,12 @@ if ($mform->is_cancelled()) {
     //create operation
     if (empty($servicedata->id)) {
         $servicedata->id = $webservicemanager->add_external_service($servicedata);
-        add_to_log(SITEID, 'webservice', 'add', $returnurl, get_string('addservice', 'webservice', $servicedata));
+        $params = array(
+            'objectid' => $servicedata->id
+        );
+        $event = \core\event\webservice_service_updated::create($params);
+        $event->add_record_snapshot('external_services', $servicedata);
+        $event->trigger();
 
         //redirect to the 'add functions to service' page
         $addfunctionpage = new moodle_url(
@@ -85,7 +95,12 @@ if ($mform->is_cancelled()) {
     } else {
         //update operation
         $webservicemanager->update_external_service($servicedata);
-        add_to_log(SITEID, 'webservice', 'edit', $returnurl, get_string('editservice', 'webservice', $servicedata));
+        $params = array(
+            'objectid' => $servicedata->id
+        );
+        $event = \core\event\webservice_service_created::create($params);
+        $event->add_record_snapshot('external_services', $servicedata);
+        $event->trigger();
     }
 
     redirect($returnurl);
index ad67c66..907a4cc 100644 (file)
@@ -57,8 +57,13 @@ if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) {
             $serviceuser->externalserviceid = $id;
             $serviceuser->userid = $adduser->id;
             $webservicemanager->add_ws_authorised_user($serviceuser);
-            add_to_log(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id='
-                    . $id, 'add', '', $adduser->id);
+
+            $params = array(
+                'objectid' => $serviceuser->externalserviceid,
+                'relateduserid' => $serviceuser->userid
+            );
+            $event = \core\event\webservice_service_user_added::create($params);
+            $event->trigger();
         }
         $potentialuserselector->invalidate_selected_users();
         $alloweduserselector->invalidate_selected_users();
@@ -71,8 +76,13 @@ if (optional_param('remove', false, PARAM_BOOL) && confirm_sesskey()) {
     if (!empty($userstoremove)) {
         foreach ($userstoremove as $removeuser) {
             $webservicemanager->remove_ws_authorised_user($removeuser, $id);
-            add_to_log(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id='
-                    . $id, 'remove', '', $removeuser->id);
+
+            $params = array(
+                'objectid' => $id,
+                'relateduserid' => $removeuser->id
+            );
+            $event = \core\event\webservice_service_user_removed::create($params);
+            $event->trigger();
         }
         $potentialuserselector->invalidate_selected_users();
         $alloweduserselector->invalidate_selected_users();
index a1ada38..2dc9353 100644 (file)
@@ -246,6 +246,8 @@ abstract class backup_activity_task extends backup_task {
      * Defines the common setting that any backup activity will have
      */
     protected function define_settings() {
+        global $CFG;
+        require_once($CFG->libdir.'/questionlib.php');
 
         // All the settings related to this activity will include this prefix
         $settingprefix = $this->modulename . '_' . $this->moduleid . '_';
@@ -264,6 +266,12 @@ abstract class backup_activity_task extends backup_task {
         // Look for "activities" root setting
         $activities = $this->plan->get_setting('activities');
         $activities->add_dependency($activity_included);
+
+        if (question_module_uses_questions($this->modulename)) {
+            $questionbank = $this->plan->get_setting('questionbank');
+            $questionbank->add_dependency($activity_included);
+        }
+
         // Look for "section_included" section setting (if exists)
         $settingname = 'section_' . $this->sectionid . '_included';
         if ($this->plan->setting_exists($settingname)) {
index 5d4cd9b..7e37f99 100644 (file)
@@ -90,8 +90,10 @@ class backup_course_task extends backup_task {
         // course->defaultgroupingid
         $this->add_step(new backup_annotate_groups_from_groupings('annotate_groups_from_groupings'));
 
-        // Annotate the question_categories belonging to the course context
-        $this->add_step(new backup_calculate_question_categories('course_question_categories'));
+        // Annotate the question_categories belonging to the course context (conditionally).
+        if ($this->get_setting_value('questionbank')) {
+            $this->add_step(new backup_calculate_question_categories('course_question_categories'));
+        }
 
         // Generate the roles file (optionally role assignments and always role overrides)
         $this->add_step(new backup_roles_structure_step('course_roles', 'roles.xml'));
index a4d1782..3e97f68 100644 (file)
@@ -152,5 +152,10 @@ class backup_root_task extends backup_task {
         $gradehistories->set_ui(new backup_setting_ui_checkbox($gradehistories, get_string('rootsettinggradehistories', 'backup')));
         $this->add_setting($gradehistories);
         $users->add_dependency($gradehistories);
+
+        // Define question bank inclusion setting.
+        $questionbank = new backup_generic_setting('questionbank', base_setting::IS_BOOLEAN, true);
+        $questionbank->set_ui(new backup_setting_ui_checkbox($questionbank, get_string('rootsettingquestionbank', 'backup')));
+        $this->add_setting($questionbank);
     }
 }
index 409be32..9fd95ac 100644 (file)
@@ -544,11 +544,18 @@ abstract class backup_controller_dbops extends backup_dbops {
             'backup_general_badges'             => 'badges',
             'backup_general_userscompletion'    => 'userscompletion',
             'backup_general_logs'               => 'logs',
-            'backup_general_histories'          => 'grade_histories'
+            'backup_general_histories'          => 'grade_histories',
+            'backup_general_questionbank'       => 'questionbank'
         );
         $plan = $controller->get_plan();
         foreach ($settings as $config=>$settingname) {
             $value = get_config('backup', $config);
+            if ($value === false) {
+                // Ignore this because the config has not been set. get_config
+                // returns false if a setting doesn't exist, '0' is returned when
+                // the configuration is set to false.
+                continue;
+            }
             $locked = (get_config('backup', $config.'_locked') == true);
             if ($plan->setting_exists($settingname)) {
                 $setting = $plan->get_setting($settingname);
index 5913324..97d3334 100644 (file)
@@ -386,11 +386,14 @@ abstract class backup_cron_automated_helper {
                 'badges' => 'backup_auto_badges',
                 'completion_information' => 'backup_auto_userscompletion',
                 'logs' => 'backup_auto_logs',
-                'histories' => 'backup_auto_histories'
+                'histories' => 'backup_auto_histories',
+                'questionbank' => 'backup_auto_questionbank'
             );
             foreach ($settings as $setting => $configsetting) {
                 if ($bc->get_plan()->setting_exists($setting)) {
-                    $bc->get_plan()->get_setting($setting)->set_value($config->{$configsetting});
+                    if (isset($config->{$configsetting})) {
+                        $bc->get_plan()->get_setting($setting)->set_value($config->{$configsetting});
+                    }
                 }
             }
 
index 19988e2..e331e2f 100644 (file)
@@ -1289,8 +1289,11 @@ function get_module_metadata($course, $modnames, $sectionreturn = null) {
 
         // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
         $gettypesfunc =  $modname.'_get_types';
+        $types = MOD_SUBTYPE_NO_CHILDREN;
         if (function_exists($gettypesfunc)) {
             $types = $gettypesfunc();
+        }
+        if ($types !== MOD_SUBTYPE_NO_CHILDREN) {
             if (is_array($types) && count($types) > 0) {
                 $group = new stdClass();
                 $group->name = $modname;
@@ -1314,7 +1317,9 @@ function get_module_metadata($course, $modnames, $sectionreturn = null) {
                     // should have the same archetype
                     $group->archetype = $subtype->archetype;
 
-                    if (get_string_manager()->string_exists('help' . $subtype->name, $modname)) {
+                    if (!empty($type->help)) {
+                        $subtype->help = $type->help;
+                    } else if (get_string_manager()->string_exists('help' . $subtype->name, $modname)) {
                         $subtype->help = get_string('help' . $subtype->name, $modname);
                     }
                     $subtype->link = new moodle_url($urlbase, array('add' => $modname, 'type' => $subtype->name));
index 2dad9f0..372652a 100644 (file)
@@ -432,24 +432,24 @@ YUI.add('moodle-course-toolboxes', function(Y) {
          * @method handle_resource_dim
          * @param {Node} button The button that triggered the action.
          * @param {Node} activity The activity node that this action will be performed on.
-         * @param {String} status Whether the activity was shown or hidden.
-         * @returns {number} 1 if we were changing to visible, 0 if we were hiding.
+         * @param {String} action 'show' or 'hide'.
+         * @returns {number} 1 if we changed to visible, 0 if we were hiding.
          */
-        handle_resource_dim : function(button, activity, status) {
+        handle_resource_dim : function(button, activity, action) {
             var toggleclass = CSS.DIMCLASS,
                 dimarea = activity.one('a'),
                 availabilityinfo = activity.one(CSS.AVAILABILITYINFODIV),
-                newstatus = (status === 'hide') ? 'show' : 'hide',
-                newstring = M.util.get_string(newstatus, 'moodle');
+                nextaction = (action === 'hide') ? 'show' : 'hide';
+                newstring = M.util.get_string(nextaction, 'moodle');
 
             // Update button info.
             button.one('img').setAttrs({
                 'alt' : newstring,
-                'src'   : M.util.image_url('t/' + newstatus)
+                'src'   : M.util.image_url('t/' + nextaction)
             });
             button.set('title', newstring);
-            button.replaceClass('editing_'+status, 'editing_'+newstatus)
-            button.setData('action', newstatus);
+            button.replaceClass('editing_'+action, 'editing_'+nextaction);
+            button.setData('action', nextaction);
 
             // If activity is conditionally hidden, then don't toggle.
             if (Y.Moodle.core_course.util.cm.getName(activity) == null) {
@@ -466,7 +466,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
             if (availabilityinfo) {
                 availabilityinfo.toggleClass(CSS.HIDE);
             }
-            return (status === 'hide') ? 0 : 1;
+            return (action === 'hide') ? 0 : 1;
         },
 
         /**
@@ -683,13 +683,13 @@ YUI.add('moodle-course-toolboxes', function(Y) {
                 shouldbevisible = args.visible,
                 buttonnode = element.one(SELECTOR.SHOW),
                 visible = (buttonnode === null),
-                status = 'hide';
+                action = 'show';
             if (visible) {
                 buttonnode = element.one(SELECTOR.HIDE);
-                status = 'show'
+                action = 'hide';
             }
             if (visible != shouldbevisible) {
-                this.handle_resource_dim(buttonnode, buttonnode.getData('activity'), status);
+                this.handle_resource_dim(buttonnode, buttonnode.getData('activity'), action);
             }
         }
     }, {
@@ -752,26 +752,26 @@ YUI.add('moodle-course-toolboxes', function(Y) {
 
             // The value to submit
             var value;
-            // The status text for strings and images
-            var status,
-                oldstatus;
+            // The text for strings and images. Also determines the icon to display.
+            var action,
+                nextaction;
 
             if (!section.hasClass(CSS.SECTIONHIDDENCLASS)) {
                 section.addClass(CSS.SECTIONHIDDENCLASS);
                 value = 0;
-                status = 'show';
-                oldstatus = 'hide';
+                action = 'hide';
+                nextaction = 'show';
             } else {
                 section.removeClass(CSS.SECTIONHIDDENCLASS);
                 value = 1;
-                status = 'hide';
-                oldstatus = 'show';
+                action = 'show';
+                nextaction = 'hide';
             }
 
-            var newstring = M.util.get_string(status + 'fromothers', 'format_' + this.get('format'));
+            var newstring = M.util.get_string(nextaction + 'fromothers', 'format_' + this.get('format'));
             hideicon.setAttrs({
                 'alt' : newstring,
-                'src'   : M.util.image_url('i/' + status)
+                'src'   : M.util.image_url('i/' + nextaction)
             });
             button.set('title', newstring);
 
@@ -800,7 +800,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
                 // NOTE: resourcestotoggle is returned as a string instead
                 // of a Number so we must cast our activityid to a String.
                 if (Y.Array.indexOf(response.resourcestotoggle, "" + activityid) != -1) {
-                    node.getData('toolbox').handle_resource_dim(button, node, oldstatus);
+                    node.getData('toolbox').handle_resource_dim(button, node, action);
                 }
             }, this);
         },
index f9ac4ca..acb8b05 100644 (file)
@@ -234,7 +234,7 @@ function cron() {
 
         $eventdata = new stdClass();
         $eventdata->modulename        = 'moodle';
-        $eventdata->component         = 'imsenterprise';
+        $eventdata->component         = 'enrol_imsenterprise';
         $eventdata->name              = 'imsenterprise_enrolment';
         $eventdata->userfrom          = get_admin();
         $eventdata->userto            = get_admin();
index e782303..c05eb92 100644 (file)
@@ -793,9 +793,12 @@ class grade_edit_tree_column_range extends grade_edit_tree_column {
     public function get_item_cell($item, $params) {
         global $DB, $OUTPUT;
 
-        // If the parent aggregation is Sum of Grades, this cannot be changed
+        // If the parent aggregation is Sum of Grades, we should show the number, even for scales, as that value is used...
+        // ...in the computation. For text grades, the grademax is not used, so we can still show the no value string.
         $parent_cat = $item->get_parent_category();
-        if ($parent_cat->aggregation == GRADE_AGGREGATE_SUM) {
+        if ($item->gradetype == GRADE_TYPE_TEXT) {
+            $grademax = ' - ';
+        } else if ($parent_cat->aggregation == GRADE_AGGREGATE_SUM) {
             $grademax = format_float($item->grademax, $item->get_decimals());
         } elseif ($item->gradetype == GRADE_TYPE_SCALE) {
             $scale = $DB->get_record('scale', array('id' => $item->scaleid));
index 59e4a23..07c59e7 100644 (file)
@@ -32,21 +32,86 @@ require_once($CFG->dirroot.'/grade/edit/tree/lib.php');
 /**
  * Tests grade_edit_tree (deals with the data on the categories and items page in the gradebook)
  */
-class core_grade_edittreelib_testcase extends basic_testcase {
-    var $courseid = 1;
-    var $context = null;
-    var $grade_edit_tree = null;
-
+class core_grade_edittreelib_testcase extends advanced_testcase {
     public function test_format_number() {
-        $numinput = array( 0,   1,   1.01, '1.010', 1.2345);
+        $numinput = array(0,   1,   1.01, '1.010', 1.2345);
         $numoutput = array(0.0, 1.0, 1.01,  1.01,   1.2345);
 
-        for ($i=0; $i<sizeof($numinput); $i++) {
+        for ($i = 0; $i < count($numinput); $i++) {
             $msg = 'format_number() testing '.$numinput[$i].' %s';
-            $this->assertEquals(grade_edit_tree::format_number($numinput[$i]),$numoutput[$i],$msg);
+            $this->assertEquals(grade_edit_tree::format_number($numinput[$i]), $numoutput[$i], $msg);
         }
     }
 
+    public function test_grade_edit_tree_column_range_get_item_cell() {
+        global $DB, $CFG;
+
+        $this->resetAfterTest(true);
+
+        // Make some things we need.
+        $scale = $this->getDataGenerator()->create_scale();
+        $course = $this->getDataGenerator()->create_course();
+        $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id));
+        $modulecontext = context_module::instance($assign->id);
+        // The generator returns a dummy object, lets get the real assign object.
+        $assign = new assign($modulecontext, false, false);
+        $cm = $assign->get_course_module();
+
+        // Get range column.
+        $column = grade_edit_tree_column::factory('range');
+
+        $gradeitemparams = array(
+            'itemtype'     => 'mod',
+            'itemmodule'   => $cm->modname,
+            'iteminstance' => $cm->instance,
+            'courseid'     => $cm->course,
+            'itemnumber'   => 0
+        );
+
+        // Lets set the grade to something we know.
+        $instance = $assign->get_instance();
+        $instance->grade = 70;
+        $instance->instance = $instance->id;
+        $assign->update_instance($instance);
+
+        $gradeitem = grade_item::fetch($gradeitemparams);
+        $cell = $column->get_item_cell($gradeitem, array());
+
+        $this->assertEquals(GRADE_TYPE_VALUE, $gradeitem->gradetype);
+        $this->assertEquals(null, $gradeitem->scaleid);
+        $this->assertEquals(70.0, (float) $cell->text, "Grade text is 70", 0.01);
+
+        // Now change it to a scale.
+        $instance = $assign->get_instance();
+        $instance->grade = -($scale->id);
+        $instance->instance = $instance->id;
+        $assign->update_instance($instance);
+
+        $gradeitem = grade_item::fetch($gradeitemparams);
+        $cell = $column->get_item_cell($gradeitem, array());
+
+        // Make the expected scale text.
+        $scaleitems = null;
+        $scaleitems = explode(',', $scale->scale);
+        $scalestring = end($scaleitems) . ' (' . count($scaleitems) . ')';
+
+        $this->assertEquals(GRADE_TYPE_SCALE, $gradeitem->gradetype);
+        $this->assertEquals($scale->id, $gradeitem->scaleid);
+        $this->assertEquals($scalestring, $cell->text, "Grade text matches scale");
+
+        // Now change it to no grade.
+        $instance = $assign->get_instance();
+        $instance->grade = 0;
+        $instance->instance = $instance->id;
+        $assign->update_instance($instance);
+
+        $gradeitem = grade_item::fetch($gradeitemparams);
+        $cell = $column->get_item_cell($gradeitem, array());
+
+        $this->assertEquals(GRADE_TYPE_TEXT, $gradeitem->gradetype);
+        $this->assertEquals(null, $gradeitem->scaleid);
+        $this->assertEquals(' - ', $cell->text, 'Grade text matches empty value of " - "');
+    }
 }
 
 
index 1a092c9..54a7297 100644 (file)
@@ -86,6 +86,7 @@ $string['configgeneralcomments'] = 'Sets the default for including comments in a
 $string['configgeneralfilters'] = 'Sets the default for including filters in a backup.';
 $string['configgeneralhistories'] = 'Sets the default for including user history within a backup.';
 $string['configgenerallogs'] = 'If enabled logs will be included in backups by default.';
+$string['configgeneralquestionbank'] = 'If enabled the question bank will be included in backups by default. PLEASE NOTE: Disabling this setting with disable the backup of activities which use the question bank, such as the quiz.';
 $string['configgeneralroleassignments'] = 'If enabled by default roles assignments will also be backed up.';
 $string['configgeneraluserscompletion'] = 'If enabled user completion information will be included in backups by default.';
 $string['configgeneralusers'] = 'Sets the default for whether to include users in backups.';
@@ -136,7 +137,9 @@ $string['generalfilters'] = 'Include filters';
 $string['generalhistories'] = 'Include histories';
 $string['generalgradehistories'] = 'Include histories';
 $string['generallogs'] = 'Include logs';
+$string['generalquestionbank'] = 'Include question bank';
 $string['generalroleassignments'] = 'Include role assignments';
+$string['generalquestionbank'] = 'Include question bank';
 $string['generalsettings'] = 'General backup settings';
 $string['generaluserscompletion'] = 'Include user completion information';
 $string['generalusers'] = 'Include users';
@@ -229,6 +232,7 @@ $string['rootsettingfilters'] = 'Include filters';
 $string['rootsettingcomments'] = 'Include comments';
 $string['rootsettingcalendarevents'] = 'Include calendar events';
 $string['rootsettinguserscompletion'] = 'Include user completion details';
+$string['rootsettingquestionbank'] = 'Include question bank';
 $string['rootsettinglogs'] = 'Include course logs';
 $string['rootsettinggradehistories'] = 'Include grade history';
 $string['rootsettingimscc1'] = 'Convert to IMS Common Cartridge 1.0';
index 83cdb58..52966b2 100644 (file)
@@ -82,6 +82,14 @@ $string['errorcoursecontextnotvalid'] = 'You cannot execute functions in the cou
 $string['errorinvalidparam'] = 'The param "{$a}" is invalid.';
 $string['errornotemptydefaultparamarray'] = 'The web service description parameter named \'{$a}\' is an single or multiple structure. The default can only be empty array. Check web service description.';
 $string['erroroptionalparamarray'] = 'The web service description parameter named \'{$a}\' is an single or multiple structure. It can not be set as VALUE_OPTIONAL. Check web service description.';
+$string['event_webservice_function_called'] = 'Web service function called';
+$string['event_webservice_login_failed'] = 'Web service login failed';
+$string['event_webservice_service_created'] = 'Web service service created';
+$string['event_webservice_service_updated'] = 'Web service service updated';
+$string['event_webservice_service_user_added'] = 'Web service service user added';
+$string['event_webservice_service_user_removed'] = 'Web service service user removed';
+$string['event_webservice_token_created'] = 'Web service token created';
+$string['event_webservice_token_sent'] = 'Web service token sent';
 $string['execute'] = 'Execute';
 $string['executewarnign'] = 'WARNING: If you press execute your database will be modified and changes can not be reverted automatically!';
 $string['externalservice'] = 'External service';
diff --git a/lib/classes/event/webservice_function_called.php b/lib/classes/event/webservice_function_called.php
new file mode 100644 (file)
index 0000000..9914385
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core webservice function_called event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice function_called event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_function_called extends \core\event\base {
+
+    /**
+     * Legacy log data.
+     */
+    protected $legacylogdata;
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The web service function '{$this->other['function']}' has been called.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        return $this->legacylogdata;
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_function_called', 'webservice');
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->data['crud'] = 'r';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->context = \context_system::instance();
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return void
+     */
+    public function set_legacy_logdata($legacydata) {
+        $this->legacylogdata = $legacydata;
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->other['function'])) {
+           throw new \coding_exception('The key \'function\' needs to be set in $other.');
+        }
+    }
+
+}
diff --git a/lib/classes/event/webservice_login_failed.php b/lib/classes/event/webservice_login_failed.php
new file mode 100644 (file)
index 0000000..02c49a3
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core web service login failed event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core web service login_failed event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_login_failed extends \core\event\base {
+
+    /**
+     * Legacy log data.
+     *
+     * @var null|array
+     */
+    protected $legacylogdata;
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "Web service authentication failed with code: {$this->other['reason']}.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        return $this->legacylogdata;
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_login_failed', 'webservice');
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->data['crud'] = 'r';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->context = \context_system::instance();
+    }
+
+    /**
+     * Set the legacy event log data.
+     *
+     * @param array $logdata The log data.
+     * @return void
+     */
+    public function set_legacy_logdata($logdata) {
+        $this->legacylogdata = $logdata;
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->other['reason'])) {
+           throw new \coding_exception('The key \'reason\' needs to be set in $other.');
+        } else if (!isset($this->other['method'])) {
+           throw new \coding_exception('The key \'method\' needs to be set in $other.');
+        } else if (!isset($this->other['token']) && !isset($this->other['tokenid']) && !isset($this->other['username'])) {
+           throw new \coding_exception('The keys \'username\', \'token\' or \'tokenid\' need to be set in $other.');
+        }
+    }
+}
diff --git a/lib/classes/event/webservice_service_created.php b/lib/classes/event/webservice_service_created.php
new file mode 100644 (file)
index 0000000..436a236
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core webservice service created event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service created event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_created extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The web service service $this->objectid has been created by user $this->userid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        $service = $this->get_record_snapshot('external_services', $this->objectid);
+        return array(SITEID, 'webservice', 'add', $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices",
+            get_string('addservice', 'webservice', $service));
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_created', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/settings.php', array('section' => 'externalservices'));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'c';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+}
diff --git a/lib/classes/event/webservice_service_deleted.php b/lib/classes/event/webservice_service_deleted.php
new file mode 100644 (file)
index 0000000..4c497d9
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core webservice service deleted event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service deleted event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_deleted extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The web service service $this->objectid has been deleted by user $this->userid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        $service = $this->get_record_snapshot('external_services', $this->objectid);
+        return array(SITEID, 'webservice', 'delete', $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices",
+            get_string('deleteservice', 'webservice', $service));
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_deleted', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/settings.php', array('section' => 'externalservices'));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'd';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+}
diff --git a/lib/classes/event/webservice_service_updated.php b/lib/classes/event/webservice_service_updated.php
new file mode 100644 (file)
index 0000000..0b82da7
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core webservice service updated event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service updated event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_updated extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The web service service $this->objectid has been updated by user $this->userid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        $service = $this->get_record_snapshot('external_services', $this->objectid);
+        return array(SITEID, 'webservice', 'edit', $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices",
+            get_string('editservice', 'webservice', $service));
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_updated', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/settings.php', array('section' => 'externalservices'));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'u';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+    /**
+     * Set the legacy event log data.
+     *
+     * @return void
+     */
+    public function set_legacy_logdata($legacylogdata) {
+        $this->legacylogdata = $legacylogdata;
+    }
+
+}
diff --git a/lib/classes/event/webservice_service_user_added.php b/lib/classes/event/webservice_service_user_added.php
new file mode 100644 (file)
index 0000000..38309fb
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core webservice service user added event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service user added event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_user_added extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The user $this->relateduserid has been added to the web service service $this->objectid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        return array(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id=' . $this->objectid, 'add', '',
+            $this->relateduserid);
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_user_added', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/webservice/service_users.php', array('id' => $this->objectid));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'c';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->relateduserid)) {
+            throw new \coding_exception('The relateduserid must be set.');
+        }
+    }
+
+}
diff --git a/lib/classes/event/webservice_service_user_removed.php b/lib/classes/event/webservice_service_user_removed.php
new file mode 100644 (file)
index 0000000..a0f7eec
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core webservice service user removed event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service user removed event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_user_removed extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The user $this->relateduserid has been removed to the web service service $this->objectid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        return array(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id=' . $this->objectid, 'remove', '',
+            $this->relateduserid);
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_user_removed', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/webservice/service_users.php', array('id' => $this->objectid));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'd';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->relateduserid)) {
+            throw new \coding_exception('The relateduserid must be set.');
+        }
+    }
+
+}
diff --git a/lib/classes/event/webservice_token_created.php b/lib/classes/event/webservice_token_created.php
new file mode 100644 (file)
index 0000000..5f18336
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core webservice token_created event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice token_created event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_token_created extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "A web service token has been created for the user $this->relateduserid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        if (!empty($this->other['auto'])) {
+            // The token has been automatically created.
+            return array(SITEID, 'webservice', 'automatically create user token', '' , 'User ID: ' . $this->relateduserid);
+        }
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_token_created', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/settings.php', array('section' => 'webservicetokens'));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'c';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_tokens';
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->relateduserid)) {
+           throw new \coding_exception('The property \'relateduserid\' must be set.');
+        }
+    }
+
+}
diff --git a/lib/classes/event/webservice_token_sent.php b/lib/classes/event/webservice_token_sent.php
new file mode 100644 (file)
index 0000000..51775bd
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * core webservice token_sent event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice token sent event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_token_sent extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The token $this->objectid has been sent to the user $this->userid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        return array(SITEID, 'webservice', 'sending requested user token', '' , 'User ID: ' . $this->userid);
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_token_sent', 'webservice');
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'r';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_tokens';
+    }
+
+}
index 4032884..badf854 100644 (file)
@@ -39,7 +39,7 @@ class core_user {
     const NOREPLY_USER = -10;
 
     /**
-     * Suppport user id.
+     * Support user id.
      */
     const SUPPORT_USER = -20;
 
@@ -160,9 +160,11 @@ class core_user {
             self::$supportuser = self::get_dummy_user_record();
             self::$supportuser->id = self::SUPPORT_USER;
             self::$supportuser->email = $CFG->supportemail;
-            self::$supportuser->firstname = $CFG->supportname ? $CFG->supportname : $supportuser->firstname;
+            if ($CFG->supportname) {
+                self::$supportuser->firstname = $CFG->supportname;
+            }
             self::$supportuser->username = 'support';
-            self::$supportuser->maildisplay = true;
+            self::$supportuser->maildisplay = '1'; // Show to all.
         }
 
         // Send support msg to admin user if nothing is set above.
@@ -191,7 +193,7 @@ class core_user {
 
     /**
      * Return true is user id is greater than self::NOREPLY_USER and
-     * alternetely check db.
+     * alternatively check db.
      *
      * @param int $userid user id.
      * @param bool $checkdb if true userid will be checked in db. By default it's false, and
@@ -199,6 +201,8 @@ class core_user {
      * @return bool true is real user else false.
      */
     public static function is_real_user($userid, $checkdb = false) {
+        global $DB;
+
         if ($userid < 0) {
             return false;
         }
index 5348112..520840e 100644 (file)
@@ -572,12 +572,6 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate {
         if ($rv !== false) {
             return $rv;
         }
-        // We did not find the entry in cache but it also can mean that tree is not built.
-        // The keys 0 and 'countall' must always be present if tree is built.
-        if ($id !== 0 && $id !== 'countall' && $coursecattreecache->has('countall')) {
-            // Tree was built, it means the non-existing $id was requested.
-            return false;
-        }
         // Re-build the tree.
         $sql = "SELECT cc.id, cc.parent, cc.visible
                 FROM {course_categories} cc
@@ -619,7 +613,8 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate {
         if (array_key_exists($id, $all)) {
             return $all[$id];
         }
-        return false;
+        // Requested non-existing category.
+        return array();
     }
 
     /**
@@ -1187,8 +1182,13 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate {
         $coursecatcache = cache::make('core', 'coursecat');
         $cntcachekey = 'scnt-'. serialize($search);
         if (($cnt = $coursecatcache->get($cntcachekey)) === false) {
-            self::search_courses($search, $options);
-            $cnt = $coursecatcache->get($cntcachekey);
+            // Cached value not found. Retrieve ALL courses and return their count.
+            unset($options['offset']);
+            unset($options['limit']);
+            unset($options['summary']);
+            unset($options['coursecontacts']);
+            $courses = self::search_courses($search, $options);
+            $cnt = count($courses);
         }
         return $cnt;
     }
@@ -1311,8 +1311,13 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate {
         $cntcachekey = 'lcnt-'. $this->id. '-'. (!empty($options['recursive']) ? 'r' : '');
         $coursecatcache = cache::make('core', 'coursecat');
         if (($cnt = $coursecatcache->get($cntcachekey)) === false) {
-            $this->get_courses($options);
-            $cnt = $coursecatcache->get($cntcachekey);
+            // Cached value not found. Retrieve ALL courses and return their count.
+            unset($options['offset']);
+            unset($options['limit']);
+            unset($options['summary']);
+            unset($options['coursecontacts']);
+            $courses = $this->get_courses($options);
+            $cnt = count($courses);
         }
         return $cnt;
     }
index b0c04d8..f8f65cc 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20130921" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20130927" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
         <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
         <FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="order of files"/>
         <FIELD NAME="referencefileid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Use to indicate file is a proxy for repository file"/>
-        <FIELD NAME="referencelastsync" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Last time the proxy file was synced with repository, defined for performance reasons"/>
-        <FIELD NAME="referencelifetime" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="How often do we have to sync proxy file with repository, defined for performance reasons"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
index d68ce28..a4a39ff 100644 (file)
@@ -2555,5 +2555,29 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2013092001.02);
     }
 
+    if ($oldversion < 2013092700.01) {
+
+        $table = new xmldb_table('files');
+
+        // Define field referencelastsync to be dropped from files.
+        $field = new xmldb_field('referencelastsync');
+
+        // Conditionally launch drop field referencelastsync.
+        if ($dbman->field_exists($table, $field)) {
+            $dbman->drop_field($table, $field);
+        }
+
+        // Define field referencelifetime to be dropped from files.
+        $field = new xmldb_field('referencelifetime');
+
+        // Conditionally launch drop field referencelifetime.
+        if ($dbman->field_exists($table, $field)) {
+            $dbman->drop_field($table, $field);
+        }
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2013092700.01);
+    }
+
     return true;
 }
index 3783eee..f05a70a 100644 (file)
@@ -1400,10 +1400,6 @@ class file_storage {
             $filerecord->sortorder = 0;
         }
 
-        // TODO MDL-33416 [2.4] fields referencelastsync and referencelifetime to be removed from {files} table completely
-        unset($filerecord->referencelastsync);
-        unset($filerecord->referencelifetime);
-
         $filerecord->mimetype          = empty($filerecord->mimetype) ? $this->mimetype($filerecord->filename) : $filerecord->mimetype;
         $filerecord->userid            = empty($filerecord->userid) ? null : $filerecord->userid;
         $filerecord->source            = empty($filerecord->source) ? null : $filerecord->source;
@@ -2345,7 +2341,7 @@ class file_storage {
                     'lastsync' => $lastsync,
                     'lifetime' => $lifetime);
         $DB->execute('UPDATE {files} SET contenthash = :contenthash, filesize = :filesize,
-            status = :status, referencelastsync = :lastsync, referencelifetime = :lifetime
+            status = :status
             WHERE referencefileid = :referencefileid', $params);
         $data = array('id' => $referencefileid, 'lastsync' => $lastsync, 'lifetime' => $lifetime);
         $DB->update_record('files_reference', (object)$data);
index 93b7cda..e937405 100644 (file)
@@ -156,12 +156,6 @@ class stored_file {
                     }
                 }
 
-                if ($field === 'referencelastsync' or $field === 'referencelifetime') {
-                    // do not update those fields
-                    // TODO MDL-33416 [2.4] fields referencelastsync and referencelifetime to be removed from {files} table completely
-                    continue;
-                }
-
                 // adding the field
                 $this->file_record->$field = $value;
             } else {
index 9d1b609..5e714a4 100644 (file)
@@ -433,6 +433,9 @@ define('FEATURE_BACKUP_MOODLE2', 'backup_moodle2');
 /** True if module can show description on course main page */
 define('FEATURE_SHOW_DESCRIPTION', 'showdescription');
 
+/** True if module uses the question bank */
+define('FEATURE_USES_QUESTIONS', 'usesquestions');
+
 /** Unspecified module archetype */
 define('MOD_ARCHETYPE_OTHER', 0);
 /** Resource-like type module */
@@ -442,6 +445,9 @@ define('MOD_ARCHETYPE_ASSIGNMENT', 2);
 /** System (not user-addable) module archetype */
 define('MOD_ARCHETYPE_SYSTEM', 3);
 
+/** Return this from modname_get_types callback to use default display in activity chooser */
+define('MOD_SUBTYPE_NO_CHILDREN', 'modsubtypenochildren');
+
 /**
  * Security token used for allowing access
  * from external application such as web services.
@@ -7247,10 +7253,35 @@ function plugin_callback($type, $name, $feature, $action, $params = null, $defau
  * @param array $params parameters of callback function
  * @param mixed $default default value if callback function hasn't been defined, or if it retursn null.
  * @return mixed
- * @throws coding_exception
  */
 function component_callback($component, $function, array $params = array(), $default = null) {
-    global $CFG; // This is needed for require_once() below.
+
+    $functionname = component_callback_exists($component, $function);
+
+    if ($functionname) {
+        // Function exists, so just return function result.
+        $ret = call_user_func_array($functionname, $params);
+        if (is_null($ret)) {
+            return $default;
+        } else {
+            return $ret;
+        }
+    }
+    return $default;
+}
+
+/**
+ * Determine if a component callback exists and return the function name to call. Note that this
+ * function will include the required library files so that the functioname returned can be
+ * called directly.
+ *
+ * @param string $component frankenstyle component name, e.g. 'mod_quiz'
+ * @param string $function the rest of the function name, e.g. 'cron' will end up calling 'mod_quiz_cron'
+ * @return mixed Complete function name to call if the callback exists or false if it doesn't.
+ * @throws coding_exception if invalid component specfied
+ */
+function component_callback_exists($component, $function) {
+    global $CFG; // This is needed for the inclusions.
 
     $cleancomponent = clean_param($component, PARAM_COMPONENT);
     if (empty($cleancomponent)) {
@@ -7276,21 +7307,15 @@ function component_callback($component, $function, array $params = array(), $def
 
     if (!function_exists($function) and function_exists($oldfunction)) {
         if ($type !== 'mod' and $type !== 'core') {
-            debugging("Please use new function name $function instead of legacy $oldfunction");
+            debugging("Please use new function name $function instead of legacy $oldfunction", DEBUG_DEVELOPER);
         }
         $function = $oldfunction;
     }
 
     if (function_exists($function)) {
-        // Function exists, so just return function result.
-        $ret = call_user_func_array($function, $params);
-        if (is_null($ret)) {
-            return $default;
-        } else {
-            return $ret;
-        }
+        return $function;
     }
-    return $default;
+    return false;
 }
 
 /**
index 506d2d7..63ad252 100644 (file)
@@ -3522,55 +3522,6 @@ class settings_navigation extends navigation_node {
         return $node;
     }
 
-    /**
-     * Generate the list of modules for the given course.
-     *
-     * @param stdClass $course The course to get modules for
-     */
-    protected function get_course_modules($course) {
-        global $CFG;
-        // This function is included when we include course/lib.php at the top
-        // of this file
-        $modnames = get_module_types_names();
-        $resources = array();
-        $activities = array();
-        foreach($modnames as $modname=>$modnamestr) {
-            if (!course_allowed_module($course, $modname)) {
-                continue;
-            }
-
-            $libfile = "$CFG->dirroot/mod/$modname/lib.php";
-            if (!file_exists($libfile)) {
-                continue;
-            }
-            include_once($libfile);
-            $gettypesfunc =  $modname.'_get_types';
-            if (function_exists($gettypesfunc)) {
-                $types = $gettypesfunc();
-                foreach($types as $type) {
-                    if (!isset($type->modclass) || !isset($type->typestr)) {
-                        debugging('Incorrect activity type in '.$modname);
-                        continue;
-                    }
-                    if ($type->modclass == MOD_CLASS_RESOURCE) {
-                        $resources[html_entity_decode($type->type, ENT_QUOTES, 'UTF-8')] = $type->typestr;
-                    } else {
-                        $activities[html_entity_decode($type->type, ENT_QUOTES, 'UTF-8')] = $type->typestr;
-                    }
-                }
-            } else {
-                $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
-                if ($archetype == MOD_ARCHETYPE_RESOURCE) {
-                    $resources[$modname] = $modnamestr;
-                } else {
-                    // all other archetypes are considered activity
-                    $activities[$modname] = $modnamestr;
-                }
-            }
-        }
-        return array($resources, $activities);
-    }
-
     /**
      * This function loads the course settings that are available for the user
      *
index 9984b71..5cdfb69 100644 (file)
@@ -2054,3 +2054,23 @@ function question_page_type_list($pagetype, $parentcontext, $currentcontext) {
         return $types;
     }
 }
+
+/**
+ * Does an activity module use the question bank?
+ *
+ * @param string $modname The name of the module (without mod_ prefix).
+ * @return bool true if the module uses questions.
+ */
+function question_module_uses_questions($modname) {
+    if (plugin_supports('mod', $modname, FEATURE_USES_QUESTIONS)) {
+        return true;
+    }
+
+    $component = 'mod_'.$modname;
+    if (component_callback_exists($component, 'question_pluginfile')) {
+        debugging("{$component} uses questions but doesn't declare FEATURE_USES_QUESTIONS", DEBUG_DEVELOPER);
+        return true;
+    }
+
+    return false;
+}
index 9f4809d..4429c0e 100644 (file)
@@ -96,6 +96,8 @@ Navigation:
     * print_navigation()                    -> $OUTPUT->navbar()
     * build_navigation()                    -> $PAGE->navbar methods
     * navmenu()                             -> (no replacement)
+    * settings_navigation::
+          get_course_modules()              -> (no replacement)
 
 Calendar:
     * add_event()                           -> calendar_event::create()
index 9fd88b0..919b97c 100644 (file)
@@ -150,7 +150,8 @@ if (!empty($user)) {
                 or (!is_siteadmin($user) && has_capability('moodle/webservice:createtoken', context_system::instance()))) {
             // if service doesn't exist, dml will throw exception
             $service_record = $DB->get_record('external_services', array('shortname'=>$serviceshortname, 'enabled'=>1), '*', MUST_EXIST);
-            // create a new token
+
+            // Create a new token.
             $token = new stdClass;
             $token->token = md5(uniqid(rand(), 1));
             $token->userid = $user->id;
@@ -159,9 +160,18 @@ if (!empty($user)) {
             $token->creatorid = $user->id;
             $token->timecreated = time();
             $token->externalserviceid = $service_record->id;
-            $tokenid = $DB->insert_record('external_tokens', $token);
-            add_to_log(SITEID, 'webservice', 'automatically create user token', '' , 'User ID: ' . $user->id);
-            $token->id = $tokenid;
+            $token->id = $DB->insert_record('external_tokens', $token);
+
+            $params = array(
+                'objectid' => $token->id,
+                'relateduserid' => $user->id,
+                'other' => array(
+                    'auto' => true
+                )
+            );
+            $event = \core\event\webservice_token_created::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->trigger();
         } else {
             throw new moodle_exception('cannotcreatetoken', 'webservice', '', $serviceshortname);
         }
@@ -170,7 +180,12 @@ if (!empty($user)) {
     // log token access
     $DB->set_field('external_tokens', 'lastaccess', time(), array('id'=>$token->id));
 
-    add_to_log(SITEID, 'webservice', 'sending requested user token', '' , 'User ID: ' . $user->id);
+    $params = array(
+        'objectid' => $token->id,
+    );
+    $event = \core\event\webservice_token_sent::create($params);
+    $event->add_record_snapshot('external_tokens', $token);
+    $event->trigger();
 
     $usertoken = new stdClass;
     $usertoken->token = $token->token;
index c6394ad..7aa48c5 100644 (file)
@@ -1547,6 +1547,7 @@ function quiz_supports($feature) {
         case FEATURE_BACKUP_MOODLE2:            return true;
         case FEATURE_SHOW_DESCRIPTION:          return true;
         case FEATURE_CONTROLS_GRADE_VISIBILITY: return true;
+        case FEATURE_USES_QUESTIONS:            return true;
 
         default: return null;
     }
diff --git a/mod/quiz/report/statistics/classes/calculated.php b/mod/quiz/report/statistics/classes/calculated.php
new file mode 100644 (file)
index 0000000..40a6210
--- /dev/null
@@ -0,0 +1,218 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * The statistics calculator returns an instance of this class which contains the calculated statistics.
+ *
+ * These quiz statistics calculations are described here :
+ *
+ * http://docs.moodle.org/dev/Quiz_statistics_calculations#Test_statistics
+ *
+ * @package    quiz_statistics
+ * @copyright  2013 The Open University
+ * @author     James Pratt me@jamiep.org
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class quiz_statistics_calculated {
+
+    public function __construct($allattempts = null) {
+        if ($allattempts !== null) {
+            $this->allattempts = $allattempts;
+        }
+    }
+
+    /**
+     * @var bool whether we are calculating calculate stats from all attempts.
+     */
+    public $allattempts;
+
+    /* Following stats all described here : http://docs.moodle.org/dev/Quiz_statistics_calculations#Test_statistics  */
+
+    public $firstattemptscount = 0;
+
+    public $allattemptscount = 0;
+
+    public $firstattemptsavg;
+
+    public $allattemptsavg;
+
+    public $median;
+
+    public $standarddeviation;
+
+    public $skewness;
+
+    public $kurtosis;
+
+    public $cic;
+
+    public $errorratio;
+
+    public $standarderror;
+
+    /**
+     * @var int time these stats where calculated and cached.
+     */
+    public $timemodified;
+
+    public function s() {
+        if ($this->allattempts) {
+            return $this->allattemptscount;
+        } else {
+            return $this->firstattemptscount;
+        }
+    }
+
+    public function avg() {
+        if ($this->allattempts) {
+            return $this->allattemptsavg;
+        } else {
+            return $this->firstattemptsavg;
+        }
+    }
+
+    /**
+     * @param $course
+     * @param $cm
+     * @param $quiz
+     * @return array to display in table or spreadsheet.
+     */
+    public function get_formatted_quiz_info_data($course, $cm, $quiz) {
+
+        // You can edit this array to control which statistics are displayed.
+        $todisplay = array('firstattemptscount' => 'number',
+                           'allattemptscount' => 'number',
+                           'firstattemptsavg' => 'summarks_as_percentage',
+                           'allattemptsavg' => 'summarks_as_percentage',
+                           'median' => 'summarks_as_percentage',
+                           'standarddeviation' => 'summarks_as_percentage',
+                           'skewness' => 'number_format',
+                           'kurtosis' => 'number_format',
+                           'cic' => 'number_format_percent',
+                           'errorratio' => 'number_format_percent',
+                           'standarderror' => 'summarks_as_percentage');
+
+        // General information about the quiz.
+        $quizinfo = array();
+        $quizinfo[get_string('quizname', 'quiz_statistics')] = format_string($quiz->name);
+        $quizinfo[get_string('coursename', 'quiz_statistics')] = format_string($course->fullname);
+        if ($cm->idnumber) {
+            $quizinfo[get_string('idnumbermod')] = $cm->idnumber;
+        }
+        if ($quiz->timeopen) {
+            $quizinfo[get_string('quizopen', 'quiz')] = userdate($quiz->timeopen);
+        }
+        if ($quiz->timeclose) {
+            $quizinfo[get_string('quizclose', 'quiz')] = userdate($quiz->timeclose);
+        }
+        if ($quiz->timeopen && $quiz->timeclose) {
+            $quizinfo[get_string('duration', 'quiz_statistics')] =
+                format_time($quiz->timeclose - $quiz->timeopen);
+        }
+
+        // The statistics.
+        foreach ($todisplay as $property => $format) {
+            if (!isset($this->$property) || !$format) {
+                continue;
+            }
+            $value = $this->$property;
+
+            switch ($format) {
+                case 'summarks_as_percentage':
+                    $formattedvalue = quiz_report_scale_summarks_as_percentage($value, $quiz);
+                    break;
+                case 'number_format_percent':
+                    $formattedvalue = quiz_format_grade($quiz, $value) . '%';
+                    break;
+                case 'number_format':
+                    // 2 extra decimal places, since not a percentage,
+                    // and we want the same number of sig figs.
+                    $formattedvalue = format_float($value, $quiz->decimalpoints + 2);
+                    break;
+                case 'number':
+                    $formattedvalue = $value + 0;
+                    break;
+                default:
+                    $formattedvalue = $value;
+            }
+
+            $quizinfo[get_string($property, 'quiz_statistics', $this->using_attempts_string())] = $formattedvalue;
+        }
+
+        return $quizinfo;
+    }
+
+    /**
+     * @return string the appropriate lang string to describe this option.
+     */
+    protected function using_attempts_string() {
+        if ($this->allattempts) {
+            return get_string('allattempts', 'quiz_statistics');
+        } else {
+            return get_string('firstattempts', 'quiz_statistics');
+        }
+    }
+
+
+    /**
+     * @var array of names of properties of this class that are cached in db record.
+     */
+    protected $fieldsindb = array('allattempts', 'firstattemptscount', 'allattemptscount', 'firstattemptsavg', 'allattemptsavg',
+                                    'median', 'standarddeviation', 'skewness',
+                                    'kurtosis', 'cic', 'errorratio', 'standarderror');
+
+    /**
+     * Cache the stats contained in this class.
+     *
+     * @param $qubaids qubaid_condition
+     */
+    public function cache($qubaids) {
+        global $DB;
+
+        $toinsert = new stdClass();
+
+        foreach ($this->fieldsindb as $field) {
+            $toinsert->{$field} = $this->{$field};
+        }
+
+        $toinsert->hashcode = $qubaids->get_hash_code();
+        $toinsert->timemodified = time();
+
+        // Fix up some dodgy data.
+        if (isset($toinsert->errorratio) && is_nan($toinsert->errorratio)) {
+            $toinsert->errorratio = null;
+        }
+        if (isset($toinsert->standarderror) && is_nan($toinsert->standarderror)) {
+            $toinsert->standarderror = null;
+        }
+
+        // Store the data.
+        $DB->insert_record('quiz_statistics', $toinsert);
+
+    }
+
+    /**
+     * Given a record from 'quiz_statistics' table load the data into the properties of this class.
+     *
+     * @param $record from db.
+     */
+    public function populate_from_record($record) {
+        foreach ($this->fieldsindb as $field) {
+            $this->$field = $record->$field;
+        }
+        $this->timemodified = $record->timemodified;
+    }
+}
diff --git a/mod/quiz/report/statistics/classes/calculator.php b/mod/quiz/report/statistics/classes/calculator.php
new file mode 100644 (file)
index 0000000..6a0d6b8
--- /dev/null
@@ -0,0 +1,250 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Class to calculate and also manage caching of quiz statistics.
+ *
+ * These quiz statistics calculations are described here :
+ *
+ * http://docs.moodle.org/dev/Quiz_statistics_calculations#Test_statistics
+ *
+ * @package    quiz_statistics
+ * @copyright  2013 The Open University
+ * @author     James Pratt me@jamiep.org
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class quiz_statistics_calculator {
+
+    /**
+     * Compute the quiz statistics.
+     *
+     * @param int   $quizid            the quiz id.
+     * @param int   $currentgroup      the current group. 0 for none.
+     * @param bool  $useallattempts    use all attempts, or just first attempts.
+     * @param array $groupstudents     students in this group.
+     * @param int   $p                 number of positions (slots).
+     * @param float $sumofmarkvariance sum of mark variance, calculated as part of question statistics
+     * @return array with two elements:
+     *      - integer $s Number of attempts included in the stats.
+     *      - object $quizstats The statistics for overall attempt scores.
+     */
+    public function calculate($quizid, $currentgroup, $useallattempts, $groupstudents, $p, $sumofmarkvariance) {
+
+        $quizstats = $this->attempt_counts_and_averages($quizid, $currentgroup, $useallattempts, $groupstudents);
+
+        $s = $quizstats->s();
+
+        if ($s == 0) {
+            return $quizstats;
+        }
+
+        // Recalculate sql again this time possibly including test for first attempt.
+        list($fromqa, $whereqa, $qaparams) =
+            quiz_statistics_attempts_sql($quizid, $currentgroup, $groupstudents, $useallattempts);
+
+        $quizstats->median = $this->median($s, $fromqa, $whereqa, $qaparams);
+
+        if ($s > 1) {
+
+            $powers = $this->sum_of_powers_of_difference_to_mean($quizstats->avg(), $fromqa, $whereqa, $qaparams);
+
+            $quizstats->standarddeviation = sqrt($powers->power2 / ($s - 1));
+
+            // Skewness.
+            if ($s > 2) {
+                // See http://docs.moodle.org/dev/Quiz_item_analysis_calculations_in_practise#Skewness_and_Kurtosis.
+                $m2 = $powers->power2 / $s;
+                $m3 = $powers->power3 / $s;
+                $m4 = $powers->power4 / $s;
+
+                $k2 = $s * $m2 / ($s - 1);
+                $k3 = $s * $s * $m3 / (($s - 1) * ($s - 2));
+                if ($k2 != 0) {
+                    $quizstats->skewness = $k3 / (pow($k2, 3 / 2));
+
+                    // Kurtosis.
+                    if ($s > 3) {
+                        $k4 = $s * $s * ((($s + 1) * $m4) - (3 * ($s - 1) * $m2 * $m2)) / (($s - 1) * ($s - 2) * ($s - 3));
+                        $quizstats->kurtosis = $k4 / ($k2 * $k2);
+                    }
+
+                    if ($p > 1) {
+                        $quizstats->cic = (100 * $p / ($p -1)) * (1 - ($sumofmarkvariance / $k2));
+                        $quizstats->errorratio = 100 * sqrt(1 - ($quizstats->cic / 100));
+                        $quizstats->standarderror = $quizstats->errorratio *
+                            $quizstats->standarddeviation / 100;
+                    }
+                }
+
+            }
+        }
+
+
+        $quizstats->cache(quiz_statistics_qubaids_condition($quizid, $currentgroup, $groupstudents, $useallattempts));
+
+        return $quizstats;
+    }
+
+    /** @var integer Time after which statistics are automatically recomputed. */
+    const TIME_TO_CACHE = 900; // 15 minutes.
+
+    /**
+     * Load cached statistics from the database.
+     *
+     * @param $qubaids qubaid_condition
+     * @return quiz_statistics_calculated The statistics for overall attempt scores or false if not cached.
+     */
+    public function get_cached($qubaids) {
+        global $DB;
+
+        $timemodified = time() - self::TIME_TO_CACHE;
+        $fromdb = $DB->get_record_select('quiz_statistics', 'hashcode = ? AND timemodified > ?',
+                                         array($qubaids->get_hash_code(), $timemodified));
+        $stats = new quiz_statistics_calculated();
+        $stats->populate_from_record($fromdb);
+        return $stats;
+    }
+
+    /**
+     * Find time of non-expired statistics in the database.
+     *
+     * @param $qubaids qubaid_condition
+     * @return integer|boolean Time of cached record that matches this qubaid_condition or false is non found.
+     */
+    public function get_last_calculated_time($qubaids) {
+        global $DB;
+
+        $timemodified = time() - self::TIME_TO_CACHE;
+        return $DB->get_field_select('quiz_statistics', 'timemodified', 'hashcode = ? AND timemodified > ?',
+                                         array($qubaids->get_hash_code(), $timemodified));
+    }
+
+    /**
+     * Calculating count and mean of marks for first and ALL attempts by students.
+     *
+     * See : http://docs.moodle.org/dev/Quiz_item_analysis_calculations_in_practise
+     *                                      #Calculating_MEAN_of_grades_for_all_attempts_by_students
+     * @param int $quizid
+     * @param int $currentgroup
+     * @param bool $useallattempts
+     * @param array $groupstudents
+     * @return quiz_statistics_calculated containing calculated counts, totals and averages.
+     */
+    protected function attempt_counts_and_averages($quizid, $currentgroup, $useallattempts, $groupstudents) {
+        global $DB;
+
+        $quizstats = new quiz_statistics_calculated($useallattempts);
+
+        list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql($quizid, $currentgroup, $groupstudents, true);
+
+        $attempttotals = $DB->get_records_sql("
+                SELECT
+                    CASE WHEN attempt = 1 THEN 1 ELSE 0 END AS isfirst,
+                    COUNT(1) AS countrecs,
+                    SUM(sumgrades) AS total
+                FROM $fromqa
+                WHERE $whereqa
+                GROUP BY CASE WHEN attempt = 1 THEN 1 ELSE 0 END", $qaparams);
+
+        // Above query that returns sums and counts for first attempt and other non first attempts.
+        // We want to work out stats for first attempt or ALL attempts.
+
+        if (isset($attempttotals[1])) {
+            $quizstats->firstattemptscount = $attempttotals[1]->countrecs;
+            $firstattemptstotal = $attempttotals[1]->total;
+        } else {
+            $quizstats->firstattemptscount = 0;
+            $firstattemptstotal = 0;
+        }
+
+        if (isset($attempttotals[0])) {
+            $quizstats->allattemptscount = $quizstats->firstattemptscount + $attempttotals[0]->countrecs;
+            $allattemptstotal = $firstattemptstotal + $attempttotals[0]->total;
+        } else {
+            $quizstats->allattemptscount = $quizstats->firstattemptscount;
+            $allattemptstotal = $firstattemptstotal;
+        }
+
+        if ($quizstats->allattemptscount !== 0) {
+            $quizstats->allattemptsavg = $allattemptstotal / $quizstats->allattemptscount;
+        }
+
+        if ($quizstats->firstattemptscount !== 0) {
+            $quizstats->firstattemptsavg = $firstattemptstotal / $quizstats->firstattemptscount;
+        }
+
+        return $quizstats;
+    }
+
+    /**
+     * Median mark.
+     *
+     * http://docs.moodle.org/dev/Quiz_statistics_calculations#Median_Score
+     *
+     * @param $s integer count of attempts
+     * @param $fromqa string
+     * @param $whereqa string
+     * @param $qaparams string
+     * @return float
+     */
+    protected function median($s, $fromqa, $whereqa, $qaparams) {
+        global $DB;
+
+        if ($s % 2 == 0) {
+            // An even number of attempts.
+            $limitoffset = $s / 2 - 1;
+            $limit = 2;
+        } else {
+            $limitoffset = floor($s / 2);
+            $limit = 1;
+        }
+        $sql = "SELECT id, sumgrades
+                FROM $fromqa
+                WHERE $whereqa
+                ORDER BY sumgrades";
+
+        $medianmarks = $DB->get_records_sql_menu($sql, $qaparams, $limitoffset, $limit);
+
+        return array_sum($medianmarks) / count($medianmarks);
+    }
+
+    /**
+     * Fetch the sum of squared, cubed and to the power 4 differences between sumgrade and it's mean.
+     *
+     * Explanation here : http://docs.moodle.org/dev/Quiz_item_analysis_calculations_in_practise
+     *              #Calculating_Standard_Deviation.2C_Skewness_and_Kurtosis_of_grades_for_all_attempts_by_students
+     *
+     * @param $mean
+     * @param $fromqa
+     * @param $whereqa
+     * @param $qaparams
+     * @return object with properties power2, power3, power4
+     */
+    protected function sum_of_powers_of_difference_to_mean($mean, $fromqa, $whereqa, $qaparams) {
+        global $DB;
+
+        $sql = "SELECT
+                    SUM(POWER((quiza.sumgrades - $mean), 2)) AS power2,
+                    SUM(POWER((quiza.sumgrades - $mean), 3)) AS power3,
+                    SUM(POWER((quiza.sumgrades - $mean), 4)) AS power4
+                    FROM $fromqa
+                    WHERE $whereqa";
+        $params = array('mean1' => $mean, 'mean2' => $mean, 'mean3' => $mean) + $qaparams;
+
+        return $DB->get_record_sql($sql, $params, MUST_EXIST);
+    }
+
+}
index 9db615c..21d88ac 100644 (file)
@@ -31,7 +31,6 @@ require_once($CFG->dirroot . '/mod/quiz/report/statistics/statistics_question_ta
 require_once($CFG->dirroot . '/question/engine/statistics.php');
 require_once($CFG->dirroot . '/question/engine/responseanalysis.php');
 require_once($CFG->dirroot . '/mod/quiz/report/statistics/statisticslib.php');
-
 /**
  * The quiz statistics report provides summary information about each question in
  * a quiz, compared to the whole quiz. It also provides a drill-down to more
@@ -41,8 +40,11 @@ require_once($CFG->dirroot . '/mod/quiz/report/statistics/statisticslib.php');
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class quiz_statistics_report extends quiz_default_report {
-    /** @var integer Time after which statistics are automatically recomputed. */
-    const TIME_TO_CACHE_STATS = 900; // 15 minutes.
+
+    /**
+     * @var context_module
+     */
+    protected $context;
 
     /** @var object instance of table class used for main questions stats table. */
     protected $table;
@@ -127,15 +129,22 @@ class quiz_statistics_report extends quiz_default_report {
                 get_string('quizstructureanalysis', 'quiz_statistics'));
         $questions = $this->load_and_initialise_questions_for_calculations($quiz);
 
-        // Get the data to be displayed.
-        list($quizstats, $questions, $subquestions, $s) =
-                $this->get_quiz_and_questions_stats($quiz, $currentgroup,
-                        $nostudentsingroup, $useallattempts, $groupstudents, $questions);
-        $quizinfo = $this->get_formatted_quiz_info_data($course, $cm, $quiz, $quizstats);
+        if (!$nostudentsingroup) {
+            // Get the data to be displayed.
+            list($quizstats, $questions, $subquestions) =
+                $this->get_quiz_and_questions_stats($quiz, $currentgroup, $useallattempts, $groupstudents, $questions);
+        } else {
+            // Or create empty stats containers.
+            $quizstats = new quiz_statistics_calculated($useallattempts);
+            $qstats = new question_statistics($questions);
+            $questions = $qstats->questions;
+            $subquestions = $qstats->subquestions;
+        }
+        $quizinfo = $quizstats->get_formatted_quiz_info_data($course, $cm, $quiz);
 
         // Set up the table, if there is data.
-        if ($s) {
-            $this->table->statistics_setup($quiz, $cm->id, $reporturl, $s);
+        if ($quizstats->s()) {
+            $this->table->statistics_setup($quiz, $cm->id, $reporturl, $quizstats->s());
         }
 
         // Print the page header stuff (if not downloading.
@@ -151,7 +160,7 @@ class quiz_statistics_report extends quiz_default_report {
 
             if (!quiz_questions_in_quiz($quiz->questions)) {
                 echo quiz_no_questions_message($quiz, $cm, $this->context);
-            } else if (!$this->table->is_downloading() && $s == 0) {
+            } else if (!$this->table->is_downloading() && $quizstats->s() == 0) {
                 echo $OUTPUT->notification(get_string('noattempts', 'quiz'));
             }
 
@@ -164,10 +173,10 @@ class quiz_statistics_report extends quiz_default_report {
             // Overall report, then the analysis of each question.
             $this->download_quiz_info_table($quizinfo);
 
-            if ($s) {
-                $this->output_quiz_structure_analysis_table($s, $questions, $subquestions);
+            if ($quizstats->s()) {
+                $this->output_quiz_structure_analysis_table($quizstats->s(), $questions, $subquestions);
 
-                if ($this->table->is_downloading() == 'xhtml' && $s != 0) {
+                if ($this->table->is_downloading() == 'xhtml' && $quizstats->s() != 0) {
                     $this->output_statistics_graph($quiz->id, $currentgroup, $useallattempts);
                 }
 
@@ -222,7 +231,7 @@ class quiz_statistics_report extends quiz_default_report {
         } else if ($this->table->is_downloading()) {
             // Downloading overview report.
             $this->download_quiz_info_table($quizinfo);
-            $this->output_quiz_structure_analysis_table($s, $questions, $subquestions);
+            $this->output_quiz_structure_analysis_table($quizstats->s(), $questions, $subquestions);
             $this->table->finish_output();
 
         } else {
@@ -232,9 +241,9 @@ class quiz_statistics_report extends quiz_default_report {
                     $groupstudents, $useallattempts, $reporturl);
             echo $this->everything_download_options();
             echo $this->output_quiz_info_table($quizinfo);
-            if ($s) {
+            if ($quizstats->s()) {
                 echo $OUTPUT->heading(get_string('quizstructureanalysis', 'quiz_statistics'));
-                $this->output_quiz_structure_analysis_table($s, $questions, $subquestions);
+                $this->output_quiz_structure_analysis_table($quizstats->s(), $questions, $subquestions);
                 $this->output_statistics_graph($quiz->id, $currentgroup, $useallattempts);
             }
         }
@@ -433,73 +442,6 @@ class quiz_statistics_report extends quiz_default_report {
         $this->table->finish_output(!$this->table->is_downloading());
     }
 
-    protected function get_formatted_quiz_info_data($course, $cm, $quiz, $quizstats) {
-
-        // You can edit this array to control which statistics are displayed.
-        $todisplay = array('firstattemptscount' => 'number',
-                    'allattemptscount' => 'number',
-                    'firstattemptsavg' => 'summarks_as_percentage',
-                    'allattemptsavg' => 'summarks_as_percentage',
-                    'median' => 'summarks_as_percentage',
-                    'standarddeviation' => 'summarks_as_percentage',
-                    'skewness' => 'number_format',
-                    'kurtosis' => 'number_format',
-                    'cic' => 'number_format_percent',
-                    'errorratio' => 'number_format_percent',
-                    'standarderror' => 'summarks_as_percentage');
-
-        // General information about the quiz.
-        $quizinfo = array();
-        $quizinfo[get_string('quizname', 'quiz_statistics')] = format_string($quiz->name);
-        $quizinfo[get_string('coursename', 'quiz_statistics')] = format_string($course->fullname);
-        if ($cm->idnumber) {
-            $quizinfo[get_string('idnumbermod')] = $cm->idnumber;
-        }
-        if ($quiz->timeopen) {
-            $quizinfo[get_string('quizopen', 'quiz')] = userdate($quiz->timeopen);
-        }
-        if ($quiz->timeclose) {
-            $quizinfo[get_string('quizclose', 'quiz')] = userdate($quiz->timeclose);
-        }
-        if ($quiz->timeopen && $quiz->timeclose) {
-            $quizinfo[get_string('duration', 'quiz_statistics')] =
-                    format_time($quiz->timeclose - $quiz->timeopen);
-        }
-
-        // The statistics.
-        foreach ($todisplay as $property => $format) {
-            if (!isset($quizstats->$property) || !$format) {
-                continue;
-            }
-            $value = $quizstats->$property;
-
-            switch ($format) {
-                case 'summarks_as_percentage':
-                    $formattedvalue = quiz_report_scale_summarks_as_percentage($value, $quiz);
-                    break;
-                case 'number_format_percent':
-                    $formattedvalue = quiz_format_grade($quiz, $value) . '%';
-                    break;
-                case 'number_format':
-                    // 2 extra decimal places, since not a percentage,
-                    // and we want the same number of sig figs.
-                    $formattedvalue = format_float($value, $quiz->decimalpoints + 2);
-                    break;
-                case 'number':
-                    $formattedvalue = $value + 0;
-                    break;
-                default:
-                    $formattedvalue = $value;
-            }
-
-            $quizinfo[get_string($property, 'quiz_statistics',
-                    $this->using_attempts_string(!empty($quizstats->allattempts)))] =
-                    $formattedvalue;
-        }
-
-        return $quizinfo;
-    }
-
     /**
      * Output the table of overall quiz statistics.
      * @param array $quizinfo as returned by {@link get_formatted_quiz_info_data()}.
@@ -566,222 +508,12 @@ class quiz_statistics_report extends quiz_default_report {
         echo $output->graph($imageurl, $graphname);
     }
 
-    /**
-     * Return the stats data for when there are no stats to show.
-     *
-     * @param int $firstattemptscount number of first attempts (optional).
-     * @param int $allattemptscount total number of attempts (optional).
-     * @return array with two elements:
-     *      - integer $s Number of attempts included in the stats (0).
-     *      - object $quizstats The statistics for overall attempt scores.
-     */
-    protected function get_empty_stats($firstattemptscount = 0, $allattemptscount = 0) {
-        $quizstats = new stdClass();
-        $quizstats->firstattemptscount = $firstattemptscount;
-        $quizstats->allattemptscount = $allattemptscount;
-
-        return array(0, $quizstats);
-    }
-
-    /**
-     * Compute the quiz statistics.
-     *
-     * @param int   $quizid            the quiz id.
-     * @param int   $currentgroup      the current group. 0 for none.
-     * @param bool  $useallattempts    use all attempts, or just first attempts.
-     * @param array $groupstudents     students in this group.
-     * @param int   $p                 number of positions (slots).
-     * @param float $sumofmarkvariance sum of mark variance, calculated as part of question statistics
-     * @return array with two elements:
-     *      - integer $s Number of attempts included in the stats.
-     *      - object $quizstats The statistics for overall attempt scores.
-     */
-    protected function calculate_quiz_stats($quizid, $currentgroup, $useallattempts, $groupstudents, $p, $sumofmarkvariance) {
-        global $DB;
-
-        // Calculating MEAN of marks for all attempts by students
-        // http://docs.moodle.org/dev/Quiz_item_analysis_calculations_in_practise
-        //     #Calculating_MEAN_of_grades_for_all_attempts_by_students.
-        list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql(
-                $quizid, $currentgroup, $groupstudents, true);
-
-        $attempttotals = $DB->get_records_sql("
-                SELECT
-                    CASE WHEN attempt = 1 THEN 1 ELSE 0 END AS isfirst,
-                    COUNT(1) AS countrecs,
-                    SUM(sumgrades) AS total
-                FROM $fromqa
-                WHERE $whereqa
-                GROUP BY CASE WHEN attempt = 1 THEN 1 ELSE 0 END", $qaparams);
-
-        if (!$attempttotals) {
-            return $this->get_empty_stats();
-        }
-
-        if (isset($attempttotals[1])) {
-            $firstattempts = $attempttotals[1];
-            $firstattempts->average = $firstattempts->total / $firstattempts->countrecs;
-        } else {
-            $firstattempts = new stdClass();
-            $firstattempts->countrecs = 0;
-            $firstattempts->total = 0;
-            $firstattempts->average = null;
-        }
-
-        $allattempts = new stdClass();
-        if (isset($attempttotals[0])) {
-            $allattempts->countrecs = $firstattempts->countrecs + $attempttotals[0]->countrecs;
-            $allattempts->total = $firstattempts->total + $attempttotals[0]->total;
-        } else {
-            $allattempts->countrecs = $firstattempts->countrecs;
-            $allattempts->total = $firstattempts->total;
-        }
-
-        if ($useallattempts) {
-            $usingattempts = $allattempts;
-            $usingattempts->sql = '';
-        } else {
-            $usingattempts = $firstattempts;
-            $usingattempts->sql = 'AND quiza.attempt = 1 ';
-        }
-
-        $s = $usingattempts->countrecs;
-        if ($s == 0) {
-            return $this->get_empty_stats($firstattempts->countrecs, $allattempts->countrecs);
-        }
-
-        $quizstats = new stdClass();
-        $quizstats->allattempts = $useallattempts;
-        $quizstats->firstattemptscount = $firstattempts->countrecs;
-        $quizstats->allattemptscount = $allattempts->countrecs;
-        $quizstats->firstattemptsavg = $firstattempts->average;
-        $quizstats->allattemptsavg = $allattempts->total / $allattempts->countrecs;
-
-        // Recalculate sql again this time possibly including test for first attempt.
-        list($fromqa, $whereqa, $qaparams) = quiz_statistics_attempts_sql(
-                $quizid, $currentgroup, $groupstudents, $useallattempts);
-
-        // Median ...
-        if ($s % 2 == 0) {
-            // An even number of attempts.
-            $limitoffset = $s/2 - 1;
-            $limit = 2;
-        } else {
-            $limitoffset = floor($s/2);
-            $limit = 1;
-        }
-        $sql = "SELECT id, sumgrades
-                FROM $fromqa
-                WHERE $whereqa
-                ORDER BY sumgrades";
-
-        $medianmarks = $DB->get_records_sql_menu($sql, $qaparams, $limitoffset, $limit);
-
-        $quizstats->median = array_sum($medianmarks) / count($medianmarks);
-        if ($s > 1) {
-            // Fetch the sum of squared, cubed and power 4d
-            // differences between marks and mean mark.
-            $mean = $usingattempts->total / $s;
-            $sql = "SELECT
-                    SUM(POWER((quiza.sumgrades - $mean), 2)) AS power2,
-                    SUM(POWER((quiza.sumgrades - $mean), 3)) AS power3,
-                    SUM(POWER((quiza.sumgrades - $mean), 4)) AS power4
-                    FROM $fromqa
-                    WHERE $whereqa";
-            $params = array('mean1' => $mean, 'mean2' => $mean, 'mean3' => $mean)+$qaparams;
-
-            $powers = $DB->get_record_sql($sql, $params, MUST_EXIST);
-
-            // Standard_Deviation:
-            // see http://docs.moodle.org/dev/Quiz_item_analysis_calculations_in_practise
-            //         #Standard_Deviation.
-
-            $quizstats->standarddeviation = sqrt($powers->power2 / ($s - 1));
-
-            // Skewness.
-            if ($s > 2) {
-                // See http://docs.moodle.org/dev/
-                //      Quiz_item_analysis_calculations_in_practise#Skewness_and_Kurtosis.
-                $m2= $powers->power2 / $s;
-                $m3= $powers->power3 / $s;
-                $m4= $powers->power4 / $s;
-
-                $k2= $s*$m2/($s-1);
-                $k3= $s*$s*$m3/(($s-1)*($s-2));
-                if ($k2) {
-                    $quizstats->skewness = $k3 / (pow($k2, 3/2));
-                }
-
-                // Kurtosis.
-                if ($s > 3) {
-                    $k4= $s*$s*((($s+1)*$m4)-(3*($s-1)*$m2*$m2))/(($s-1)*($s-2)*($s-3));
-                    if ($k2) {
-                        $quizstats->kurtosis = $k4 / ($k2*$k2);
-                    }
-                }
-            }
-        }
-
-        if ($s > 1) {
-            if ($p > 1 && isset($k2)) {
-                $quizstats->cic = (100 * $p / ($p -1)) *
-                        (1 - ($sumofmarkvariance / $k2));
-                $quizstats->errorratio = 100 * sqrt(1 - ($quizstats->cic / 100));
-                $quizstats->standarderror = $quizstats->errorratio *
-                        $quizstats->standarddeviation / 100;
-            }
-        }
-
-        $this->cache_stats(quiz_statistics_qubaids_condition($quizid, $currentgroup, $groupstudents, $useallattempts), $quizstats);
-
-        return array($s, $quizstats);
-    }
-
-    /**
-     * Load the cached statistics from the database.
-     *
-     * @param $qubaids qubaid_condition
-     * @return The statistics for overall attempt scores or false if not cached.
-     */
-    protected function get_cached_quiz_stats($qubaids) {
-        global $DB;
-
-        $timemodified = time() - self::TIME_TO_CACHE_STATS;
-        return  $DB->get_record_select('quiz_statistics', 'hashcode = ? AND timemodified > ?',
-                                       array($qubaids->get_hash_code(), $timemodified));
-    }
-
-    /**
-     * @param $qubaids    qubaid_condition
-     * @param $quizstats  object            the quiz stats to cache
-     */
-    protected function cache_stats($qubaids, $quizstats) {
-        global $DB;
-
-        $toinsert = clone($quizstats);
-        $toinsert->hashcode = $qubaids->get_hash_code();
-        $toinsert->timemodified = time();
-
-        // Fix up some dodgy data.
-        if (isset($toinsert->errorratio) && is_nan($toinsert->errorratio)) {
-            $toinsert->errorratio = null;
-        }
-        if (isset($toinsert->standarderror) && is_nan($toinsert->standarderror)) {
-            $toinsert->standarderror = null;
-        }
-
-        // Store the data.
-        $DB->insert_record('quiz_statistics', $toinsert);
-
-    }
-
     /**
      * Get the quiz and question statistics, either by loading the cached results,
      * or by recomputing them.
      *
      * @param object $quiz the quiz settings.
      * @param int $currentgroup the current group. 0 for none.
-     * @param bool $nostudentsingroup true if there a no students.
      * @param bool $useallattempts use all attempts, or just first attempts.
      * @param array $groupstudents students in this group.
      * @param array $questions question definitions.
@@ -791,45 +523,36 @@ class quiz_statistics_report extends quiz_default_report {
      *     - $subquestions The subquestions, if any, with an additional _stats field.
      *     - $s Number of attempts included in the stats.
      */
-    protected function get_quiz_and_questions_stats($quiz, $currentgroup,
-            $nostudentsingroup, $useallattempts, $groupstudents, $questions) {
+    protected function get_quiz_and_questions_stats($quiz, $currentgroup, $useallattempts, $groupstudents, $questions) {
 
         $qubaids = quiz_statistics_qubaids_condition($quiz->id, $currentgroup, $groupstudents, $useallattempts);
 
-        $quizstats = $this->get_cached_quiz_stats($qubaids);
 
         $qstats = new question_statistics($questions);
 
-        if (empty($quizstats)) {
+        $quizcalc = new quiz_statistics_calculator();
+
+        if ($quizcalc->get_last_calculated_time($qubaids) === false) {
             // Recalculate now.
             $qstats->calculate($qubaids);
 
-            if ($nostudentsingroup) {
-                list($s, $quizstats) = $this->get_empty_stats();
-            } else {
-                list($s, $quizstats) = $this->calculate_quiz_stats($quiz->id, $currentgroup, $useallattempts,
-                                                           $groupstudents, count($questions), $qstats->get_sum_of_mark_variance());
-            }
+            $quizstats = $quizcalc->calculate($quiz->id, $currentgroup, $useallattempts,
+                                               $groupstudents, count($questions), $qstats->get_sum_of_mark_variance());
 
             $questions = $qstats->questions;
             $subquestions = $qstats->subquestions;
 
-            if ($s) {
+            if ($quizstats->s()) {
                 $this->calculate_responses_for_all_questions_and_subquestions($qubaids, $questions, $subquestions);
             }
         } else {
-            if ($useallattempts) {
-                $s = $quizstats->allattemptscount;
-            } else {
-                $s = $quizstats->firstattemptscount;
-            }
+            $quizstats = $quizcalc->get_cached($qubaids);
             $qstats->get_cached($qubaids);
             $questions = $qstats->questions;
             $subquestions = $qstats->subquestions;
-
         }
 
-        return array($quizstats, $questions, $subquestions, $s);
+        return array($quizstats, $questions, $subquestions);
     }
 
     protected function calculate_responses_for_all_questions_and_subquestions($qubaids, $questions, $subquestions) {
@@ -942,18 +665,6 @@ class quiz_statistics_report extends quiz_default_report {
         $DB->delete_records('question_response_analysis', array('hashcode' => $qubaids->get_hash_code()));
     }
 
-    /**
-     * @param bool $useallattempts whether we are using all attempts.
-     * @return the appropriate lang string to describe this option.
-     */
-    protected function using_attempts_string($useallattempts) {
-        if ($useallattempts) {
-            return get_string('allattempts', 'quiz_statistics');
-        } else {
-            return get_string('firstattempts', 'quiz_statistics');
-        }
-    }
-
     /**
      * @param object $quiz the quiz.
      * @return array of questions for this quiz.
index be6c7a9..6f762b3 100644 (file)
@@ -64,8 +64,7 @@ $qubaids = quiz_statistics_qubaids_condition($quizid, $currentgroup, $groupstude
 // Load the rest of the required data.
 $questions = quiz_report_get_significant_questions($quiz);
 
-// Load enough data to check permissions.
-$quizstatistics = $DB->get_record('quiz_statistics', array('hashcode' => $qubaids->get_hash_code()));
+// Only load main question not sub questions.
 $questionstatistics = $DB->get_records_select('question_statistics', 'hashcode = ? AND slot IS NOT NULL',
                                               array($qubaids->get_hash_code()));
 
index 6e816ca..32cb585 100644 (file)
@@ -45,8 +45,7 @@ class testable_quiz_statistics_report extends quiz_statistics_report {
         $qubaids = quiz_statistics_qubaids_condition($quiz->id, $currentgroup, $groupstudents, $useallattempts);
         $this->clear_cached_data($qubaids);
         $questions = $this->load_and_initialise_questions_for_calculations($quiz);
-        return $this->get_quiz_and_questions_stats($quiz, $currentgroup, $nostudentsingroup,
-                                                   $useallattempts, $groupstudents, $questions);
+        return $this->get_quiz_and_questions_stats($quiz, $currentgroup, $useallattempts, $groupstudents, $questions);
     }
 }
 
@@ -95,7 +94,7 @@ class quiz_report_statistics_from_steps extends mod_quiz_attempt_walkthrough_fro
         $this->check_attempts_results($csvdata['results'], $attemptids);
 
         $this->report = new testable_quiz_statistics_report();
-        list($quizstats, $questions, $subquestions, $s) = $this->report->get_stats($this->quiz);
+        list($quizstats, $questions, $subquestions) = $this->report->get_stats($this->quiz);
 
         // These quiz stats and the question stats found in qstats00.csv were calculated independently in spreadsheet which is
         // available in open document or excel format here :
index c1e6329..7438376 100644 (file)
@@ -126,7 +126,7 @@ function scorm_add_instance($scorm, $mform=null) {
 
     // Store the package and verify.
     if ($record->scormtype === SCORM_TYPE_LOCAL) {
-        if ($data = $mform->get_data()) {
+        if ($mform && $data = $mform->get_data()) {
             $fs = get_file_storage();
             $fs->delete_area_files($context->id, 'mod_scorm', 'package');
             file_save_draft_area_files($data->packagefile, $context->id, 'mod_scorm', 'package',
@@ -202,7 +202,7 @@ function scorm_update_instance($scorm, $mform=null) {
     $context = context_module::instance($cmid);
 
     if ($scorm->scormtype === SCORM_TYPE_LOCAL) {
-        if ($data = $mform->get_data()) {
+        if ($mform && $data = $mform->get_data()) {
             $fs = get_file_storage();
             $fs->delete_area_files($context->id, 'mod_scorm', 'package');
             file_save_draft_area_files($data->packagefile, $context->id, 'mod_scorm', 'package',
index bc46994..daff632 100644 (file)
@@ -1,6 +1,14 @@
 This files describes API changes in /mod/* - activity modules,
 information provided here is intended especially for developers.
 
+=== 2.6 ===
+
+* Modules using the question bank MUST now declare their use of it with the xxx_supports()
+  flag FEATURE_USES_QUESTIONS.
+* xxx_get_types() module callback can now return subtypes that have
+  a custom help text set. Also instead of array it can now return
+  MOD_SUBTYPE_NO_CHILDREN. This is optional and still defaults to prior
+  behavior. See get_module_metadata() in course/lib.php for details.
 
 === 2.5 ===
 
index 546b0e2..d09431d 100644 (file)
@@ -386,7 +386,9 @@ class workshop_best_evaluation extends workshop_evaluation {
             $n     += $weight;
 
             // variations very close to zero are too sensitive to a small change of data values
-            if ($var > 0.01 and $agrade != $rgrade) {
+            $var = max($var, 0.01);
+
+            if ($agrade != $rgrade) {
                 $absdelta   = abs($agrade - $rgrade);
                 $reldelta   = pow($agrade - $rgrade, 2) / ($settings->comparison * $var);
                 $distance  += $absdelta * $reldelta * $weight;
index 9b31e36..b2480c1 100644 (file)
@@ -239,6 +239,82 @@ class workshopeval_best_evaluation_testcase extends basic_testcase {
             $this->evaluator->assessments_distance($assessment2, $referential, $diminfo, $settings));
 
     }
+
+    public function test_assessments_distance_zero_variance() {
+        // Fixture set-up: an assessment form of the strategy "Number of errors",
+        // three assertions, same weight.
+        $diminfo = array(
+            1 => (object)array('min' => 0, 'max' => 1, 'weight' => 1),
+            2 => (object)array('min' => 0, 'max' => 1, 'weight' => 1),
+            3 => (object)array('min' => 0, 'max' => 1, 'weight' => 1),
+        );
+
+        // Simulate structure returned by {@link workshop_best_evaluation::prepare_data_from_recordset()}
+        $assessments = array(
+            // The first assessment has weight 0 and the assessment was No, No, No.
+            10 => (object)array(
+                'assessmentid' => 10,
+                'weight' => 0,
+                'reviewerid' => 56,
+                'gradinggrade' => null,
+                'submissionid' => 99,
+                'dimgrades' => array(
+                    1 => 0,
+                    2 => 0,
+                    3 => 0,
+                ),
+            ),
+            // The second assessment has weight 1 and assessments was Yes, Yes, Yes.
+            20 => (object)array(
+                'assessmentid' => 20,
+                'weight' => 1,
+                'reviewerid' => 76,
+                'gradinggrade' => null,
+                'submissionid' => 99,
+                'dimgrades' => array(
+                    1 => 1,
+                    2 => 1,
+                    3 => 1,
+                ),
+            ),
+            // The third assessment has weight 1 and assessments was Yes, Yes, Yes too.
+            30 => (object)array(
+                'assessmentid' => 30,
+                'weight' => 1,
+                'reviewerid' => 97,
+                'gradinggrade' => null,
+                'submissionid' => 99,
+                'dimgrades' => array(
+                    1 => 1,
+                    2 => 1,
+                    3 => 1,
+                ),
+            ),
+        );
+
+        // Process assessments in the same way as in the {@link workshop_best_evaluation::process_assessments()}
+        $assessments = $this->evaluator->normalize_grades($assessments, $diminfo);
+        $average = $this->evaluator->average_assessment($assessments);
+        $variances = $this->evaluator->weighted_variance($assessments);
+        foreach ($variances as $dimid => $variance) {
+            $diminfo[$dimid]->variance = $variance;
+        }
+
+        // Simulate the chosen comparison of assessments "fair" (does not really matter here but we need something).
+        $settings = (object)array('comparison' => 5);
+
+        // Exercise SUT: for every assessment, calculate its distance from the average one.
+        $distances = array();
+        foreach ($assessments as $asid => $assessment) {
+            $distances[$asid] = $this->evaluator->assessments_distance($assessment, $average, $diminfo, $settings);
+        }
+
+        // Validate: the first assessment is far far away from the average one ...
+        $this->assertTrue($distances[10] > 0);
+        // ... while the two others were both picked as the referential ones.
+        $this->assertTrue($distances[20] == 0);
+        $this->assertTrue($distances[30] == 0);
+    }
 }
 
 
index 5df9f2c..40a82b6 100644 (file)
@@ -109,8 +109,8 @@ class qtype_multianswer extends question_type {
                     if ($oldwrappedquestion->qtype != $wrapped->qtype) {
                         switch ($oldwrappedquestion->qtype) {
                             case 'multichoice':
-                                $DB->delete_records('question_multichoice',
-                                        array('question' => $oldwrappedquestion->id));
+                                $DB->delete_records('qtype_multichoice_options',
+                                        array('questionid' => $oldwrappedquestion->id));
                                 break;
                             case 'shortanswer':
                                 $DB->delete_records('qtype_shortanswer_options',
index 930b971..fa9441c 100644 (file)
@@ -53,7 +53,7 @@ class backup_qtype_multichoice_plugin extends backup_qtype_plugin {
 
         // Now create the qtype own structures.
         $multichoice = new backup_nested_element('multichoice', array('id'), array(
-            'layout', 'answers', 'single', 'shuffleanswers',
+            'layout', 'single', 'shuffleanswers',
             'correctfeedback', 'correctfeedbackformat',
             'partiallycorrectfeedback', 'partiallycorrectfeedbackformat',
             'incorrectfeedback', 'incorrectfeedbackformat', 'answernumbering', 'shownumcorrect'));
@@ -62,8 +62,8 @@ class backup_qtype_multichoice_plugin extends backup_qtype_plugin {
         $pluginwrapper->add_child($multichoice);
 
         // Set source to populate the data.
-        $multichoice->set_source_table('question_multichoice',
-                array('question' => backup::VAR_PARENTID));
+        $multichoice->set_source_table('qtype_multichoice_options',
+                array('questionid' => backup::VAR_PARENTID));
 
         // Don't need to annotate ids nor files.
 
index c9f0247..cceada3 100644 (file)
@@ -68,24 +68,14 @@ class restore_qtype_multichoice_plugin extends restore_qtype_plugin {
         $questioncreated = (bool) $this->get_mappingid('question_created', $oldquestionid);
 
         // If the question has been created by restore, we need to create its
-        // question_multichoice too.
+        // qtype_multichoice_options too.
         if ($questioncreated) {
             // Adjust some columns.
-            $data->question = $newquestionid;
-            // Map sequence of question_answer ids.
-            if ($data->answers) {
-                $answersarr = explode(',', $data->answers);
-            } else {
-                $answersarr = array();
-            }
-            foreach ($answersarr as $key => $answer) {
-                $answersarr[$key] = $this->get_mappingid('question_answer', $answer);
-            }
-            $data->answers = implode(',', $answersarr);
+            $data->questionid = $newquestionid;
             // Insert record.
-            $newitemid = $DB->insert_record('question_multichoice', $data);
+            $newitemid = $DB->insert_record('qtype_multichoice_options', $data);
             // Create mapping (needed for decoding links).
-            $this->set_mapping('question_multichoice', $oldid, $newitemid);
+            $this->set_mapping('qtype_multichoice_options', $oldid, $newitemid);
         }
     }
 
@@ -163,8 +153,8 @@ class restore_qtype_multichoice_plugin extends restore_qtype_plugin {
         $contents = array();
 
         $fields = array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback');
-        $contents[] = new restore_decode_content('question_multichoice',
-                $fields, 'question_multichoice');
+        $contents[] = new restore_decode_content('qtype_multichoice_options',
+                $fields, 'qtype_multichoice_options');
 
         return $contents;
     }
index eb7bb86..1c446fc 100644 (file)
@@ -4,12 +4,11 @@
     xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
 >
   <TABLES>
-    <TABLE NAME="question_multichoice" COMMENT="Options for multiple choice questions">
+    <TABLE NAME="qtype_multichoice_options" COMMENT="Options for multiple choice questions">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
-        <FIELD NAME="question" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Foreign key references question.id"/>
+        <FIELD NAME="questionid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Foreign key references question.id"/>
         <FIELD NAME="layout" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Not used. Was intended for a vertical/horizontal layout option. See MDL-18445."/>
-        <FIELD NAME="answers" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="Redundant. Comma-separated list of question_answer ids. SELECT id FROM question_answers WHERE question = ? ORDER BY id."/>
         <FIELD NAME="single" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If 0 it multiple response (checkboxes). Otherwise it is radio buttons."/>
         <FIELD NAME="shuffleanswers" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Whether the choices can be randomly shuffled."/>
         <FIELD NAME="correctfeedback" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Feedback shown for any correct response."/>
@@ -23,7 +22,7 @@
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
-        <KEY NAME="question" TYPE="foreign" FIELDS="question" REFTABLE="question" REFFIELDS="id"/>
+        <KEY NAME="questionid" TYPE="foreign-unique" FIELDS="questionid" REFTABLE="question" REFFIELDS="id"/>
       </KEYS>
     </TABLE>
   </TABLES>
index 63b4cb8..489e29c 100644 (file)
@@ -36,21 +36,102 @@ function xmldb_qtype_multichoice_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-
     // Moodle v2.2.0 release upgrade line
     // Put any upgrade step following this.
 
     // Moodle v2.3.0 release upgrade line
     // Put any upgrade step following this.
 
-
     // Moodle v2.4.0 release upgrade line
     // Put any upgrade step following this.
 
-
     // Moodle v2.5.0 release upgrade line.
     // Put any upgrade step following this.
 
+    if ($oldversion < 2013092300) {
+        // Find duplicate rows before they break the 2013092304 step below.
+        $problemids = $DB->get_recordset_sql("
+                SELECT question, MIN(id) AS recordidtokeep
+                  FROM {question_multichoice}
+              GROUP BY question
+                HAVING COUNT(1) > 1
+                ");
+        foreach ($problemids as $problem) {
+            $DB->delete_records_select('question_multichoice',
+                    'question = ? AND id > ?',
+                    array($problem->question, $problem->recordidtokeep));
+        }
+        $problemids->close();
+
+        // Shortanswer savepoint reached.
+        upgrade_plugin_savepoint(true, 2013092300, 'qtype', 'multichoice');
+    }
+
+    if ($oldversion < 2013092301) {
+
+        // Define table question_multichoice to be renamed to qtype_multichoice_options.
+        $table = new xmldb_table('question_multichoice');
+
+        // Launch rename table for question_multichoice.
+        $dbman->rename_table($table, 'qtype_multichoice_options');
+
+        // Record that qtype_match savepoint was reached.
+        upgrade_plugin_savepoint(true, 2013092301, 'qtype', 'multichoice');
+    }
+
+    if ($oldversion < 2013092302) {
+
+        // Define key question (foreign) to be dropped form qtype_multichoice_options.
+        $table = new xmldb_table('qtype_multichoice_options');
+        $key = new xmldb_key('question', XMLDB_KEY_FOREIGN, array('question'), 'question', array('id'));
+
+        // Launch drop key question.
+        $dbman->drop_key($table, $key);
+
+        // Record that qtype_match savepoint was reached.
+        upgrade_plugin_savepoint(true, 2013092302, 'qtype', 'multichoice');
+    }
+
+    if ($oldversion < 2013092303) {
+
+        // Rename field question on table qtype_multichoice_options to questionid.
+        $table = new xmldb_table('qtype_multichoice_options');
+        $field = new xmldb_field('question', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
+
+        // Launch rename field question.
+        $dbman->rename_field($table, $field, 'questionid');
+
+        // Record that qtype_match savepoint was reached.
+        upgrade_plugin_savepoint(true, 2013092303, 'qtype', 'multichoice');
+    }
+
+    if ($oldversion < 2013092304) {
+
+        // Define key questionid (foreign-unique) to be added to qtype_multichoice_options.
+        $table = new xmldb_table('qtype_multichoice_options');
+        $key = new xmldb_key('questionid', XMLDB_KEY_FOREIGN_UNIQUE, array('questionid'), 'question', array('id'));
+
+        // Launch add key questionid.
+        $dbman->add_key($table, $key);
+
+        // Record that qtype_match savepoint was reached.
+        upgrade_plugin_savepoint(true, 2013092304, 'qtype', 'multichoice');
+    }
+
+    if ($oldversion < 2013092305) {
+
+        // Define field answers to be dropped from qtype_multichoice_options.
+        $table = new xmldb_table('qtype_multichoice_options');
+        $field = new xmldb_field('answers');
+
+        // Conditionally launch drop field answers.
+        if ($dbman->field_exists($table, $field)) {
+            $dbman->drop_field($table, $field);
+        }
+
+        // Record that qtype_match savepoint was reached.
+        upgrade_plugin_savepoint(true, 2013092305, 'qtype', 'multichoice');
+    }
 
     return true;
 }
index 352018e..164acce 100644 (file)
@@ -39,8 +39,8 @@ require_once($CFG->libdir . '/questionlib.php');
 class qtype_multichoice extends question_type {
     public function get_question_options($question) {
         global $DB, $OUTPUT;
-        $question->options = $DB->get_record('question_multichoice',
-                array('question' => $question->id), '*', MUST_EXIST);
+        $question->options = $DB->get_record('qtype_multichoice_options',
+                array('questionid' => $question->id), '*', MUST_EXIST);
         parent::get_question_options($question);
     }
 
@@ -67,7 +67,6 @@ class qtype_multichoice extends question_type {
         // Insert all the new answers.
         $totalfraction = 0;
         $maxfraction = -1;
-        $answers = array();
         foreach ($question->answer as $key => $answerdata) {
             if (trim($answerdata['text']) == '') {
                 continue;
@@ -93,7 +92,6 @@ class qtype_multichoice extends question_type {
             $answer->feedbackformat = $question->feedback[$key]['format'];
 
             $DB->update_record('question_answers', $answer);
-            $answers[] = $answer->id;
 
             if ($question->fraction[$key] > 0) {
                 $totalfraction += $question->fraction[$key];
@@ -110,17 +108,16 @@ class qtype_multichoice extends question_type {
             $DB->delete_records('question_answers', array('id' => $oldanswer->id));
         }
 
-        $options = $DB->get_record('question_multichoice', array('question' => $question->id));
+        $options = $DB->get_record('qtype_multichoice_options', array('questionid' => $question->id));
         if (!$options) {
             $options = new stdClass();
-            $options->question = $question->id;
+            $options->questionid = $question->id;
             $options->correctfeedback = '';
             $options->partiallycorrectfeedback = '';
             $options->incorrectfeedback = '';
-            $options->id = $DB->insert_record('question_multichoice', $options);
+            $options->id = $DB->insert_record('qtype_multichoice_options', $options);
         }
 
-        $options->answers = implode(',', $answers);
         $options->single = $question->single;
         if (isset($question->layout)) {
             $options->layout = $question->layout;
@@ -128,7 +125,7 @@ class qtype_multichoice extends question_type {
         $options->answernumbering = $question->answernumbering;
         $options->shuffleanswers = $question->shuffleanswers;
         $options = $this->save_combined_feedback_helper($options, $question, $context, true);
-        $DB->update_record('question_multichoice', $options);
+        $DB->update_record('qtype_multichoice_options', $options);
 
         $this->save_hints($question, true);
 
@@ -179,7 +176,7 @@ class qtype_multichoice extends question_type {
 
     public function delete_question($questionid, $contextid) {
         global $DB;
-        $DB->delete_records('question_multichoice', array('question' => $questionid));
+        $DB->delete_records('qtype_multichoice_options', array('question' => $questionid));
 
         parent::delete_question($questionid, $contextid);
     }
index 4c05df1..fa93d26 100644 (file)
@@ -139,7 +139,7 @@ class qtype_multichoice_test extends advanced_testcase {
         }
 
         foreach ($questiondata->options as $optionname => $value) {
-            if (!in_array($optionname, array('answers'))) {
+            if ($optionname != 'answers') {
                 $this->assertAttributeEquals($value, $optionname, $actualquestiondata->options);
             }
         }
index 15355a9..f27a768 100644 (file)
@@ -26,7 +26,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component = 'qtype_multichoice';
-$plugin->version   = 2013050100;
+$plugin->version   = 2013092305;
 
 $plugin->requires  = 2013050100;
 
index 32ad8f2..4b4a9ba 100644 (file)
@@ -2,7 +2,11 @@ This files describes API changes for code that uses the question API.
 
 === 2.6 ===
 
-1) It is sometimes necessary to display bits of question content without having
+1) Modules using the question bank MUST now declare their use of it with the xxx_supports()
+   flag FEATURE_USES_QUESTIONS. question_module_uses_questions() should be used to determine
+   if a module uses questions.
+
+2) It is sometimes necessary to display bits of question content without having
    and attempt (question_usage) in progress. Two examples of this are the option
    in the question bank to display the questiontext, and in the quiz statistics
    report, where it displays the question text above the report.
index 2e03f7a..6d021bb 100644 (file)
@@ -10,7 +10,8 @@ http://docs.moodle.org/dev/Repository_API
 * The function repository_attach_id() was removed, it was never used and was not useful.
 * New functions send_relative_file() and supports_relative_file() to allow sending relative linked
   files - see filesystem repository for example.
-
+* DB fields files.referencelifetime and files.referencelastsync are deleted.
+  Their values are stored only in files_reference.lastsync and files_reference.lifetime.
 
 === 2.5 ===
 
index 5d6f6fc..c4909c5 100644 (file)
@@ -211,3 +211,8 @@ input.titleeditor { width: 330px; vertical-align: text-bottom; }
 .dndupload-progress-outer {width:70px;border:1px solid black;border-radius:4px;height:10px;display:inline-block;margin:0;padding:0;overflow:hidden;position:relative;}
 .dndupload-progress-inner {width:0%;height:100%;background-color:green;display:inline-block;margin:0;padding:0;float:left;box-shadow: 0 0 4px #229b15;border-radius:2px;background-repeat:repeat-x;background-position:top;background-image:url([[pix:theme_base|progress]])}
 .dndupload-hidden {display:none;}
+
+/* activity label  */
+.modtype_label .no-overflow > p:last-child {
+    margin-bottom: 0;
+}
index 0876c5a..52a64c7 100644 (file)
@@ -72,6 +72,9 @@
     font-weight: normal;
     padding: .2em;
 }
+.modtype_label .no-overflow > p:last-child {
+    margin-bottom: 0;
+}
 .section li.activity {
     padding: .2em;
     clear: both;
index 8d367a4..7eb6566 100644 (file)
@@ -1,4 +1,4 @@
-.layout-option-noheader #page-header,.layout-option-nonavbar #page-navbar,.layout-option-nofooter #page-footer,.layout-option-nocourseheader .course-content-header,.layout-option-nocoursefooter .course-content-footer{display:none}.empty-region-side-pre #block-region-side-pre,.empty-region-side-post #block-region-side-post{display:none}.empty-region-side-post #region-bs-main-and-pre.span9{width:100%}.empty-region-side-pre #region-main{float:none;width:100%}.empty-region-side-post.used-region-side-pre #region-main.span8{width:74.46808510638297%;*width:74.41489361702126%}.empty-region-side-post.used-region-side-pre #block-region-side-pre.span4{width:23.404255319148934%;*width:23.351063829787233%}.empty-region-side-post #region-bs-main-and-post.span9 #region-main.span8{width:100%}.dir-ltr,.mdl-left,.dir-rtl .mdl-right{text-align:left}.dir-rtl,.mdl-right,.dir-rtl .mdl-left{text-align:right}#add,#remove,.centerpara,.mdl-align{text-align:center}a.dimmed,a.dimmed:link,a.dimmed:visited,a.dimmed_text,a.dimmed_text:link,a.dimmed_text:visited,.dimmed_text,.dimmed_text a,.dimmed_text a:link,.dimmed_text a:visited,.usersuspended,.usersuspended a,.usersuspended a:link,.usersuspended a:visited,.dimmed_category,.dimmed_category a{color:#999}.activity.label .dimmed_text{opacity:.5;filter:alpha(opacity=50)}.unlist,.unlist li,.inline-list,.inline-list li,.block .list,.block .list li,.section li.activity,.section li.movehere,.tabtree li{padding:0;margin:0;list-style:none}.inline,.inline-list li{display:inline}.notifytiny{font-size:10.5px}.notifytiny li,.notifytiny td{font-size:100%}.red,.notifyproblem{color:#b94a48}.green,.notifysuccess{color:#468847}.reportlink{text-align:right}a.autolink.glossary:hover{cursor:help}.collapsibleregioncaption{white-space:nowrap}.collapsibleregioncaption img{vertical-align:middle}.jsenabled .hiddenifjs{display:none}.visibleifjs{display:none}.jsenabled .visibleifjs{display:inline}.jsenabled .collapsibleregion{overflow:hidden}.jsenabled .collapsed .collapsibleregioninner{visibility:hidden}.collapsible-actions{display:none;text-align:right}.dir-rtl .collapsible-actions{text-align:left}.jsenabled .collapsible-actions{display:block}.collapsible-actions .collapseexpand{padding-left:20px;background:url([[pix:t/collapsed]]) 2px center no-repeat}.dir-rtl .collapsible-actions .collapseexpand{padding-right:20px;padding-left:0;background:url([[pix:t/collapsed_rtl]]) right center no-repeat}.collapsible-actions .collapse-all,.dir-rtl .collapsible-actions .collapse-all{background-image:url([[pix:t/expanded]])}.yui-overlay .yui-widget-bd{position:relative;top:0;left:0;z-index:1;padding:2px 5px;color:#000;background-color:#ffee69;border:1px solid #a6982b;border-top-color:#d4c237}.clearer{display:block;height:1px;padding:0;margin:0;clear:both;background:transparent;border-width:0}.bold,.warning,.errorbox .title,.pagingbar .title,.pagingbar .thispage,.headingblock{font-weight:bold}img.resize{width:1em;height:1em}.block img.resize,.breadcrumb img.resize{width:.8em;height:.9em}img.icon{width:16px;height:16px;padding-right:6px;vertical-align:text-bottom}.dir-rtl img.icon{padding-right:0;padding-left:6px}img.iconsmall{width:12px;height:12px;margin-right:3px;vertical-align:middle}img.iconhelp,.helplink img{width:16px;height:16px;padding-left:3px;vertical-align:text-bottom}h1 img.iconhelp,h1 img.icon,h2 img.iconhelp,h2 img.icon,h3 img.iconhelp,h3 img.icon,h4 img.iconhelp,h4 img.icon,h5 img.iconhelp,h5 img.icon,h6 img.iconhelp,h6 img.icon{vertical-align:middle}.dir-rtl img.iconhelp,.dir-rtl .helplink img{padding-right:3px;padding-left:0}img.iconlarge{width:24px;height:24px;vertical-align:middle}img.iconsort{padding-left:.3em;margin-bottom:.15em;vertical-align:text-bottom}.dir-rtl img.iconsort{padding-right:.3em;padding-left:0}img.icontoggle{width:50px;height:17px;vertical-align:middle}img.iconkbhelp{width:49px;height:17px}img.icon-pre,.dir-rtl img.icon-post{padding-right:3px;padding-left:0}img.icon-post,.dir-rtl img.icon-pre{padding-right:0;padding-left:3px}.boxaligncenter{margin-right:auto;margin-left:auto}.boxalignright{margin-right:0;margin-left:auto}.boxalignleft{margin-right:auto;margin-left:0}.boxwidthnarrow{width:30%}.boxwidthnormal{width:50%}.boxwidthwide{width:80%}.headermain{font-weight:bold}#maincontent{display:block;height:1px;overflow:hidden}img.uihint{cursor:help}#addmembersform table{margin-right:auto;margin-left:auto}.flexible th{white-space:nowrap}table.flexible .emptyrow{display:none}img.emoticon{width:15px;height:15px;vertical-align:middle}form.popupform,form.popupform div{display:inline}.arrow_button input{overflow:hidden}.action-icon img.smallicon{margin:0 .3em;vertical-align:text-bottom}.no-overflow{padding-bottom:1px;overflow:auto}.pagelayout-report .no-overflow{overflow:visible}.no-overflow>.generaltable{margin-bottom:0}.accesshide{position:absolute;left:-10000px;font-size:1em;font-weight:normal}.dir-rtl .accesshide{top:-30000px;left:auto}span.hide,div.hide{display:none}a.skip-block,a.skip{position:absolute;top:-1000em;font-size:.85em;text-decoration:none}a.skip-block:focus,a.skip-block:active,a.skip:focus,a.skip:active{position:static;display:block}.skip-block-to{display:block;height:1px;overflow:hidden}.addbloglink{text-align:center}.blog_entry .audience{padding-right:4px;text-align:right}.blog_entry .tags{margin-top:15px}.blog_entry .tags .action-icon img.smallicon{width:16px;height:16px}.blog_entry .content{margin-left:43px}#page-group-index #groupeditform{text-align:center}#doc-contents h1{margin:1em 0 0 0}#doc-contents ul{width:90%;padding:0;margin:0}#doc-contents ul li{list-style-type:none}.groupmanagementtable td{vertical-align:top}.groupmanagementtable #existingcell,.groupmanagementtable #potentialcell{width:42%}.groupmanagementtable #buttonscell{width:16%}.groupmanagementtable #buttonscell p.arrow_button input{width:auto;min-width:80%;margin:0 auto}.groupmanagementtable #removeselect_wrapper,.groupmanagementtable #addselect_wrapper{width:100%}.groupmanagementtable #removeselect_wrapper label,.groupmanagementtable #addselect_wrapper label{font-weight:normal}.dir-rtl .groupmanagementtable p{text-align:right}#group-usersummary{width:14em}.groupselector{margin-top:3px;margin-bottom:3px}.loginbox{margin:15px;overflow:visible}.loginbox.twocolumns{margin:15px}.loginbox h2,.loginbox .subcontent{padding:10px;margin:5px;text-align:center}.loginbox .loginpanel .desc{padding:0;margin:0;margin-top:15px;margin-bottom:5px}.loginbox .signuppanel .subcontent{text-align:left}.dir-rtl .loginbox .signuppanel .subcontent{text-align:right}.loginbox .loginsub{margin-right:0;margin-left:0}.loginbox .guestsub,.loginbox .forgotsub,.loginbox .potentialidps{margin:5px 12%}.loginbox .potentialidps .potentialidplist{margin-left:40%}.loginbox .potentialidps .potentialidplist div{text-align:left}.loginbox .loginform{margin-top:1em;text-align:left}.loginbox .loginform .form-label{float:left;width:44%;text-align:right;white-space:nowrap;direction:rtl}.dir-rtl .loginbox .loginform .form-label{float:left;width:44%;text-align:right;white-space:nowrap;direction:ltr}.loginbox .loginform .form-input{float:right;width:55%}.loginbox .loginform .form-input input{width:6em}.loginbox .signupform{margin-top:1em;text-align:center}.loginbox.twocolumns .loginpanel,.loginbox.twocolumns .signuppanel{display:block;float:left;width:48%;min-height:30px;padding:0;padding-bottom:2000px;margin:0;margin-bottom:-2000px;margin-left:2.76243%;border:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.loginbox .potentialidp .smallicon{margin:0 .3em;vertical-align:text-bottom}.notepost{margin-bottom:1em}.notepost .userpicture{float:left;margin-right:5px}.notepost .content,.notepost .footer{clear:both}.notesgroup{margin-left:20px}.path-my .coursebox .overview{margin:15px 30px 10px 30px}.path-my .coursebox .info{float:none;margin:0}.mod_introbox{padding:10px}table.mod_index{width:100%}.comment-ctrl{display:none;padding:0;margin:0;font-size:12px}.comment-ctrl h5{padding:5px;margin:0}.comment-area{max-width:400px;padding:5px}.comment-area textarea{width:100%;overflow:auto}.comment-area .fd{text-align:right}.comment-meta span{color:gray}.comment-link img{vertical-align:text-bottom}.comment-list{padding:0;margin:0;overflow:auto;font-size:11px;list-style:none}.comment-list li{position:relative;padding:.3em;margin:2px;margin-bottom:5px;clear:both;list-style:none}.comment-list li.first{display:none}.comment-paging{text-align:center}.comment-paging .pageno{padding:2px}.comment-paging .curpage{border:1px solid #CCC}.comment-message .picture{float:left;width:20px}.dir-rtl .comment-message .picture{float:right}.comment-message .text{padding:0;margin:0}.comment-message .text p{padding:0;margin:0 18px 0 0}.comment-delete{position:absolute;top:0;right:0;margin:.3em}.dir-rtl .comment-delete{position:absolute;right:auto;left:0;margin:.3em}.comment-delete-confirm{width:5em;padding:2px;text-align:center;background:#eee}.comment-container{float:left;margin:4px}.comment-report-selectall{display:none}.comment-link{display:none}.jsenabled .comment-link{display:block}.jsenabled .showcommentsnonjs{display:none}.jsenabled .comment-report-selectall{display:inline}.completion-expired{background:#f2dede}.completion-expected{font-size:10.5px}.completion-sortchoice,.completion-identifyfield{font-size:10.5px;vertical-align:bottom}.completion-progresscell{text-align:right}.completion-expired .completion-expected{font-weight:bold}#page-tag-coursetags_edit .coursetag_edit_centered{position:relative;width:600px;margin:20px auto}#page-tag-coursetags_edit .coursetag_edit_row{clear:both}#page-tag-coursetags_edit .coursetag_edit_row .coursetag_edit_left{float:left;width:50%;text-align:right}#page-tag-coursetags_edit .coursetag_edit_row .coursetag_edit_right{margin-left:50%}#page-tag-coursetags_edit .coursetag_edit_input3{display:none}#page-tag-coursetags_more .coursetag_more_large{font-size:120%}#page-tag-coursetags_more .coursetag_more_small{font-size:80%}#page-tag-coursetags_more .coursetag_more_link{font-size:80%}#tag-description,#tag-blogs{width:100%}#tag-management-box{margin-bottom:10px;line-height:20px}#tag-user-table{width:100%;padding:3px;clear:both}#tag-user-table{*zoom:1}#tag-user-table:before,#tag-user-table:after{display:table;line-height:0;content:""}#tag-user-table:after{clear:both}img.user-image{width:100px;height:100px}#small-tag-cloud-box{width:300px;margin:0 auto}#big-tag-cloud-box{float:none;width:600px;margin:0 auto}ul#tag-cloud-list{padding:5px;margin:0;list-style:none}ul#tag-cloud-list li{display:inline;margin:0;list-style-type:none}#tag-search-box{margin:10px auto;text-align:center}#tag-search-results-container{width:100%;padding:0}#tag-search-results{display:block;float:left;width:60%;padding:0;margin:15px 20% 0 20%}#tag-search-results li{float:left;width:30%;padding-right:1%;padding-left:1%;line-height:20px;text-align:left;list-style:none}span.flagged-tag,span.flagged-tag a{color:#b94a48}table#tag-management-list{width:100%;text-align:left}table#tag-management-list td,table#tag-management-list th{padding:4px;text-align:left;vertical-align:middle}.tag-management-form{text-align:center}#relatedtags-autocomplete-container{width:100%;min-height:4.6em;margin-right:auto;margin-left:auto}#relatedtags-autocomplete{position:relative;display:block;width:60%;margin-right:auto;margin-left:auto}#relatedtags-autocomplete .yui-ac-content{position:absolute;left:20%;z-index:9050;width:420px;overflow:hidden;background:#fff;border:1px solid #404040}#relatedtags-autocomplete .ysearchquery{position:absolute;right:10px;z-index:10;color:#808080}#relatedtags-autocomplete .yui-ac-shadow{position:absolute;z-index:9049;width:100%;margin:.3em;background:#a0a0a0}#relatedtags-autocomplete ul{width:100%;padding:0;margin:0;list-style-type:none}#relatedtags-autocomplete li{padding:0 5px;white-space:nowrap;cursor:default}#relatedtags-autocomplete li.yui-ac-highlight{background:#ffc}h2.tag-heading,div#tag-description,div#tag-blogs,body.tag .managelink{padding:5px}.tag_cloud .s20{font-size:1.5em;font-weight:bold}.tag_cloud .s19{font-size:1.5em}.tag_cloud .s18{font-size:1.4em;font-weight:bold}.tag_cloud .s17{font-size:1.4em}.tag_cloud .s16{font-size:1.3em;font-weight:bold}.tag_cloud .s15{font-size:1.3em}.tag_cloud .s14{font-size:1.2em;font-weight:bold}.tag_cloud .s13{font-size:1.2em}.tag_cloud .s12,.tag_cloud .s11{font-size:1.1em;font-weight:bold}.tag_cloud .s10,.tag_cloud .s9{font-size:1.1em}.tag_cloud .s8,.tag_cloud .s7{font-size:1em;font-weight:bold}.tag_cloud .s6,.tag_cloud .s5{font-size:1em}.tag_cloud .s4,.tag_cloud .s3{font-size:.9em;font-weight:bold}.tag_cloud .s2,.tag_cloud .s1{font-size:.9em}.tag_cloud .s0{font-size:.8em}#webservice-doc-generator td{text-align:left;border:0 solid black}.smartselect{position:absolute}.smartselect .smartselect_mask{background-color:#fff}.smartselect ul{padding:0;margin:0}.smartselect ul li{list-style:none}.smartselect .smartselect_menu{margin-right:5px}.safari .smartselect .smartselect_menu{margin-left:2px}.smartselect .smartselect_menu,.smartselect .smartselect_submenu{display:none;background-color:#FFF;border:1px solid #000}.smartselect .smartselect_menu.visible,.smartselect .smartselect_submenu.visible{display:block}.smartselect .smartselect_menu_content ul li{position:relative;padding:2px 5px}.smartselect .smartselect_menu_content ul li a{color:#333;text-decoration:none}.smartselect .smartselect_menu_content ul li a.selectable{color:inherit}.smartselect .smartselect_submenuitem{background-image:url([[pix:moodle|t/collapsed]]);background-position:100%;background-repeat:no-repeat}.smartselect.spanningmenu .smartselect_submenu{position:absolute;top:-1px;left:100%}.smartselect.spanningmenu .smartselect_submenu a{padding-right:16px;white-space:nowrap}.smartselect.spanningmenu .smartselect_menu_content ul li a.selectable:hover{text-decoration:underline}.smartselect.compactmenu .smartselect_submenu{position:relative;z-index:1010;display:none;margin:2px -3px;margin-left:10px;border-width:0}.smartselect.compactmenu .smartselect_submenu.visible{display:block}.smartselect.compactmenu .smartselect_menu{z-index:1000;overflow:hidden}.smartselect.compactmenu .smartselect_submenu .smartselect_submenu{z-index:1020}.smartselect.compactmenu .smartselect_submenuitem:hover>.smartselect_menuitem_label{font-weight:bold}#page-admin-registration-register .registration_textfield{width:300px}.userenrolment{width:100%;border-collapse:collapse}.userenrolment td{height:41px;padding:0}.userenrolment .subfield{margin-right:5px}.userenrolment .col_userdetails .subfield_picture{float:left}.userenrolment .col_lastseen{width:150px}.userenrolment .col_role{width:262px}.userenrolment .col_role .roles{margin-right:30px}.userenrolment .col_role .role{float:left;padding:3px;margin:3px}.dir-rtl .userenrolment .col_role .role{float:right}.userenrolment .col_role .role a{margin-left:3px;cursor:pointer}.userenrolment .col_role .addrole{float:right;width:18px;height:18px;margin:3px;text-align:center;background-color:#dff0d8;border:1px solid #d6e9c6}.userenrolment .col_role .addrole img{vertical-align:baseline}.userenrolment .hasAllRoles .col_role .addrole{display:none}.userenrolment .col_group .groups{margin-right:30px}.userenrolment .col_group .group{float:left;padding:3px;margin:3px;white-space:nowrap}.userenrolment .col_group .group a{margin-left:3px;cursor:pointer}.userenrolment .col_group .addgroup{float:right;width:18px;height:18px;margin:3px;text-align:center}.userenrolment .col_group .addgroup a img{vertical-align:bottom}.userenrolment .col_enrol .enrolment{float:left;padding:3px;margin:3px}.userenrolment .col_enrol .enrolment a{float:right;margin-left:3px}#page-enrol-users .enrol_user_buttons{float:right}#page-enrol-users.dir-rtl .enrol_user_buttons{float:left}#page-enrol-users .enrol_user_buttons .enrolusersbutton{display:inline;margin-left:1em}#page-enrol-users .enrol_user_buttons .enrolusersbutton div,#page-enrol-users .enrol_user_buttons .enrolusersbutton form{display:inline}#page-enrol-users .enrol_user_buttons .enrolusersbutton input{padding-right:6px;padding-left:6px}#page-enrol-users.dir-rtl .col_userdetails .subfield_picture{float:right}#page-enrol-users .user-enroller-panel .uep-search-results .user .details{width:237px}.dir-rtl .headermain{float:right}.dir-rtl .headermenu{float:left}.dir-rtl .loginbox .loginform .form-label{float:right;text-align:left}.dir-rtl .loginbox .loginform .form-input{text-align:right}.dir-rtl .yui3-menu-hidden{left:0}#page-admin-roles-define.dir-rtl #rolesform .felement{margin-right:180px}#page-message-edit.dir-rtl table.generaltable th.c0{text-align:right}.corelightbox{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;background-color:#CCC}.corelightbox img{position:fixed;top:50%;left:50%}.mod-indent-1{margin-left:30px}.mod-indent-2{margin-left:60px}.mod-indent-3{margin-left:90px}.mod-indent-4{margin-left:120px}.mod-indent-5{margin-left:150px}.mod-indent-6{margin-left:180px}.mod-indent-7{margin-left:210px}.mod-indent-8{margin-left:240px}.mod-indent-9{margin-left:270px}.mod-indent-10{margin-left:300px}.mod-indent-11{margin-left:330px}.mod-indent-12{margin-left:360px}.mod-indent-13{margin-left:390px}.mod-indent-14{margin-left:420px}.mod-indent-15,.mod-indent-huge{margin-left:420px}.dir-rtl .mod-indent-1{margin-right:30px;margin-left:0}.dir-rtl .mod-indent-2{margin-right:60px;margin-left:0}.dir-rtl .mod-indent-3{margin-right:90px;margin-left:0}.dir-rtl .mod-indent-4{margin-right:120px;margin-left:0}.dir-rtl .mod-indent-5{margin-right:150px;margin-left:0}.dir-rtl .mod-indent-6{margin-right:180px;margin-left:0}.dir-rtl .mod-indent-7{margin-right:210px;margin-left:0}.dir-rtl .mod-indent-8{margin-right:240px;margin-left:0}.dir-rtl .mod-indent-9{margin-right:270px;margin-left:0}.dir-rtl .mod-indent-10{margin-right:300px;margin-left:0}.dir-rtl .mod-indent-11{margin-right:330px;margin-left:0}.dir-rtl .mod-indent-12{margin-right:360px;margin-left:0}.dir-rtl .mod-indent-13{margin-right:390px;margin-left:0}.dir-rtl .mod-indent-14{margin-right:420px;margin-left:0}.dir-rtl .mod-indent-15,.dir-rtl .mod-indent-huge{margin-right:420px;margin-left:0}.resourcecontent .mediaplugin_mp3 object{width:600px;height:25px}.resourcecontent audio.mediaplugin_html5audio{width:600px}.resourceimage{max-width:100%}.mediaplugin_mp3 object{width:300px;height:15px}audio.mediaplugin_html5audio{width:300px}.core_media_preview.pagelayout-embedded #content{padding:0}.core_media_preview.pagelayout-embedded #maincontent{height:0}.core_media_preview.pagelayout-embedded .mediaplugin{margin:0}.dir-rtl .ygtvtn,.dir-rtl .ygtvtm,.dir-rtl .ygtvtmh,.dir-rtl .ygtvtmhh,.dir-rtl .ygtvtp,.dir-rtl .ygtvtph,.dir-rtl .ygtvtphh,.dir-rtl .ygtvln,.dir-rtl .ygtvlm,.dir-rtl .ygtvlmh,.dir-rtl .ygtvlmhh,.dir-rtl .ygtvlp,.dir-rtl .ygtvlph,.dir-rtl .ygtvlphh,.dir-rtl .ygtvdepthcell,.dir-rtl .ygtvok,.dir-rtl .ygtvok:hover,.dir-rtl .ygtvcancel,.dir-rtl .ygtvcancel:hover{width:18px;height:22px;cursor:pointer;background-image:url([[pix:theme|yui2-treeview-sprite-rtl]]);background-repeat:no-repeat}.dir-rtl .ygtvtn{background-position:0 -5600px}.dir-rtl .ygtvtm{background-position:0 -4000px}.dir-rtl .ygtvtmh,.dir-rtl .ygtvtmhh{background-position:0 -4800px}.dir-rtl .ygtvtp{background-position:0 -6400px}.dir-rtl .ygtvtph,.dir-rtl .ygtvtphh{background-position:0 -7200px}.dir-rtl .ygtvln{background-position:0 -1600px}.dir-rtl .ygtvlm{background-position:0 0}.dir-rtl .ygtvlmh,.dir-rtl .ygtvlmhh{background-position:0 -800px}.dir-rtl .ygtvlp{background-position:0 -2400px}.dir-rtl .ygtvlph,.dir-rtl .ygtvlphh{background-position:0 -3200px}.dir-rtl .ygtvdepthcell{background-position:0 -8000px}.dir-rtl .ygtvok{background-position:0 -8800px}.dir-rtl .ygtvok:hover{background-position:0 -8844px}.dir-rtl .ygtvcancel{background-position:0 -8822px}.dir-rtl .ygtvcancel:hover{background-position:0 -8866px}.dir-rtl.yui-skin-sam .yui-panel .hd{text-align:right}.dir-rtl .yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd{text-align:right}.dir-rtl .clearlooks2.ie9 .mceAlert .mceMiddle span,.dir-rtl .clearlooks2 .mceConfirm .mceMiddle span{top:44px}.dir-rtl .o2k7Skin table,.dir-rtl .o2k7Skin tbody,.dir-rtl .o2k7Skin a,.dir-rtl .o2k7Skin img,.dir-rtl .o2k7Skin tr,.dir-rtl .o2k7Skin div,.dir-rtl .o2k7Skin td,.dir-rtl .o2k7Skin iframe,.dir-rtl .o2k7Skin span,.dir-rtl .o2k7Skin *,.dir-rtl .o2k7Skin .mceText,.dir-rtl .o2k7Skin .mceListBox .mceText{text-align:right}.path-rating .ratingtable{width:100%;margin-bottom:1em}.path-rating .ratingtable th.rating{width:100%}.path-rating .ratingtable td.rating,.path-rating .ratingtable td.time{text-align:center;white-space:nowrap}.initialbar a{padding-right:2px}.moodle-dialogue-base .moodle-dialogue-lightbox{background-color:#AAA}.moodle-dialogue-base .hidden,.moodle-dialogue-base .moodle-dialogue-hidden{display:none}.no-scrolling{overflow:hidden}.moodle-dialogue-base .moodle-dialogue-fullscreen{position:fixed;top:0;right:0;bottom:-50px;left:0}.moodle-dialogue-base .moodle-dialogue-fullscreen .closebutton{width:28px;height:16px;background-size:100%}.moodle-dialogue-base .moodle-dialogue{z-index:600;padding:0;margin:0;background:0;border:0;outline:#000 dotted 0}.moodle-dialogue-base .moodle-dialogue-wrap{margin-top:-3px;margin-left:-3px;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd{padding:5px;margin:0;font-size:12px;font-weight:normal;letter-spacing:1px;color:#333;text-align:center;text-shadow:1px 1px 1px #fff;background:#ccc;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border-bottom:1px solid #bbb;-webkit-border-radius:10px 10px 0 0;-moz-border-radius:10px 10px 0 0;border-radius:10px 10px 0 0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0);filter:dropshadow(color=#ffffff,offx=1,offy=1)}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd h1{display:inline;padding:0;margin:0;font-size:100%;font-weight:bold}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd .yui3-widget-buttons{padding:5px}.moodle-dialogue-base .closebutton{display:inline-block;float:right;width:25px;height:15px;padding:0;vertical-align:middle;cursor:pointer;background-image:url([[pix:theme|sprite]]);background-repeat:no-repeat;border-style:none}.dir-rtl .moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd .yui3-widget-buttons{right:auto;left:0}.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-bd{padding:1em;overflow:auto;font-size:12px;line-height:2em;color:#555}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-content{padding:0;background:#FFF}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-hd{padding:10px;font-size:16px}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-content{position:absolute;top:0;right:0;bottom:50px;left:0;margin:0;overflow:auto;border:0}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-hd,.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-wrap{border-radius:0}.moodle-dialogue-confirm .confirmation-dialogue{text-align:center}.moodle-dialogue-confirm .confirmation-dialogue input{text-align:center}.moodle-dialogue-exception .moodle-exception-message{text-align:center}.moodle-dialogue-exception .moodle-exception-param label{font-weight:bold}.moodle-dialogue-exception .param-stacktrace label{background-color:#EEE;border:1px solid #ccc;border-bottom-width:0}.moodle-dialogue-exception .param-stacktrace pre{background-color:#fff;border:1px solid #ccc}.moodle-dialogue-exception .param-stacktrace .stacktrace-file{font-size:11.9px;color:navy}.moodle-dialogue-exception .param-stacktrace .stacktrace-line{font-size:11.9px;color:#b94a48}.moodle-dialogue-exception .param-stacktrace .stacktrace-call{font-size:90%;color:#333;border-bottom:1px solid #eee}.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-content .moodle-dialogue-ft{padding:0;margin:.7em 1em;font-size:12px;text-align:right;background-color:#FFF}.moodle-dialogue-confirm .confirmation-message{margin:.5em 1em}.moodle-dialogue-confirm .confirmation-dialogue input{min-width:80px}.moodle-dialogue-exception .moodle-exception-message{margin:1em}.moodle-dialogue-exception .moodle-exception-param{margin-bottom:.5em}.moodle-dialogue-exception .moodle-exception-param label{width:150px}.moodle-dialogue-exception .param-stacktrace label{display:block;padding:4px 1em;margin:0}.moodle-dialogue-exception .param-stacktrace pre{display:block;height:200px;overflow:auto}.moodle-dialogue-exception .param-stacktrace .stacktrace-file{display:inline-block;margin:4px 0}.moodle-dialogue-exception .param-stacktrace .stacktrace-line{display:inline-block;width:50px;margin:4px 1em}.moodle-dialogue-exception .param-stacktrace .stacktrace-call{padding-bottom:4px;padding-left:25px;margin-bottom:4px}.moodle-dialogue .moodle-dialogue-bd .content-lightbox{top:0;left:0;width:100%;height:100%;padding:10% 0;text-align:center;background-color:white;opacity:.75;filter:alpha(opacity=75)}.moodle-dialogue .tooltiptext{max-height:300px}.moodle-dialogue-base .moodle-dialogue.moodle-dialogue-tooltip{z-index:3001}#page-question-edit.dir-rtl a.container-close{right:auto;left:6px}.chooserdialoguebody,.choosertitle{display:none}.moodle-dialogue.chooserdialogue .moodle-dialogue-content .moodle-dialogue-ft{margin:0}.chooserdialogue .moodle-dialogue-wrap .moodle-dialogue-bd{padding:0;background:#f2f2f2;-webkit-border-bottom-right-radius:10px;border-bottom-right-radius:10px;-webkit-border-bottom-left-radius:10px;border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-moz-border-radius-bottomleft:10px}.choosercontainer #chooseform .submitbuttons{margin:.7em 0;text-align:center}.choosercontainer #chooseform .submitbuttons input{min-width:100px;margin:0 .5em}.choosercontainer #chooseform .options{position:relative;border-bottom:1px solid #bbb}.jsenabled .choosercontainer #chooseform .alloptions{max-width:20.3em;overflow-x:hidden;overflow-y:auto;-webkit-box-shadow:inset 0 0 30px 0 #ccc;-moz-box-shadow:inset 0 0 30px 0 #ccc;box-shadow:inset 0 0 30px 0 #ccc}.dir-rtl.jsenabled .choosercontainer #chooseform .alloptions{max-width:18.3em}.choosercontainer #chooseform .moduletypetitle,.choosercontainer #chooseform .option,.choosercontainer #chooseform .nonoption{padding:0 1.6em 0 1.6em;margin-bottom:0}.choosercontainer #chooseform .moduletypetitle{padding-top:1.2em;padding-bottom:.4em;text-transform:uppercase}.choosercontainer #chooseform .option .typename,.choosercontainer #chooseform .option span.modicon img.icon,.choosercontainer #chooseform .nonoption .typename,.choosercontainer #chooseform .nonoption span.modicon img.icon{padding:0 0 0 .5em}.dir-rtl .choosercontainer #chooseform .option .typename,.dir-rtl .choosercontainer #chooseform .option span.modicon img.icon,.dir-rtl .choosercontainer #chooseform .nonoption .typename,.dir-rtl .choosercontainer #chooseform .nonoption span.modicon img.icon{padding:0 .5em 0 0}.choosercontainer #chooseform .option span.modicon img.icon,.choosercontainer #chooseform .nonoption span.modicon img.icon{width:24px;height:24px}.choosercontainer #chooseform .option input[type=radio],.choosercontainer #chooseform .option span.typename,.choosercontainer #chooseform .option span.modicon{vertical-align:middle}.choosercontainer #chooseform .option label{display:block;padding:.3em 0 .1em 0;border-bottom:1px solid #fff}.choosercontainer #chooseform .nonoption{padding-top:.3em;padding-bottom:.1em;padding-left:2.7em}.dir-rtl .choosercontainer #chooseform .nonoption{padding-right:2.7em;padding-left:0}.choosercontainer #chooseform .subtype{padding:0 1.6em 0 3.2em;margin-bottom:0}.dir-rtl .choosercontainer #chooseform .subtype{padding:0 3.2em 0 1.6em}.choosercontainer #chooseform .subtype .typename{margin:0 0 0 .2em}.dir-rtl .choosercontainer #chooseform .subtype .typename{margin:0 .2em 0 0}.jsenabled .choosercontainer #chooseform .instruction,.jsenabled .choosercontainer #chooseform .typesummary{position:absolute;top:0;right:0;bottom:0;left:20.3em;display:none;padding:1.6em;margin:0;overflow-x:hidden;overflow-y:auto;line-height:2em;background-color:#fff}.dir-rtl.jsenabled .choosercontainer #chooseform .instruction,.dir-rtl.jsenabled .choosercontainer #chooseform .typesummary{right:18.5em;left:0;border-right:1px solid grey}.jsenabled .choosercontainer #chooseform .instruction,.choosercontainer #chooseform .selected .typesummary{display:block}.choosercontainer #chooseform .selected{background-color:#fff;-webkit-box-shadow:0 0 10px 0 #ccc;-moz-box-shadow:0 0 10px 0 #ccc;box-shadow:0 0 10px 0 #ccc}.section-modchooser-link img.smallicon{padding:3px}.formlistingradio{padding-right:10px;padding-bottom:25px}.formlistinginputradio{float:left}.formlistingmain{min-height:225px}.formlisting{position:relative;padding:1px 19px 14px;margin:15px 0;background-color:white;border:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.formlistingmore{position:absolute;right:-1px;bottom:-1px;padding:3px 7px;font-size:12px;font-weight:bold;color:#9da0a4;cursor:pointer;background-color:whiteSmoke;border:1px solid #ddd;-webkit-border-radius:4px 0 4px 0;-moz-border-radius:4px 0 4px 0;border-radius:4px 0 4px 0}.formlistingall{padding:0;margin:15px 0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.formlistingrow{top:50%;left:50%;float:left;width:150px;min-height:34px;padding:6px;cursor:pointer;background-color:#f7f7f9;border-right:1px solid #e1e1e8;border-bottom:1px solid;border-left:1px solid #e1e1e8;border-color:#e1e1e8;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}body.jsenabled .formlistingradio{display:none}body.jsenabled .formlisting{display:block}table.collection{width:100%;margin-bottom:20px;border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}table.collection th,table.collection td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}table.collection th{font-weight:bold}table.collection thead th{vertical-align:bottom}table.collection caption+thead tr:first-child th,table.collection caption+thead tr:first-child td,table.collection colgroup+thead tr:first-child th,table.collection colgroup+thead tr:first-child td,table.collection thead:first-child tr:first-child th,table.collection thead:first-child tr:first-child td{border-top:0}table.collection tbody+tbody{border-top:2px solid #ddd}table.collection .table{background-color:#fff}table.collection th,table.collection td{border-left:1px solid #ddd}table.collection caption+thead tr:first-child th,table.collection caption+tbody tr:first-child th,table.collection caption+tbody tr:first-child td,table.collection colgroup+thead tr:first-child th,table.collection colgroup+tbody tr:first-child th,table.collection colgroup+tbody tr:first-child td,table.collection thead:first-child tr:first-child th,table.collection tbody:first-child tr:first-child th,table.collection tbody:first-child tr:first-child td{border-top:0}table.collection thead:first-child tr:first-child>th:first-child,table.collection tbody:first-child tr:first-child>td:first-child,table.collection tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}table.collection thead:first-child tr:first-child>th:last-child,table.collection tbody:first-child tr:first-child>td:last-child,table.collection tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}table.collection thead:last-child tr:last-child>th:first-child,table.collection tbody:last-child tr:last-child>td:first-child,table.collection tbody:last-child tr:last-child>th:first-child,table.collection tfoot:last-child tr:last-child>td:first-child,table.collection tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}table.collection thead:last-child tr:last-child>th:last-child,table.collection tbody:last-child tr:last-child>td:last-child,table.collection tbody:last-child tr:last-child>th:last-child,table.collection tfoot:last-child tr:last-child>td:last-child,table.collection tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}table.collection tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}table.collection tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}table.collection caption+thead tr:first-child th:first-child,table.collection caption+tbody tr:first-child td:first-child,table.collection colgroup+thead tr:first-child th:first-child,table.collection colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}table.collection caption+thead tr:first-child th:last-child,table.collection caption+tbody tr:first-child td:last-child,table.collection colgroup+thead tr:first-child th:last-child,table.collection colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}table.collection tbody>tr:nth-child(odd)>td,table.collection tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}table.collection .name{text-align:left;vertical-align:middle}table.collection .awards{width:10%;text-align:center;vertical-align:middle}table.collection .criteria{width:40%;text-align:left;vertical-align:top}table.collection .badgeimage,table.collection .status{width:15%;text-align:center;vertical-align:middle}table.collection .description{width:25%;text-align:left}table.collection .actions{width:11em;text-align:center;vertical-align:middle}a.criteria-action{float:right;padding:0 3px}table.issuedbadgebox{width:750px;background-color:#fff}table.badgeissuedimage{width:150px;text-align:center}table.badgeissuedinfo{width:600px}table.badgeissuedinfo .bvalue{text-align:left;vertical-align:middle}table.badgeissuedinfo .bfield{width:125px;font-style:italic;text-align:left}.dir-rtl table.badgeissuedinfo .bvalue,.dir-rtl table.badgeissuedinfo .bfield{text-align:right}ul.badges{margin:0;list-style:none}.badges li{position:relative;display:inline-block;width:150px;padding-bottom:2em;text-align:center;vertical-align:top}.badges li .badge-name{display:block;padding:5px}.badges li>img{position:absolute}.badges li .badge-image{top:0;left:10px;z-index:1;width:90px;height:90px}.badges li .badge-actions{position:relative}div.badge{position:relative;display:block}div.badge .expireimage{top:0;left:20px;width:100px;height:100px}.expireimage{position:absolute;top:0;left:30px;z-index:10;width:90px;height:90px;opacity:.85;filter:alpha(opacity=85)}.badge-profile{vertical-align:top}.connected{color:#468847}.notconnected{color:#b94a48}.connecting{color:#c09853}#page-badges-award .recipienttable tr td{vertical-align:top}#page-badges-award .recipienttable tr td.actions .actionbutton{width:100%;padding:.5em 0;margin:.3em 0}#page-badges-award .recipienttable tr td.existing,#page-badges-award .recipienttable tr td.potential{width:42%}.statustable{margin-bottom:0}.statusbox.active{background-color:#dff0d8}.statusbox.inactive{background-color:#fcf8e3}.activatebadge{margin:0;text-align:left;vertical-align:middle}.dir-rtl .activatebadge{text-align:right}img#persona_signin{cursor:pointer}.addcourse{float:right}.invisiblefieldset{display:inline;padding:0;margin:0;border-width:0}.breadcrumb-nav{float:left;margin-bottom:10px}.dir-rtl .breadcrumb-nav{float:right}.breadcrumb-button .singlebutton div{margin-right:0}.breadcrumb-nav .breadcrumb{margin:0}.moodle-actionmenu,.moodle-actionmenu>ul,.moodle-actionmenu>ul>li{display:inline-block}.moodle-actionmenu ul{padding:0;margin:0;list-style-type:none}.moodle-actionmenu .toggle-display,.moodle-actionmenu .menu-action-text{display:none}.jsenabled .moodle-actionmenu[data-enhance]{display:block}.jsenabled .moodle-actionmenu[data-enhance] .menu{display:none}.jsenabled .moodle-actionmenu[data-enhance] .toggle-display{display:inline;opacity:.5;filter:alpha(opacity=50)}.jsenabled .moodle-actionmenu[data-enhanced] .toggle-display{opacity:1;filter:alpha(opacity=100)}.jsenabled .moodle-actionmenu[data-enhanced] .menu-action-text{display:inline}.moodle-actionmenu[data-enhanced].show{position:relative}.moodle-actionmenu[data-enhanced].show .menu{position:absolute;z-index:1000;display:block;text-align:left;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}.moodle-actionmenu[data-enhanced].show .menu a{display:block;padding:2px 1em 2px .5em;color:#333}.moodle-actionmenu[data-enhanced].show .menu a:hover,.moodle-actionmenu[data-enhanced].show .menu a:focus{color:#fff;background-color:#08c}.moodle-actionmenu[data-enhanced].show .menu a:first-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.moodle-actionmenu[data-enhanced].show .menu a:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.moodle-actionmenu[data-enhanced].show .menu a.hidden{display:none}.moodle-actionmenu[data-enhanced].show .menu img{vertical-align:middle}.moodle-actionmenu[data-enhanced].show .menu .iconsmall{margin-right:8px}.moodle-actionmenu[data-enhanced].show .menu>li{display:block}.moodle-actionmenu[data-enhanced].show .menu.align-tl-bl{top:100%;left:0;margin-top:4px}.moodle-actionmenu[data-enhanced].show .menu.align-tr-bl{top:100%;right:100%}.moodle-actionmenu[data-enhanced].show .menu.align-bl-bl{bottom:100%;left:0}.moodle-actionmenu[data-enhanced].show .menu.align-br-bl{right:100%;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-br{top:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tr-br{top:100%;right:0;margin-top:4px}.moodle-actionmenu[data-enhanced].show .menu.align-bl-br{bottom:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-br-br{right:0;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-tl{top:0;left:0}.moodle-actionmenu[data-enhanced].show .menu.align-tr-tl{top:0;right:100%;margin-right:4px}.moodle-actionmenu[data-enhanced].show .menu.align-bl-tl{bottom:100%;left:0;margin-bottom:4px}.moodle-actionmenu[data-enhanced].show .menu.align-br-tl{right:100%;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-tr{top:0;left:100%;margin-left:4px}.moodle-actionmenu[data-enhanced].show .menu.align-tr-tr{top:0;right:0}.moodle-actionmenu[data-enhanced].show .menu.align-bl-tr{bottom:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-br-tr{right:0;bottom:100%;margin-bottom:4px}.action-menu-shown .moodle-actionmenu[data-enhanced] .toggle-display{background-color:#FFF}.block .moodle-actionmenu{text-align:right}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu{right:auto;left:0;text-align:right}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu .iconsmall{margin-right:0;margin-left:8px}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-bl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-bl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-bl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-bl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-br{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-br{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-br{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-br{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-tl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-tl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-tl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-tl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-tr{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-tr{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-tr{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-tr{right:auto;left:0}.dir-rtl .block .moodle-actionmenu{text-align:right}ul.dragdrop-keyboard-drag li{list-style-type:none}.block-control-actions .moodle-core-dragdrop-draghandle img{width:12px;height:12px}a.disabled:hover,a.disabled{font-style:italic;color:#808080;text-decoration:none;cursor:default}.formtable tbody th{font-weight:normal;text-align:right}.path-admin #assignrole{width:60%;margin-right:auto;margin-left:auto}.path-admin .admintable .leftalign{text-align:left}.environmenttable p.warn{color:#c09853;background-color:#fcf8e3}.environmenttable .error,.environmenttable span.warn,.environmenttable .ok{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.environmenttable .error:empty,.environmenttable span.warn:empty,.environmenttable .ok:empty{display:none}.environmenttable .error-important,.environmenttable span.warn-important,.environmenttable .ok-important{background-color:#b94a48}.environmenttable .error-important[href],.environmenttable span.warn-important[href],.environmenttable .ok-important[href]{background-color:#953b39}.environmenttable .error-warning,.environmenttable span.warn-warning,.environmenttable .ok-warning{background-color:#f89406}.environmenttable .error-warning[href],.environmenttable span.warn-warning[href],.environmenttable .ok-warning[href]{background-color:#c67605}.environmenttable .error-success,.environmenttable span.warn-success,.environmenttable .ok-success{background-color:#468847}.environmenttable .error-success[href],.environmenttable span.warn-success[href],.environmenttable .ok-success[href]{background-color:#356635}.environmenttable .error-info,.environmenttable span.warn-info,.environmenttable .ok-info{background-color:#3a87ad}.environmenttable .error-info[href],.environmenttable span.warn-info[href],.environmenttable .ok-info[href]{background-color:#2d6987}.environmenttable .error-inverse,.environmenttable span.warn-inverse,.environmenttable .ok-inverse{background-color:#333}.environmenttable .error-inverse[href],.environmenttable span.warn-inverse[href],.environmenttable .ok-inverse[href]{background-color:#1a1a1a}.environmenttable .error{background-color:#b94a48}.environmenttable span.warn{background-color:#f89406}.environmenttable .ok{background-color:#468847}.path-admin .admintable.environmenttable .name,.path-admin .admintable.environmenttable .info,.path-admin #assignrole .admintable .role,.path-admin #assignrole .admintable .userrole,.path-admin #assignrole .admintable .roleholder{white-space:nowrap}.path-admin .incompatibleblockstable td.c0{font-weight:bold}#page-admin-course-category .addcategory{padding:10px}#page-admin-course-index .editcourse{margin:20px auto}#page-admin-course-index .editcourse th,#page-admin-course-index .editcourse td{padding-right:10px;padding-left:10px}.timewarninghidden{display:none}.statusok,.statuswarning,.statusserious,.statuscritical{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.statusok:empty,.statuswarning:empty,.statusserious:empty,.statuscritical:empty{display:none}.statusok-important,.statuswarning-important,.statusserious-important,.statuscritical-important{background-color:#b94a48}.statusok-important[href],.statuswarning-important[href],.statusserious-important[href],.statuscritical-important[href]{background-color:#953b39}.statusok-warning,.statuswarning-warning,.statusserious-warning,.statuscritical-warning{background-color:#f89406}.statusok-warning[href],.statuswarning-warning[href],.statusserious-warning[href],.statuscritical-warning[href]{background-color:#c67605}.statusok-success,.statuswarning-success,.statusserious-success,.statuscritical-success{background-color:#468847}.statusok-success[href],.statuswarning-success[href],.statusserious-success[href],.statuscritical-success[href]{background-color:#356635}.statusok-info,.statuswarning-info,.statusserious-info,.statuscritical-info{background-color:#3a87ad}.statusok-info[href],.statuswarning-info[href],.statusserious-info[href],.statuscritical-info[href]{background-color:#2d6987}.statusok-inverse,.statuswarning-inverse,.statusserious-inverse,.statuscritical-inverse{background-color:#333}.statusok-inverse[href],.statuswarning-inverse[href],.statusserious-inverse[href],.statuscritical-inverse[href]{background-color:#1a1a1a}.statusok{background-color:#468847}.statuswarning{background-color:#c09853}.statusserious{background-color:#f89406}.statuscritical{background-color:#b94a48}#page-admin-report-capability-index #capabilitysearch{width:30em}#page-admin-report-backups-index .backup-error,#page-admin-report-backups-index .backup-unfinished{color:#b94a48}#page-admin-report-backups-index .backup-skipped,#page-admin-report-backups-index .backup-ok{color:#468847}#page-admin-report-backups-index .backup-warning{color:#c09853}#page-admin-qtypes .disabled,#page-admin-qbehaviours .disabled{color:#999}#page-admin-qtypes #qtypes div,#page-admin-qtypes #qtypes form,#page-admin-qbehaviours #qbehaviours div,#page-admin-qbehaviours #qbehaviours form{display:inline}#page-admin-qtypes #qtypes img.spacer,#page-admin-qbehaviours #qbehaviours img.spacer{width:16px}img.iconsmall{padding:.3em;margin:0}#page-admin-qbehaviours .cell.c3,#page-admin-qtypes .cell.c3{font-size:10.5px}#page-admin-lang .generalbox,#page-admin-course-index .singlebutton,#page-admin-course-index .addcategory,#page-course-index .buttons,#page-course-index-category .buttons,#page-admin-course-category .addcategory,#page-admin-stickyblocks .generalbox,#page-admin-maintenance .buttons,#page-admin-course-index .buttons,#page-admin-course-category .buttons,#page-admin-index .copyright,#page-admin-index .copyrightnotice,#page-admin-index .adminerror,#page-admin-index .availableupdatesinfo,#page-admin-index .adminerror .singlebutton,#page-admin-index .adminwarning .singlebutton,#page-admin-index #layout-table .singlebutton{margin-bottom:1em;text-align:center}.path-admin-roles .capabilitysearchui{margin-right:auto;margin-left:auto;text-align:left}#page-admin-roles-define .topfields{margin:1em 0 2em}#page-admin-roles-define .capdefault{background-color:#eee;border:1px solid #cecece}#page-filter-manage .backlink,.path-admin-roles .backlink{margin-top:1em}#page-admin-roles-explain #chooseuser h3,#page-admin-roles-usersroles .contextname{margin-top:0}#page-admin-roles-explain #chooseusersubmit{margin-top:0;text-align:center}#page-admin-roles-usersroles p{margin:0}#page-admin-roles-override .cell.c1,#page-admin-roles-assign .cell.c3,#page-admin-roles-assign .cell.c1{padding-top:.75em}#page-admin-roles-override .overridenotice,#page-admin-roles-define .definenotice{margin:1em 10% 2em 10%;text-align:left}#notice{width:60%;min-width:220px;margin:auto}#page-admin-index .releasenoteslink,#page-admin-index .adminwarning,#page-admin-index .maturitywarning,#page-admin-index .testsitewarning,#page-admin-index .maturityinfo{width:60%;min-width:220px;padding:8px 35px 8px 14px;margin:auto;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}#page-admin-index .maturitywarning,#page-admin-index .testsitewarning,#page-admin-index .adminwarning.maturityinfo.maturity50{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}#page-admin-index .adminwarning.availableupdatesinfo,#page-admin-index .releasenoteslink{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo span{display:block}#page-admin-index .updateplugin div,#page-admin-plugins .updateplugin div{margin-bottom:.5em}#page-admin-index .updateplugin .updatepluginconfirmexternal,#page-admin-plugins .updateplugin .updatepluginconfirmexternal{padding:1em;background-color:#f2dede;border:1px solid #eed3d7}#page-admin-user-user_bulk #users .fgroup{white-space:nowrap}#page-admin-report-stats-index .graph{margin-bottom:1em;text-align:center}#page-admin-report-courseoverview-index .graph{margin-bottom:1em;text-align:center}#page-admin-lang .translator{border-style:solid;border-width:1px}.path-admin .roleassigntable{width:100%}.path-admin .roleassigntable td{padding:.2em .3em;vertical-align:top}.path-admin .roleassigntable p{margin:.2em 0;text-align:left}.path-admin .roleassigntable #existingcell,.path-admin .roleassigntable #potentialcell{width:42%}.path-admin .roleassigntable #existingcell p>label:first-child,.path-admin .roleassigntable #potentialcell p>label:first-child{font-weight:bold}.path-admin .roleassigntable #buttonscell{width:16%}.path-admin .roleassigntable #buttonscell #assignoptions{font-size:10.5px}.path-admin .roleassigntable #removeselect_wrapper,.path-admin .roleassigntable #addselect_wrapper{width:100%}.path-admin table.rolecap tr.rolecap th{font-weight:normal;text-align:left}.path-admin.dir-rtl table.rolecap tr.rolecap th{text-align:right}.path-admin .rolecap .hiddenrow{display:none}.path-admin #defineroletable .rolecap .inherit,.path-admin #defineroletable .rolecap .allow,.path-admin #defineroletable .rolecap .prevent,.path-admin #defineroletable .rolecap .prohibit{min-width:3.5em;padding:0;text-align:center}.path-admin .rolecap .cap-name,.path-admin .rolecap .note{display:block;font-size:10.5px;font-weight:normal;white-space:nowrap}.path-admin .rolecap label{display:block;padding:.5em;margin:0;text-align:center}.plugincheckwrapper{width:100%}.environmentbox{margin-top:1em}#mnetconfig table{margin-right:auto;margin-left:auto}.environmenttable .cell{padding:.15em .5em}.environmenttable img.iconhelp{padding-right:.3em}.dir-rtl .environmenttable img.iconhelp{padding-right:0;padding-left:.3em}#trustedhosts .generaltable{width:500px;margin-right:auto;margin-left:auto}#trustedhosts .standard{width:auto}#adminsettings legend{display:none}#adminsettings fieldset.error{margin:.2em 0 .5em 0}#adminsettings fieldset.error legend{display:block}.dir-rtl #admin-spelllanguagelist textarea,#page-admin-setting-editorsettingstinymce.dir-rtl .form-textarea textarea{text-align:left;direction:ltr}.adminsettingsflags{float:right}.dir-rtl .adminsettingsflags{float:left}.adminsettingsflags label{margin-right:7px}.dir-rtl .adminsettingsflags label{margin-left:7px}.form-description{clear:right}.dir-rtl .form-description{clear:left}.form-item .form-setting .form-htmlarea{display:inline;width:640px}.form-item .form-setting .form-htmlarea .htmlarea{display:block;width:640px}.form-item .form-setting .form-multicheckbox ul{padding:0;margin:7px 0 0 0;list-style:none}.form-item .form-setting .defaultsnext{display:inline;margin-right:.5em}.dir-rtl .form-item .form-setting .defaultsnext{margin-right:0;margin-left:.5em}.form-item .form-setting .locked-checkbox{display:inline;margin-right:.2em;margin-left:.5em}.dir-rtl .form-item .form-setting .locked-checkbox{display:inline;margin-right:.5em;margin-left:.2em}.form-item .form-setting .form-password .unmask,.form-item .form-setting .form-defaultinfo{display:inline-block}.form-item .pathok,.form-item .patherror{margin-left:.5em}#admin-devicedetectregex table{border:0}#admin-emoticons td input{width:8em}#admin-emoticons td.c0 input{width:4em}#adminthemeselector .selectedtheme td.c0{border:1px solid;border-right-width:0}#adminthemeselector .selectedtheme td.c1{border:1px solid;border-left-width:0}.admin_colourpicker,.admin_colourpicker_preview{display:none}.jsenabled .admin_colourpicker_preview{display:inline}.jsenabled .admin_colourpicker{display:block;width:410px;height:102px;margin-bottom:10px}.admin_colourpicker .loadingicon{margin-left:auto;vertical-align:middle}.admin_colourpicker .colourdialogue{float:left;border:1px solid #000}.admin_colourpicker .previewcolour{margin-left:301px;border:1px solid #000}.admin_colourpicker .currentcolour{margin-left:301px;border:1px solid #000;border-top-width:0}.dir-rtl .form-item .form-setting,.dir-rtl .form-item .form-label,.dir-rtl .form-item .form-description,.dir-rtl.path-admin .roleassigntable p{text-align:right}#page-admin-index #notice .checkforupdates{text-align:center}#plugins-check-info{margin:1em;text-align:center}#plugins-check .displayname .pluginicon{width:16px}#plugins-check .status-new .status{background-color:#dff0d8}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release,#plugins-check .status-upgrade .status,#plugins-check .status-delete .status{background-color:#d9edf7}#plugins-control-panel .extension .source,#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity100 .info.release,#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity150 .info.release,.pluginupdateinfo.maturity100,.pluginupdateinfo.maturity150,#plugins-check .extension .source{background-color:#fcf8e3}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity50 .info.release,.pluginupdateinfo.maturity50,#plugins-check .requires-failed,#plugins-check .missingfromdisk .displayname,#plugins-check .status-missing .status,#plugins-check .status-downgrade .status{background-color:#f2dede}#plugins-control-panel .statusmsg{padding:3px;background-color:#eee;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#plugins-control-panel .status-missing .pluginname{background-color:#f2dede}#plugins-control-panel .status-missing .statusmsg{color:#b94a48}#plugins-control-panel .status-new .pluginname{background-color:#dff0d8}#plugins-control-panel .status-new .statusmsg{color:#468847}#plugins-control-panel .disabled .availability{background-color:#eee}#plugins-check .standard .source,#plugins-check .status-nodb .status,#plugins-check .status-uptodate .status,#plugins-check .requires-ok{color:#999}#plugins-check .requires ul{margin:0;font-size:10.5px}#plugins-check .status .pluginupdateinfo{padding:5px 10px;margin:10px;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-check .status .pluginupdateinfo span,#plugins-check .status .pluginupdateinfo a{padding-right:1em}#page-admin-index .upgradepluginsinfo{text-align:center}#page-admin-plugins .checkforupdates{margin:0 auto 1em;text-align:center}#plugins-control-panel .requiredby,#plugins-control-panel .pluginname .componentname{font-size:11.9px;color:#999}#plugins-control-panel .pluginname .componentname{margin-left:22px}#plugins-overview-filter .filter-item,#plugins-overview-panel .info{padding:0 10px}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo .separator,#plugins-check .status .pluginupdateinfo .separator,#page-admin-plugins .separator{border-left:1px dotted #999}#plugins-control-panel .msg td{text-align:center}#plugins-overview-filter,#plugins-overview-panel{margin:1em auto;text-align:center}#plugins-overview-panel .info.updatable{margin-left:10px;font-weight:bold;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-overview-filter .filter-item.active{font-weight:bold}#plugins-control-panel .displayname img.icon{padding-top:0;padding-bottom:0}#plugins-control-panel .uninstall a{color:#b94a48}#plugins-control-panel .notes .pluginupdateinfo{padding:5px 10px;margin:10px;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-control-panel .notes .pluginupdateinfo span,#plugins-control-panel .notes .pluginupdateinfo a{padding-right:1em}.dir-rtl #plugins-check .pluginupdateinfo{text-align:center;direction:ltr}.dir-rtl #plugins-check .rootdir,.dir-rtl #plugins-check .requires-ok{text-align:left;direction:ltr}#page-admin-mnet-peers .box.deletedhosts{margin-bottom:1em;font-size:11.9px}#page-admin-mnet-peers .mform .certdetails{background-color:white}#page-admin-mnet-peers .mform .deletedhostinfo{padding:4px;margin-bottom:5px;background-color:#f2dede;border:2px solid #eed3d7}#core-cache-plugin-summaries table,#core-cache-store-summaries table{width:100%}#core-cache-lock-summary table,#core-cache-definition-summaries table,#core-cache-mode-mappings table{margin:0 auto}#core-cache-store-summaries .default-store td{font-style:italic;color:#333}#core-cache-rescan-definitions,#core-cache-mode-mappings .edit-link,#core-cache-lock-summary .new-instance{margin-top:.5em;text-align:center}.tinymcesubplugins img.icon{padding-top:0;padding-bottom:0}#page-admin-roles-assign div.box.generalbox{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;color:#b94a48;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;background-color:#f2dede;border:1px solid #fbeed5;border-color:#eed3d7;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.calendartable{width:100%}.calendartable th,.calendartable td{width:14%;text-align:center;vertical-align:top;border:0}.calendar_event_course{background-color:#ffd3bd}.calendar_event_global{background-color:#d6f8cd}.calendar_event_group{background-color:#fee7ae}.calendar_event_user{background-color:#dce7ec}.path-calendar .calendar-controls .previous,.path-calendar .calendar-controls .next,.path-calendar .calendar-controls .current{display:block;float:left;width:12%}.path-calendar .calendar-controls .previous{text-align:left}.path-calendar .calendar-controls .current{width:76%;text-align:center}.path-calendar .calendar-controls .next{text-align:right}.path-calendar .maincalendar{padding:0;vertical-align:top}.path-calendar .maincalendar .bottom{padding:5px 0 0 0;text-align:center}.path-calendar .maincalendar .heightcontainer{position:relative;height:100%}.path-calendar .maincalendar .calendarmonth{width:98%;margin:10px auto}.path-calendar .maincalendar .calendarmonth ul{margin:0}.path-calendar .maincalendar .calendarmonth ul li{margin-top:4px;list-style-type:none}.path-calendar .maincalendar .calendarmonth td{height:5em}.path-calendar .maincalendar .calendar-controls .previous,.path-calendar .maincalendar .calendar-controls .next{width:30%}.path-calendar .maincalendar .calendar-controls .current{width:39.95%}.path-calendar .maincalendar .controls{width:98%;margin:10px auto}.path-calendar .maincalendar .eventlist .event{width:100%;margin-bottom:10px;border-collapse:separate;border-spacing:0;border-style:solid;border-width:1px}.path-calendar .maincalendar .eventlist .event .topic .name{float:left}.dir-rtl.path-calendar .maincalendar .eventlist .event .topic .name,.path-calendar .maincalendar .eventlist .event .topic .date{float:right}.dir-rtl.path-calendar .maincalendar .eventlist .event .topic .date{float:left}.path-calendar .maincalendar .eventlist .event .subscription,.path-calendar .maincalendar .eventlist .event .course{float:left;clear:left}.dir-rtl.path-calendar .maincalendar .eventlist .event .subscription,.dir-rtl.path-calendar .maincalendar .eventlist .event .course{float:right;clear:right}.path-calendar .maincalendar .eventlist .event .side{width:32px}.path-calendar .maincalendar .eventlist .event .commands a{margin:0 3px}.path-calendar .maincalendar .header{overflow:hidden}.path-calendar .maincalendar .header .buttons{float:right}.dir-rtl.path-calendar .maincalendar .header .buttons{float:left}.path-calendar .filters table{width:100%;border-collapse:separate;border-spacing:2px}#page-calendar-export .indent{padding-left:20px}.path-calendar .cal_courses_flt label{margin-right:.45em}.dir-rtl.path-calendar .cal_courses_flt label{margin-right:0;margin-left:.45em}.block .minicalendar th,.block .minicalendar td{padding:2px;font-size:.8em}.block .minicalendar{max-width:280px;margin-right:auto;margin-left:auto}.block .minicalendar td.weekend{color:#A00}.block .calendar-controls .previous{display:block;float:left;width:12%;text-align:left}.block .calendar-controls .current{display:block;float:left;width:76%;text-align:center}.block .calendar-controls .next{display:block;float:left;width:12%;text-align:right}.block .calendar_filters ul{margin:0;list-style:none}.block .calendar_filters li{margin-bottom:.2em}.block .calendar_filters li span img{padding:0 .2em}.block .calendar_filters .eventname{padding-left:.2em}.dir-rtl .block .calendar_filters .eventname{padding-right:.2em;padding-left:0}.block .content h3.eventskey{margin-top:.5em}@media(min-width:768px){#page-calender-view .container fluid{min-width:1024px}}.section_add_menus{text-align:right}.dir-rtl .section_add_menus{text-align:left}.section_add_menus .horizontal div,.section_add_menus .horizontal form{display:inline}.section_add_menus optgroup{font-style:italic;font-weight:normal}.section_add_menus .urlselect{margin-left:.4em}.dir-rtl .section_add_menus .urlselect{margin-right:.4em;margin-left:0}.section_add_menus .urlselect select{margin-left:.2em}.dir-rtl .section_add_menus .urlselect select{margin-right:.2em;margin-left:0}.section_add_menus .urlselect img.iconhelp{padding:0;margin:0;vertical-align:text-bottom}.site-topic ul.section,.course-content ul.section{margin:1em}.section .activity img.activityicon{margin-right:6px}.dir-rtl .section .activity img.activityicon{margin-right:0;margin-left:6px}.section .activity .activityinstance,.section .activity .activityinstance div{display:inline-block}.editing .section .activity .activityinstance{min-width:40%}.section .activity .activityinstance>a{display:block}.editing_show+.editing_assign,.editing_hide+.editing_assign{margin-left:20px}.section .activity .commands{display:inline;white-space:nowrap}.section .activity.modtype_label .commands{padding-left:.2em;margin-left:40%}.section .activity.modtype_label.label{padding:.2em;font-weight:normal}.section li.activity{padding:.2em;clear:both}.section .activity .activityinstance .groupinglabel{padding-left:30px}.dir-rtl .section .activity .activityinstance .groupinglabel{padding-right:30px}.section .activity .availabilityinfo,.section .activity .contentafterlink{margin-top:.5em;margin-left:30px}.dir-rtl .section .activity .availabilityinfo,.dir-rtl .section .activity .contentafterlink{margin-right:30px;margin-left:0}.section .activity .contentafterlink p{margin:.5em 0}.editing .section .activity:hover,.editing .section .activity.action-menu-shown{background-color:#eee}.course-content .current{background-color:#d9edf7}.course-content .section-summary{margin-top:5px;list-style:none;border:1px solid #DDD}.course-content .section-summary .section-title{margin:2px 5px 10px 5px}.course-content .section-summary .summarytext{margin:2px 5px 2px 5px}.course-content .section-summary .section-summary-activities .activity-count{display:inline-block;margin:3px;font-size:11.9px;color:#999;white-space:nowrap}.course-content .section-summary .summary{margin-top:5px}.course-content .single-section{margin-top:1em}.course-content .single-section .section-navigation{display:block;padding:.5em;margin-bottom:-0.5em}.course-content .single-section .section-navigation .title{clear:both;font-size:108%;font-weight:bold}.course-content .single-section .section-navigation .mdl-left{float:left;margin-right:1em;font-weight:normal}.dir-rtl .course-content .single-section .section-navigation .mdl-left{float:right}.course-content .single-section .section-navigation .mdl-left .larrow{margin-right:.1em}.course-content .single-section .section-navigation .mdl-right{float:right;margin-left:1em;font-weight:normal}.dir-rtl .course-content .single-section .section-navigation .mdl-right{float:left}.course-content .single-section .section-navigation .mdl-right .rarrow{margin-left:.1em}.course-content .single-section .section-navigation .mdl-bottom{margin-top:0}.course-content ul li.section.main{margin-top:0;border-bottom:2px solid #eee}.course-content ul li.section.hidden{opacity:.5}.course-content ul.topics li.section .content,.course-content ul.weeks li.section .content{padding:0;margin-right:20px;margin-left:20px}.course-content{margin-top:0}.course-content ul.topics li.section{padding-bottom:20px}.course-content ul.topics li.section .summary{margin-left:25px}.path-course-view .completionprogress{margin-left:25px}.path-course-view .completionprogress{position:relative;z-index:1000;display:block;float:right;height:20px}#page-site-index .subscribelink{text-align:right}#page-site-index .headingblock{margin-bottom:9px}.path-course-view a.reduce-sections{padding-left:.2em}.path-course-view .headingblock{margin-bottom:9px}.path-course-view .subscribelink{text-align:right}.path-course-view .unread{margin-left:30px}.dir-rtl.path-course-view .unread{margin-right:30px}.path-course-view .block.drag .header{cursor:move}.path-course-view .completionprogress{text-align:right}.dir-rtl.path-course-view .completionprogress{text-align:left}.path-course-view .single-section .completionprogress{margin-right:5px}.path-course-view .section .summary{line-height:normal}.path-site li.activity>div,.path-course-view li.activity>div{position:relative}.path-course-view li.activity span.autocompletion,.path-course-view li.activity form.togglecompletion{float:right}.path-course-view li.activity form.togglecompletion .ajaxworking{width:16px;height:16px;background:url([[pix:i/ajaxloader]]) no-repeat}.dir-rtl.path-course-view li.activity form.togglecompletion,.dir-rtl.path-course-view li.activity span.autocompletion{float:left}.dir-rtl.path-course-view .completionprogress{float:none}.dir-rtl.path-course-view li.activity form.togglecompletion .ajaxworking{right:-22px}li.section.hidden span.commands a.editing_hide,li.section.hidden span.commands a.editing_show{cursor:default}ul.weeks h3.sectionname{white-space:nowrap}.editing ul.weeks h3.sectionname{white-space:normal}.single-section h3.sectionname{clear:both;text-align:center}.section img.movetarget{width:80px;height:16px}input.titleeditor{width:330px;vertical-align:text-bottom}span.editinstructions{position:absolute;top:0;left:0;z-index:9999;padding:.1em .4em;margin-top:-22px;margin-left:30px;font-size:11.9px;line-height:16px;color:#3a87ad;text-decoration:none;background-color:#d9edf7;border:1px solid #bce8f1;-webkit-box-shadow:2px 2px 5px 1px #ccc;-moz-box-shadow:2px 2px 5px 1px #ccc;box-shadow:2px 2px 5px 1px #ccc}.dir-rtl span.editinstructions{right:32px;left:auto}#dndupload-status{position:absolute;z-index:9999;z-index:0;width:40%;padding:6px;margin:0 30%;color:#3a87ad;text-align:center;background:#d9edf7;border:1px solid #bce8f1;-webkit-border-bottom-right-radius:8px;border-bottom-right-radius:8px;-webkit-border-bottom-left-radius:8px;border-bottom-left-radius:8px;-moz-border-radius-bottomright:8px;-moz-border-radius-bottomleft:8px;-webkit-box-shadow:2px 2px 5px 1px #ccc;-moz-box-shadow:2px 2px 5px 1px #ccc;box-shadow:2px 2px 5px 1px #ccc}.dndupload-preview{padding:.3em;margin-top:.2em;color:#909090;list-style:none;border:1px dashed #909090}.dndupload-preview img.icon{padding:0;vertical-align:text-bottom}.dndupload-progress-outer{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.dndupload-progress-inner{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.dndupload-hidden{display:none}#page-course-pending .singlebutton,#page-course-index .singlebutton,#page-course-index-category .singlebutton,#page-course-editsection .singlebutton{text-align:center}#page-admin-course-manage #movecourses td img{margin:0 .22em;vertical-align:text-bottom}#page-admin-course-manage #movecourses td img.icon{padding:0}#coursesearch{margin-top:1em;text-align:center}#page-course-pending .pendingcourserequests{margin-bottom:1em}#page-course-pending .pendingcourserequests .singlebutton{display:inline}#page-course-pending .pendingcourserequests .cell{padding:0 5px}#page-course-pending .pendingcourserequests .cell.c6{white-space:nowrap}.coursebox{padding:5px;margin-bottom:15px;border:1px dotted #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.coursebox>.info>.name a{display:block;padding-left:21px;background-image:url([[pix:moodle|i/course]]);background-position:center left;background-repeat:no-repeat}.coursebox.remotehost>.info>.name a{background-image:url([[pix:moodle|i/mnethost]])}.coursebox>.info>.name,.coursebox .content .teachers,.coursebox .content .courseimage,.coursebox .content .coursefile{float:left;width:40%;clear:left}.coursebox>.info>h3.name{margin:5px}.coursebox>.info>.name{padding:0;margin:5px}.coursebox .content .teachers li{padding:0;margin:0;list-style-type:none}.coursebox .enrolmenticons{float:right;padding:3px 0}.coursebox .moreinfo{float:right;padding:3px 0}.coursebox .enrolmenticons img,.coursebox .moreinfo img{margin:0 .2em}.coursebox .content{clear:both}.coursebox .content .summary,.coursebox .content .coursecat{float:right;width:55%}.coursebox .content .coursecat{clear:right;text-align:right}.coursebox.remotecoursebox .remotecourseinfo{float:left;width:40%}.coursebox .content .courseimage img{max-width:100px;max-height:100px}.coursebox .content .coursecat,.coursebox .content .summary,.coursebox .content .courseimage,.coursebox .content .coursefile,.coursebox .content .teachers,.coursebox.remotecoursebox .remotecourseinfo{padding:0;margin:3px 5px}.dir-rtl .coursebox>.info>.name a{padding-right:21px;padding-left:0;background-position:center right}.dir-rtl .coursebox>.info>.name,.dir-rtl .coursebox .teachers,.dir-rtl .coursebox .content .courseimage,.dir-rtl .coursebox .content .coursefile{float:right;clear:right}.dir-rtl .coursebox .enrolmenticons,.dir-rtl .coursebox .moreinfo{float:left}.dir-rtl .coursebox .summary,.dir-rtl .coursebox .coursecat{float:left}.dir-rtl .coursebox .coursecat{clear:left;text-align:left}.coursebox.collapsed{margin-bottom:0}.coursebox.collapsed>.content{display:none}.courses .coursebox.collapsed{padding:3px 0;border:1px solid #eee}.courses .coursebox.even{background-color:#f6f6f6}.courses .coursebox:hover,.course_category_tree .courses>.paging.paging-morelink:hover{background-color:#eee}.course_category_tree .category .numberofcourse{font-size:11.9px}.course_category_tree .category>.info .name{padding:2px 18px;margin:3px;background-image:url([[pix:moodle|t/collapsed_empty]]);background-position:center left;background-repeat:no-repeat}.dir-rtl .course_category_tree .category>.info .name{background-image:url([[pix:moodle|t/collapsed_empty_rtl]]);background-position:center right}.course_category_tree .category.with_children>.info .name{cursor:pointer;background-image:url([[pix:moodle|t/expanded]])}.course_category_tree .category.with_children.collapsed>.info .name{background-image:url([[pix:moodle|t/collapsed]])}.dir-rtl .course_category_tree .category.with_children.collapsed>.info .name{background-image:url([[pix:moodle|t/collapsed_rtl]])}.course_category_tree .category.collapsed>.content{display:none}.course_category_tree .category>.info{min-height:20px;min-height:0;padding:19px;padding:0;margin:3px 0;margin-bottom:20px;margin-bottom:3px;clear:both;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.course_category_tree .category>.info blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.course_category_tree.frontpage-category-names .category>.info{margin:0;background:0;border:0}.course_category_tree .category>.content{padding-left:16px}.dir-rtl .course_category_tree .category>.content{padding-right:16px;padding-left:0}.course_category_tree .subcategories>.paging,.courses>.paging{padding:5px;margin:0;text-align:center}.courses>.paging.paging-morelink,.course_category_tree .subcategories>.paging.paging-morelink{text-align:left}.course_category_tree .paging.paging-morelink a{font-size:11.9px}.dir-rtl .courses>.paging.paging-morelink,.dir-rtl .course_category_tree .paging.paging-morelink{text-align:right}#page-course-index-category .generalbox.info{padding:5px;margin-bottom:15px;border:1px dotted #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}#page-course-index-category .categorypicker{margin:10px 0 20px;text-align:center}.section .activity .moodle-actionmenu .iconsmall{width:16px;width:1rem;height:16px;height:1rem;max-width:none!important;padding:.3em}.filemanager,.filepicker,.file-picker{font-size:11px}.filemanager a,.file-picker a,.filemanager a:hover,.file-picker a:hover{color:#555;text-decoration:none}.filemanager input[type="text"],.file-picker input[type="text"]{width:265px}.filemanager .fp-license td,.file-picker .fp-setlicense td{max-width:265px}.filemanager .fp-license select,.file-picker .fp-setlicense select{max-width:100%}.fp-content-center{display:table-cell;width:100%;height:100%;vertical-align:middle}.fp-content-hidden{visibility:hidden}.yui3-panel-focused{outline:0}#filesskin .yui3-panel-content{display:inline-block;*display:inline;padding-bottom:20px;background:#f2f2f2;border:1px solid #fff;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;*zoom:1;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}#filesskin .yui3-widget-hd{padding:5px;font-size:12px;letter-spacing:1px;color:#333;text-align:center;text-shadow:1px 1px 1px #fff;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border-bottom:1px solid #bbb;-webkit-border-radius:10px 10px 0 0;-moz-border-radius:10px 10px 0 0;border-radius:10px 10px 0 0;filter:dropshadow(color=#ffffff,offx=1,offy=1);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}.fp-panel-button{display:inline-block;*display:inline;padding:3px 20px 2px 20px;margin:10px;text-align:center;background:#fff;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;*zoom:1;-webkit-box-shadow:2px 2px 3px .1px #999;-moz-box-shadow:2px 2px 3px .1px #999;box-shadow:2px 2px 3px .1px #999}.filepicker .moodle-dialogue-wrap .moodle-dialogue-bd{padding:0}#filesskin .file-picker.fp-generallayout{position:relative;width:859px;background:#fff;border:1px solid #ccc;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.file-picker .fp-repo-area{display:inline-block;*display:inline;float:left;width:180px;height:525px;overflow:auto;border-right:1px solid #bbb;*zoom:1}.dir-rtl .file-picker .fp-repo-area{float:right;border-right:0;border-left:1px solid #bbb}.file-picker .fp-repo-items{float:left;width:693px}.dir-rtl .file-picker .fp-repo-items{float:right}.file-picker .fp-navbar{min-height:22px;padding:5px 8px;background:#f2f2f2;border-bottom:1px solid #bbb}.file-picker .fp-content{height:468px;overflow:auto;clear:both;background:#fff}.filepicker.moodle-dialogue-fullscreen .file-picker .fp-content{width:100%;height:100%}.dir-rtl .file-picker .fp-repo-items{margin-right:181px}.file-picker .fp-content-loading{display:table;width:100%;height:100%;text-align:center}.file-picker .fp-content .fp-object-container{width:98%;height:98%}.dir-rtl .file-picker .fp-list{text-align:right}.dir-rtl .file-picker .fp-toolbar{padding:0}.dir-rtl .file-picker .fp-list{text-align:right}.dir-rtl .file-picker .fp-repo-name{display:inline}.dir-rtl .file-picker .fp-pathbar{display:block;text-align:right;border-top:0}.dir-rtl .file-picker div.bd{text-align:right}.dir-rtl #filemenu .yuimenuitemlabel{text-align:right}.dir-rtl .filepicker .yui-layout-unit-left{left:500px}.dir-rtl .filepicker .yui-layout-unit-center{left:0}.dir-rtl .filemanager-toolbar a{padding:0}.file-picker .fp-list{float:left;width:100%;padding:0;margin:0;list-style-type:none}.dir-rtl .file-picker .fp-list{float:left;text-align:right}.file-picker .fp-list .fp-repo a{display:block;padding:.5em .7em}.file-picker .fp-list .fp-repo.active{background:#f2f2f2}.file-picker .fp-list .fp-repo-icon{padding:0 7px 0 5px}.fp-toolbar{display:table-row;float:left;max-width:70%;line-height:22px}.dir-rtl .fp-toolbar{float:right}.fp-toolbar.empty{display:none}.fp-toolbar .disabled{display:none}.fp-toolbar div{display:inline-block;*display:inline;padding:0 2px;padding-right:10px;*zoom:1}.dir-rtl .fp-toolbar div{width:100px;padding-right:0}.fp-toolbar img{margin-right:5px;vertical-align:-15%}.fp-toolbar .fp-tb-search{width:228px;height:14px}.fp-toolbar .fp-tb-search input{width:200px;height:16px;padding:2px 6px 1px 20px;background:#fff url('[[pix:a/search]]') no-repeat 3px 3px;border:1px solid #bbb}.fp-viewbar{float:right;width:69px;height:22px;margin-right:8px}.dir-rtl .fp-toolbar img{vertical-align:-35%}.dir-rtl .fp-viewbar{float:left;width:100px}.fp-vb-icons{display:inline-block;*display:inline;width:22px;height:22px;background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-icons{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0}.fp-vb-icons.checked{background:url('[[pix:theme|fp/view_icon_selected]]')}.dir-rtl .fp-vb-icons.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_icon_selected]]')}.fp-viewbar.disabled .fp-vb-icons{background:url('[[pix:theme|fp/view_icon_inactive]]')}.fp-vb-details{display:inline-block;*display:inline;width:23px;height:22px;margin-left:-4px;background:url('[[pix:theme|fp/view_list_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-details{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_list_active]]') no-repeat 0 0}.fp-vb-details.checked{background:url('[[pix:theme|fp/view_list_selected]]')}.dir-rtl .fp-vb-details.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_list_selected]]')}.fp-viewbar.disabled .fp-vb-details{background:url('[[pix:theme|fp/view_list_inactive]]')}.fp-vb-tree{display:inline-block;*display:inline;width:23px;height:22px;margin-left:-4px;background:url('[[pix:theme|fp/view_tree_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-tree{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_tree_active]]') no-repeat 0 0}.fp-vb-tree.checked{background:url('[[pix:theme|fp/view_tree_selected]]')}.dir-rtl .fp-vb-tree.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_tree_selected]]')}.fp-viewbar.disabled .fp-vb-tree{background:url('[[pix:theme|fp/view_tree_inactive]]')}.file-picker .fp-clear-left{clear:left}.dir-rtl .filemanager-toolbar .fp-vb-icons a:hover{background:url('[[pix:theme|fp/view_icon_selected]]')}.dir-rtl .filemanager-toolbar .fp-vb-icons.checked a:hover{background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0}.dir-rtl .fp-vb-details a:hover{background:0;border:20px solid black}.dir-rtl .fp-vb-details.checked a:hover{background:0;border:40px solid black}.dir-rtl .fp-vb-tree a:hover{background:0;border:30px solid black}.dir-rtl .fp-vb-tree.checked a:hover{background:0;border:50px solid black}.file-picker .fp-pathbar{display:table-row}.fp-pathbar.empty{display:none}.fp-pathbar .fp-path-folder{width:27px;height:12px;margin-left:4px;background:url('[[pix:theme|fp/path_folder]]') no-repeat 0 0}.dir-rtl .fp-pathbar .fp-path-folder{width:auto;height:12px;margin-left:4px;background:url('[[pix:theme|fp/path_folder_rtl]]') no-repeat right top}.dir-rtl .fp-pathbar span{display:inline-block;*display:inline;float:right;margin-left:32px;*zoom:1}.fp-pathbar .fp-path-folder-name{margin-left:32px;line-height:20px}.dir-rtl .fp-pathbar .fp-path-folder-name{margin-right:32px;line-height:20px}.fp-iconview .fp-file{position:relative;float:left;margin:10px 10px 35px;text-align:center}.fp-iconview .fp-thumbnail{display:block;min-width:110px;min-height:110px;line-height:110px;text-align:center;border:1px solid #fff}.fp-iconview .fp-thumbnail img{padding:3px;vertical-align:middle;border:1px solid #ddd;-webkit-box-shadow:1px 1px 2px 0 #ccc;-moz-box-shadow:1px 1px 2px 0 #ccc;box-shadow:1px 1px 2px 0 #ccc}.fp-iconview .fp-thumbnail:hover{background:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 0 10px 0 #ccc;-moz-box-shadow:inset 0 0 10px 0 #ccc;box-shadow:inset 0 0 10px 0 #ccc}.fp-iconview .fp-filename-field{position:absolute;height:33px;overflow:hidden;word-wrap:break-word}.fp-iconview .fp-filename-field:hover{z-index:1000;overflow:visible}.fp-iconview .fp-filename-field .fp-filename{min-width:112px;padding-top:5px;padding-bottom:12px;background:#fff}.dir-rtl .fp-iconview .fp-file{float:right}.file-picker .yui3-datatable table{width:100%;border:0 solid #bbb}#filesskin .file-picker .yui3-datatable-header{color:#555;background:#fff;border-bottom:1px solid #ccc;border-left:0 solid #fff}#filesskin .file-picker .yui3-datatable-odd .yui3-datatable-cell{background-color:#f6f6f6;border-left:0 solid #f6f6f6}#filesskin .file-picker .yui3-datatable-even .yui3-datatable-cell{background-color:#fff;border-left:0 solid #fff}.dir-rtl .file-picker .yui3-datatable-header{text-align:right}.file-picker .ygtvtn,.filemanager .ygtvtn{width:17px;height:22px;background:url('[[pix:moodle|y/tn]]') 0 0 no-repeat}.dir-rtl .filemanager .ygtvtn,.dir-rtl .file-picker .ygtvtn{width:17px;height:22px;background:url('[[pix:moodle|y/tn_rtl]]') 0 0 no-repeat}.file-picker .ygtvtm,.filemanager .ygtvtm{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tm]]') 0 10px no-repeat}.file-picker .ygtvtmh,.filemanager .ygtvtmh{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tm]]') 0 10px no-repeat}.file-picker .ygtvtp,.filemanager .ygtvtp{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvtp,.dir-rtl .filemanager .ygtvtp{background:url('[[pix:moodle|y/tp_rtl]]') 0 10px no-repeat}.file-picker .ygtvtph,.filemanager .ygtvtph{width:13px;height:22px;cursor:pointer;background:url('[[pix:moodle|y/tp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvtph,.dir-rtl .filemanager .ygtvtph{background:url('[[pix:moodle|y/tp_rtl]]') 0 10px no-repeat}.file-picker .ygtvln,.filemanager .ygtvln{width:17px;height:22px;background:url('[[pix:moodle|y/ln]]') 0 0 no-repeat}.dir-rtl .file-picker .ygtvln,.dir-rtl .filemanager .ygtvln{background:url('[[pix:moodle|y/ln_rtl]]') 0 0 no-repeat}.file-picker .ygtvlm,.filemanager .ygtvlm{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lm]]') 0 10px no-repeat}.file-picker .ygtvlmh,.filemanager .ygtvlmh{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lm]]') 0 10px no-repeat}.file-picker .ygtvlp,.filemanager .ygtvlp{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvlp,.dir-rtl .filemanager .ygtvlp{background:url('[[pix:moodle|y/lp_rtl]]') 0 10px no-repeat}.file-picker .ygtvlph,.filemanager .ygtvlph{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvlph,.dir-rtl .filemanager .ygtvlph{background:url('[[pix:moodle|y/lp_rtl]]') 0 10px no-repeat}.file-picker .ygtvloading,.filemanager .ygtvloading{width:16px;height:22px;background:transparent url('[[pix:moodle|y/loading]]') 0 0 no-repeat}.file-picker .ygtvdepthcell,.filemanager .ygtvdepthcell{width:17px;height:32px;background:url('[[pix:moodle|y/vline]]') 0 0 no-repeat}.file-picker .ygtvblankdepthcell,.filemanager .ygtvblankdepthcell{width:17px;height:22px}a.ygtvspacer:hover{color:transparent;text-decoration:none}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;cursor:pointer;background-color:transparent}.file-picker .ygtvfocus,.filemanager .ygtvfocus{background-color:#eee}.fp-filename-icon{position:relative;display:block;margin-top:10px}.fp-icon{float:left;width:24px;height:24px;margin-top:-7px;margin-right:10px;line-height:24px;text-align:center}.dir-rtl .fp-icon{float:right;margin-right:0;margin-left:10px}.fp-icon img{max-width:24px;max-height:24px;vertical-align:middle}.fp-filename{padding-right:10px}.dir-rtl .fp-filename{padding-right:0;padding-left:10px}.file-picker .fp-login-form{display:table;width:100%;height:100%}.file-picker .fp-login-form table{margin:0 auto}.file-picker .fp-login-form p{margin-top:3em;text-align:center}.file-picker .fp-login-form .fp-login-input label{display:block;text-align:right}.file-picker .fp-login-form .fp-login-input .input{text-align:left}.file-picker .fp-login-form input[type="checkbox"]{width:15px;height:15px}.file-picker .fp-upload-form{display:table;width:100%;height:100%}.file-picker .fp-upload-form table{margin:0 auto}.file-picker.fp-dlg{text-align:center}.file-picker.fp-dlg .fp-dlg-text{padding:30px 20px 10px;font-size:12px}.file-picker.fp-dlg .fp-dlg-buttons{margin:0 20px}.file-picker.fp-msg{text-align:center}.file-picker.fp-msg .fp-msg-text{max-width:500px;max-height:300px;min-width:200px;padding:40px 20px 10px 20px;overflow:auto;font-size:12px}.file-picker.fp-msg.fp-msg-error .fp-msg-text{padding:40px 20px 10px 20px;font-size:12px}.file-picker .fp-content-error{display:table;width:100%;height:100%;text-align:center}.file-picker .fp-content-error .fp-error{display:table-cell;width:100%;height:100%;padding:40px 20px 10px 20px;font-size:12px;vertical-align:middle}.file-picker .fp-nextpage{clear:both}.file-picker .fp-nextpage .fp-nextpage-loading{display:none}.file-picker .fp-nextpage.loading .fp-nextpage-link{display:none}.file-picker .fp-nextpage.loading .fp-nextpage-loading{display:block;height:100px;padding-top:50px;text-align:center}.fp-select form{padding:20px 20px 0}.fp-select .fp-select-loading{margin-top:20px;text-align:center}.fp-select .fp-hr{width:auto;height:1px;margin:10px 0;clear:both;background-color:#fff;border-bottom:1px solid #bbb}.fp-select table{padding:0 0 10px}.fp-select table .mdl-right{min-width:84px}.fp-select .fp-reflist .mdl-right{vertical-align:top}.fp-select .fp-select-buttons{float:right}.fp-select .fp-info{display:block;padding:1px 20px 0;clear:both}.fp-select .fp-thumbnail{float:left;min-width:110px;min-height:110px;margin:10px 20px 0 0;line-height:110px;text-align:center;background:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 0 10px 0 #ccc;-moz-box-shadow:inset 0 0 10px 0 #ccc;box-shadow:inset 0 0 10px 0 #ccc}.fp-select .fp-thumbnail img{padding:3px;margin:10px;vertical-align:middle;border:1px solid #ddd}.fp-select .fp-fileinfo{display:inline-block;*display:inline;margin-top:10px;*zoom:1}.file-picker.fp-select .fp-fileinfo{max-width:240px}.fp-select .fp-fileinfo div{padding-bottom:5px}.file-picker.fp-select .uneditable{display:none}.file-picker.fp-select .fp-select-loading{display:none}.file-picker.fp-select.loading .fp-select-loading{display:block}.file-picker.fp-select.loading form{display:none}.fp-select .fp-dimensions.fp-unknown{display:none}.filemanager-loading{display:none}.jsenabled .filemanager-loading{display:block;margin-top:100px}.filemanager.fm-loading .filemanager-toolbar,.filemanager.fm-loading .fp-pathbar,.filemanager.fm-loading .filemanager-container,.filemanager.fm-loaded .filemanager-loading,.filemanager.fm-maxfiles .fp-btn-add,.filemanager.fm-maxfiles .dndupload-message,.filemanager.fm-noitems .fp-btn-download,.filemanager .fm-empty-container,.filemanager.fm-noitems .filemanager-container .fp-content{display:none}.filemanager .filemanager-updating{display:none;text-align:center}.filemanager.fm-updating .filemanager-updating{display:block;margin-top:37px}.filemanager.fm-updating .fm-content-wrapper,.filemanager.fm-nomkdir .fp-btn-mkdir,.fitem.disabled .filemanager .filemanager-toolbar,.fitem.disabled .filemanager .fp-pathbar,.fitem.disabled .filemanager .fp-restrictions,.fitem.disabled .filemanager .fm-content-wrapper{display:none}.fp-restrictions{text-align:right}.filemanager .fp-navbar{background:#f2f2f2;border:1px solid #bbb;border-bottom:0}.filemanager-toolbar{min-height:22px;padding:5px 8px;overflow:hidden}.fp-pathbar{min-height:20px;padding:5px 8px 1px;border-top:1px solid #bbb}.filemanager .fp-pathbar.empty{display:none}.filepicker-filelist,.filemanager-container{position:relative;min-height:140px;overflow:auto;clear:both;background:#fff;border:1px solid #bbb}.filemanager .fp-content{max-height:472px;min-height:157px;overflow:auto}.filemanager-container,.filepicker-filelist{overflow:hidden}.fitem.disabled .filepicker-filelist,.fitem.disabled .filemanager-container{background-color:#ebebe4}.fitem.disabled .fp-btn-choose{color:#999}.fitem.disabled .filepicker-filelist .filepicker-filename{display:none}.fp-iconview .fp-reficons1{position:absolute;top:0;left:0;width:100%;height:100%}.fp-iconview .fp-reficons2{position:absolute;top:0;left:0;width:100%;height:100%}.fp-iconview .fp-file.fp-hasreferences .fp-reficons1{background:url('[[pix:theme|fp/link]]') no-repeat;background-position:bottom right}.fp-iconview .fp-file.fp-isreference .fp-reficons2{background:url('[[pix:theme|fp/alias]]') no-repeat;background-position:bottom left}.filemanager .fp-iconview .fp-file.fp-originalmissing .fp-thumbnail img{display:none}.filemanager .fp-iconview .fp-file.fp-originalmissing .fp-thumbnail{background:url([[pix:s/dead]]) no-repeat;background-position:center center}.filemanager .yui3-datatable table{width:100%;border:0 solid #bbb}.filemanager .yui3-datatable-header{color:#555!important;background:#fff!important;border-bottom:1px solid #ccc!important;border-left:0 solid #fff!important}.filemanager .yui3-datatable-odd .yui3-datatable-cell{background-color:#f6f6f6!important;border-left:0 solid #f6f6f6}.filemanager .yui3-datatable-even .yui3-datatable-cell{background-color:#fff!important;border-left:0 solid #fff}.filemanager .fp-filename-icon.fp-hasreferences .fp-reficons1{position:absolute;top:8px;left:17px;z-index:1000;width:100%;height:100%;background:url('[[pix:theme|fp/link_sm]]') no-repeat 0 0}.filemanager .fp-filename-icon.fp-isreference .fp-reficons2{position:absolute;top:9px;left:-6px;z-index:1001;width:100%;height:100%;background:url('[[pix:theme|fp/alias_sm]]') no-repeat 0 0}.filemanager .fp-contextmenu{display:none}.filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu{position:absolute;right:7px;bottom:5px;display:block}.filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,.filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu{position:absolute;top:6px;left:14px;display:inline;margin-right:-20px}.dir-rtl .filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu{right:inherit;left:7px}.dir-rtl .filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,.dir-rtl .filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu{right:16px;left:inherit;margin-right:0}.filepicker-filelist .filepicker-container,.filemanager.fm-noitems .fm-empty-container{position:absolute;top:10px;right:10px;bottom:10px;left:10px;display:block;padding-top:85px;text-align:center;border:2px dashed #bbb}.filepicker-filelist .dndupload-target,.filemanager-container .dndupload-target{position:absolute;top:10px;right:10px;bottom:10px;left:10px;padding-top:85px;text-align:center;background:#fff;border:2px dashed #fb7979;-webkit-box-shadow:0 0 0 10px #fff;-moz-box-shadow:0 0 0 10px #fff;box-shadow:0 0 0 10px #fff}.filepicker-filelist.dndupload-over .dndupload-target,.filemanager-container.dndupload-over .dndupload-target{position:absolute;top:10px;right:10px;bottom:10px;left:10px;padding-top:85px;text-align:center;background:#fff;border:2px dashed #6c8cd3}.dndupload-message{display:none}.dndsupported .dndupload-message{display:inline}.dnduploadnotsupported-message{display:none}.dndnotsupported .dnduploadnotsupported-message{display:inline}.dndupload-target{display:none}.dndsupported .dndupload-ready .dndupload-target{display:block}.dndupload-uploadinprogress{display:none;text-align:center}.dndupload-uploading .dndupload-uploadinprogress{display:block}.dndupload-arrow{position:absolute;top:5px;width:100%;height:80px;margin-left:-28px;background:url([[pix:theme|fp/dnd_arrow]]) center no-repeat}.fitem.disabled .filepicker-container,.fitem.disabled .fm-empty-container{display:none}.dndupload-progressbars{display:none;padding:10px}.dndupload-inprogress .dndupload-progressbars{display:block}.dndupload-inprogress .fp-content{display:none}.filemanager.fm-noitems .dndupload-inprogress .fm-empty-container{display:none}.filepicker-filelist.dndupload-inprogress .filepicker-container{display:none}.filepicker-filelist.dndupload-inprogress a{display:none}.filemanager.fp-select .fp-select-loading{display:none}.filemanager.fp-select.loading .fp-select-loading{display:block}.filemanager.fp-select.loading form{display:none}.filemanager.fp-select.fp-folder .fp-license,.filemanager.fp-select.fp-folder .fp-author,.filemanager.fp-select.fp-file .fp-file-unzip,.filemanager.fp-select.fp-folder .fp-file-unzip,.filemanager.fp-select.fp-file .fp-file-zip,.filemanager.fp-select.fp-zip .fp-file-zip{display:none}.filemanager.fp-select .fp-file-setmain{display:none}.filemanager.fp-select.fp-cansetmain .fp-file-setmain{display:inline-block;*display:inline;*zoom:1}.filemanager .fp-mainfile .fp-filename{font-weight:bold}.filemanager.fp-select.fp-folder .fp-file-download{display:none}.fm-operation{font-weight:bold}.filemanager.fp-select .fp-original.fp-unknown,.filemanager.fp-select .fp-original .fp-originloading{display:none}.filemanager.fp-select .fp-original.fp-loading .fp-originloading{display:inline}.filemanager.fp-select .fp-reflist.fp-unknown,.filemanager.fp-select .fp-reflist .fp-reflistloading{display:none}.filemanager.fp-select .fp-refcount{max-width:265px}.filemanager.fp-select .fp-reflist.fp-loading .fp-reflistloading{display:inline}.filemanager.fp-select .fp-reflist .fp-value{max-width:265px;max-height:75px;padding:8px 7px;margin:0;overflow:auto;background:#f9f9f9;border:1px solid #bbb}.filemanager.fp-select .fp-reflist .fp-value li{padding-bottom:7px}.filemanager.fp-mkdir-dlg{text-align:center}.filemanager.fp-mkdir-dlg .fp-mkdir-dlg-text{margin:20px;text-align:left}.dir-rtl .filemanager .fp-mkdir-dlg p{text-align:right}.filemanager.fp-dlg{text-align:center}.filemanager.fp-dlg .fp-dlg-text{max-width:340px;max-height:300px;min-width:200px;padding:0 10px;margin:40px 20px 20px;overflow:auto;font-size:12px;line-height:22px}.file-picker div.bd{text-align:left}.dir-rtl .file-picker div.bd,.dir-rtl .file-picker .fp-pathbar,.dir-rtl .file-picker .fp-list,.dir-rtl #filemenu .yuimenuitemlabel,.dir-rtl .filemanager-container .yui3-skin-sam .yui3-datatable-header{text-align:right}.dir-rtl .filepicker .yui-layout-unit-left{left:500px}.dir-rtl .filepicker .yui-layout-unit-center{left:0}.message-discussion-noframes h1{font-size:1em}.message-discussion-noframes #userinfo .commands,.message .noframesjslink,.message .link{font-size:11.9px}.message .heading{font-size:1em;font-weight:bold}.message .author{font-weight:bold}.message .time{font-style:italic}#page-message-user .commands span{font-size:.7em}#page-message-user .name{font-size:1.1em;font-weight:bold}table.message_search_results td{border-color:#ddd}.message .time,.message.me .author{color:#999}.message.other .author{color:#88c}#page-message-messages{padding:10px}#page-message-send .notifysuccess{padding:1px}#page-message-send td.fixeditor{text-align:center}.message .note{padding:10px}table.message .searchresults td{padding:5px}.message .contactselector{float:left;width:24%}.message .contactselector .contact{text-align:left}.message .contactselector .messageselecteduser{font-weight:bold}.message .contactselector .paging{position:relative;z-index:1}.message .messagearea{float:right;width:74%;min-height:200px;padding-left:1%;border-left:1px solid #d3d3d3}.message .messagearea .messagehistorytype{padding-bottom:20px;clear:both}.message .messagearea .messagehistory .message_user_pictures{margin-right:auto;margin-left:auto}.message .messagearea .messagehistory .message_user_pictures #user1{width:200px;vertical-align:top}.message .messagearea .messagehistory .message_user_pictures #user2{width:200px;vertical-align:top}.message .messagearea .messagehistory .message_user_pictures .useractionlinks{font-size:.9em}.message .messagearea .messagehistory .heading{width:100%;clear:both}.message .messagearea .messagehistory .left{float:left;width:50%;padding-bottom:10px;clear:both}.message .messagearea .messagehistory .right{float:right;width:50%;padding-bottom:10px;clear:both}.message .messagearea .messagehistory .notification{padding:10px;margin-top:5px;background-color:#eee}.message .messagearea .messagesend{padding-top:20px;clear:both}.message .messagearea .messagesend .messagesendbox{width:100%}.message .messagearea .messagesend fieldset{padding:0;margin:0}.message .messagearea .messagerecent{width:100%;text-align:left}.message .messagearea .messagerecent .singlemessage{padding:10px;border-bottom:1px solid #d3d3d3}.message .messagearea .messagerecent .singlemessage .otheruser span{padding:5px}.message .messagearea .messagerecent .singlemessage .messagedate{float:right}.message .hiddenelement{display:none}.message .visible{display:inline}.message #usergroupselector.fieldset,.message #viewing{width:100%}.messagesearchresults{margin-bottom:40px}.messagesearchresults td{padding:0 10px 0 20px}.messagesearchresults td span{white-space:nowrap}.messagesearchresults td img.userpicture{padding-right:.45em;vertical-align:text-bottom}.dir-rtl .messagesearchresults td img.userpicture{padding-right:0;padding-left:.45em}.messagesearchresults td span img{padding:0 0 0 .45em;vertical-align:text-bottom}.dir-rtl .messagesearchresults td span img{padding:0 .45em 0 0}#newmessageoverlay{position:fixed;right:0;bottom:0;padding:20px;background-color:#d3d3d3;border:1px solid black}#newmessageoverlay #usermessage{padding:10px}.questionbank h2{margin-top:0}.questioncategories h3{margin-top:0}#chooseqtypebox{margin-top:1em}#chooseqtype h3{margin:0 0 .3em}#chooseqtype .instruction{display:none}#chooseqtype .fakeqtypes{border-top:1px solid silver}#chooseqtype .qtypeoption{margin-bottom:.5em}#chooseqtype label{display:block}#chooseqtype .qtypename img{padding:0 .3em}#chooseqtype .qtypename{display:inline-table;width:16em}#chooseqtype .qtypesummary{display:block;margin:0 2em}#chooseqtype .submitbuttons{margin:.7em 0;text-align:center}#qtypechoicecontainer{display:none}#qtypechoicecontainer_c.yui-panel-container.shadow .underlay{background:0}#qtypechoicecontainer.yui-panel .hd{letter-spacing:1px;color:#333;text-shadow:1px 1px 1px #fff;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border:1px solid #ccc;border-bottom:1px solid #bbb;-webkit-border-top-right-radius:10px;border-top-right-radius:10px;-webkit-border-top-left-radius:10px;border-top-left-radius:10px;-moz-border-radius-topright:10px;-moz-border-radius-topleft:10px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}#qtypechoicecontainer{font-size:12px;color:#333;background:#f2f2f2;border:1px solid #ccc;border-top:0 none;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}#chooseqtype{width:40em}#chooseqtypehead h3{margin:0;font-weight:normal}#chooseqtype .qtypes{position:relative;padding:.24em 0;border-bottom:1px solid #bbb}#chooseqtype .qtypeoption{padding:.3em .3em .3em 1.6em;margin-bottom:0}#chooseqtype .qtypeoption img{padding-right:.5em;padding-left:1em;vertical-align:text-bottom}#chooseqtype .selected{background-color:#fff;-webkit-box-shadow:0 0 10px 0 #ccc;-moz-box-shadow:0 0 10px 0 #ccc;box-shadow:0 0 10px 0 #ccc}#chooseqtype .instruction,#chooseqtype .qtypesummary{position:absolute;top:0;right:0;bottom:0;left:60%;display:none;padding:1.5em 1.6em;margin:0;overflow-y:auto;background-color:#fff}#chooseqtype .instruction,#chooseqtype .selected .qtypesummary{display:block}#categoryquestions{margin:0}#categoryquestions td,#categoryquestions th{padding:0 .2em}#categoryquestions th{font-weight:normal;text-align:left}#categoryquestions .checkbox{padding-left:20px}.dir-rtl #categoryquestions th{text-align:right}.questionbank .singleselect{margin:0}#combinedfeedbackhdr div.fhtmleditor{padding:0}#combinedfeedbackhdr div.fcheckbox{margin-bottom:1em}#multitriesheader div.fitem_feditor{margin-top:1em}#multitriesheader div.fitem_fgroup{margin-bottom:1em}#multitriesheader div.fitem_fgroup fieldset.felement label{margin-right:.3em;margin-left:.3em}body.path-question-type .fitem_fgroup .accesshide{position:static;left:0;padding-right:.3em;font:inherit}.que{margin:0 auto 1.8em auto;clear:left;text-align:left}.dir-rtl .que{text-align:right}.que .info{float:left;width:7em;padding:.5em;margin-bottom:1.8em;background-color:#eee;border:1px solid #dcdcdc;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.que h2.no{margin:0;font-size:.8em;line-height:1}.que span.qno{font-size:1.5em;font-weight:bold}.que .info>div{margin-top:.7em;font-size:.8em}.que .info .questionflag.editable{cursor:pointer}.que .info .editquestion img,.que .info .questionflag img,.que .info .questionflag input{vertical-align:bottom}.que .content{margin:0 0 0 8.5em}.que .formulation,.que .outcome,.que .comment{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.que .formulation{color:#3a87ad;color:#333;background-color:#d9edf7;border-color:#bce8f1}.formulation input[type="text"],.formulation select{width:auto}.path-mod-quiz input[size]{width:auto}.que .comment{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.que .history{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.que .history blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.que .ablock{margin:.7em 0 .3em 0}.que .im-controls{margin-top:.5em;text-align:left}.dir-rtl .que .im-controls{text-align:right}.que .specificfeedback,.que .generalfeedback,.que .rightanswer,.que .im-feedback,.que .feedback,.que p{margin:0 0 .5em}.que .qtext{margin-bottom:1.5em}.que .correctness{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.que .correctness:empty{display:none}.que .correctness-important{background-color:#b94a48}.que .correctness-important[href]{background-color:#953b39}.que .correctness-warning{background-color:#f89406}.que .correctness-warning[href]{background-color:#c67605}.que .correctness-success{background-color:#468847}.que .correctness-success[href]{background-color:#356635}.que .correctness-info{background-color:#3a87ad}.que .correctness-info[href]{background-color:#2d6987}.que .correctness-inverse{background-color:#333}.que .correctness-inverse[href]{background-color:#1a1a1a}.que .correctness.correct{background-color:#468847}.que .correctness.partiallycorrect{background-color:#f89406}.que .correctness.notanswered,.que .correctness.incorrect{background-color:#b94a48}.que .validationerror{color:#b94a48}.formulation .correct{background-color:#dff0d8}.formulation .partiallycorrect{background-color:#fcf8e3}.formulation .incorrect{background-color:#f2dede}.formulation select.correct,.formulation input.correct{color:#468847;background-color:#dff0d8;border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.correct:focus,.formulation input.correct:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.formulation select.partiallycorrect,.formulation input.partiallycorrect{color:#c09853;background-color:#fcf8e3;border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.partiallycorrect:focus,.formulation input.partiallycorrect:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.formulation select.incorrect,.formulation input.incorrect{color:#b94a48;background-color:#f2dede;border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.incorrect:focus,.formulation input.incorrect:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.que .grading,.que .comment,.que .commentlink,.que .history{margin-top:.5em}.que .history h3{margin:0 0 .2em;font-size:1em}.que .history table{width:100%;margin:0}.que .history .current{font-weight:bold}.que .questioncorrectnessicon{vertical-align:text-bottom}.que input.questionflagimage{padding-right:3px}.dir-rtl .que input.questionflagimage{padding-right:0;padding-left:3px}.importerror{margin-top:10px;border-bottom:1px solid #555}.mform .que.comment .fitemtitle{width:20%}#page-question-preview #techinfo{margin:1em 0}.dir-rtl #chooseqtype .instruction,.dir-rtl #chooseqtype .qtypesummary{right:60%;left:0;border-right:1px solid grey;border-left:0}#page-mod-quiz-edit .questionbankwindow div.header{padding:3px;padding:2px 10px 2px 10px;margin:0 -10px 0 -10px;color:#444;text-shadow:none;background:transparent;-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}#page-mod-quiz-edit .questionbankwindow div.header a:link,#page-mod-quiz-edit .questionbankwindow div.header a:visited{color:#08c}#page-mod-quiz-edit .questionbankwindow div.header a:hover{color:#005580}#page-mod-quiz-edit .questionbankwindow div.header .title{color:#333}#page-mod-quiz-edit div.container div.generalbox{padding:1.5em;background-color:transparent}#page-mod-quiz-edit .categoryinfo{background-color:#fff;border-bottom:0}#page-mod-quiz-edit div.questionbank .categoryquestionscontainer,#page-mod-quiz-edit div.questionbank .categorysortopotionscontainer,#page-mod-quiz-edit div.questionbank .categorypagingbarcontainer,#page-mod-quiz-edit div.questionbank .categoryselectallcontainer{padding:0 0 1.5em 0}#page-mod-quiz-edit div.questionbank .categorypagingbarcontainer{padding:1em;margin:0 -1.2em;background-color:transparent;border-top:0;border-bottom:0}#page-mod-quiz-edit div.questionbank .categoryquestionscontainer{margin:0 -1.2em -1em -1.2em}#page-mod-quiz-edit div.question div.content div.questioncontrols{background-color:#fff}#page-mod-quiz-edit div.question div.content div.points{padding-bottom:.5em;margin-top:-0.5em;background-color:#fff;border:0}#page-mod-quiz-edit div.question div.content div.points label{display:inline-block}#page-mod-quiz-edit div.quizpage .pagecontent .pagestatus{background-color:#fff}#page-mod-quiz-edit .quizpagedelete,#page-mod-quiz-edit .quizpagedelete img{background-color:transparent}#page-mod-quiz-edit div.quizpage .pagecontent{overflow:hidden;border:1px solid #ddd;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}#page-mod-quiz-edit .modulespecificbuttonscontainer{width:220px}.questionbankwindow .module{width:auto}#page-mod-quiz-edit div.editq div.question div.content{overflow:hidden;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.path-mod-quiz .statedetails{display:block;font-size:.9em}a#hidebankcmd{color:#08c}.que.shortanswer .answer{padding:0}.que label{display:inline}.userprofile .fullprofilelink{margin:10px;text-align:center}.userprofile .description{margin-bottom:20px}.userprofile dl.list{*zoom:1}.userprofile dl.list:before,.userprofile dl.list:after{display:table;line-height:0;content:""}.userprofile dl.list:after{clear:both}.userprofile dl.list dt{float:left;width:180px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.userprofile dl.list dd{margin-left:200px}.user-box{float:left;width:115px;height:160px;margin:8px;clear:none;text-align:center}.userlist .action-icon img{vertical-align:middle}.userlist #showall{margin:10px 0}.userlist .buttons{text-align:center}.userlist .buttons label{padding:0 3px}.userlist table#participants{text-align:center}.userlist table#participants td,.userlist table#participants th{padding:4px;text-align:left;vertical-align:middle}.userlist table.controls{width:100%}.userlist table.controls tr{vertical-align:top}.userlist table.controls td.right,.userlist table.controls td.left{padding:4px}.userlist table.controls .right{text-align:right}.userinfobox{width:100%;padding:10px;border:1px solid;border-collapse:separate}.userinfobox .left,.userinfobox .side{width:100px;vertical-align:top}.userinfobox .userpicture{width:100px;height:100px}.userinfobox .content{vertical-align:top}.userinfobox .links{width:100px;padding:5px;vertical-align:bottom}.userinfobox .links a{display:block}.userinfobox .list td{padding:3px}.userinfobox .username{padding-bottom:20px;font-weight:bold}.userinfobox td.label{font-weight:bold;text-align:right;white-space:nowrap;vertical-align:top}.groupinfobox{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.groupinfobox blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.groupinfobox .left{width:100px;padding:10px;vertical-align:top}.course-participation #showall{margin:10px 0;text-align:center}#user-policy .noticebox{width:80%;height:250px;margin-right:auto;margin-bottom:10px;margin-left:auto;text-align:center}#user-policy #policyframe{width:100%;height:100%}.iplookup #map{margin:auto}.userselector select{width:100%}.userselector div{margin-top:.2em}.userselector div label{margin-right:.3em}.userselector .userselector-infobelow{font-size:.8em}#userselector_options{padding:.3em 0}#userselector_options .collapsibleregioncaption{font-weight:bold}#userselector_options p{margin:.2em 0;text-align:left}.dir-rtl #userselector_options p{text-align:right}#page-user-profile .messagebox{margin-right:auto;margin-left:auto;text-align:center}#page-course-view-weeks .messagebox{margin-right:auto;margin-left:auto;text-align:center}.dir-rtl .descriptionbox{margin-right:110px;margin-left:0}.dir-rtl .userlist table#participants td,.dir-rtl .userlist table#participants th{text-align:right}.dir-rtl .userlist table#participants{margin:0 auto}#page-my-index.dir-rtl .block h3{text-align:right}/*!
+.layout-option-noheader #page-header,.layout-option-nonavbar #page-navbar,.layout-option-nofooter #page-footer,.layout-option-nocourseheader .course-content-header,.layout-option-nocoursefooter .course-content-footer{display:none}.empty-region-side-pre #block-region-side-pre,.empty-region-side-post #block-region-side-post{display:none}.empty-region-side-post #region-bs-main-and-pre.span9{width:100%}.empty-region-side-pre #region-main{float:none;width:100%}.empty-region-side-post.used-region-side-pre #region-main.span8{width:74.46808510638297%;*width:74.41489361702126%}.empty-region-side-post.used-region-side-pre #block-region-side-pre.span4{width:23.404255319148934%;*width:23.351063829787233%}.empty-region-side-post #region-bs-main-and-post.span9 #region-main.span8{width:100%}.dir-ltr,.mdl-left,.dir-rtl .mdl-right{text-align:left}.dir-rtl,.mdl-right,.dir-rtl .mdl-left{text-align:right}#add,#remove,.centerpara,.mdl-align{text-align:center}a.dimmed,a.dimmed:link,a.dimmed:visited,a.dimmed_text,a.dimmed_text:link,a.dimmed_text:visited,.dimmed_text,.dimmed_text a,.dimmed_text a:link,.dimmed_text a:visited,.usersuspended,.usersuspended a,.usersuspended a:link,.usersuspended a:visited,.dimmed_category,.dimmed_category a{color:#999}.activity.label .dimmed_text{opacity:.5;filter:alpha(opacity=50)}.unlist,.unlist li,.inline-list,.inline-list li,.block .list,.block .list li,.section li.activity,.section li.movehere,.tabtree li{padding:0;margin:0;list-style:none}.inline,.inline-list li{display:inline}.notifytiny{font-size:10.5px}.notifytiny li,.notifytiny td{font-size:100%}.red,.notifyproblem{color:#b94a48}.green,.notifysuccess{color:#468847}.reportlink{text-align:right}a.autolink.glossary:hover{cursor:help}.collapsibleregioncaption{white-space:nowrap}.collapsibleregioncaption img{vertical-align:middle}.jsenabled .hiddenifjs{display:none}.visibleifjs{display:none}.jsenabled .visibleifjs{display:inline}.jsenabled .collapsibleregion{overflow:hidden}.jsenabled .collapsed .collapsibleregioninner{visibility:hidden}.collapsible-actions{display:none;text-align:right}.dir-rtl .collapsible-actions{text-align:left}.jsenabled .collapsible-actions{display:block}.collapsible-actions .collapseexpand{padding-left:20px;background:url([[pix:t/collapsed]]) 2px center no-repeat}.dir-rtl .collapsible-actions .collapseexpand{padding-right:20px;padding-left:0;background:url([[pix:t/collapsed_rtl]]) right center no-repeat}.collapsible-actions .collapse-all,.dir-rtl .collapsible-actions .collapse-all{background-image:url([[pix:t/expanded]])}.yui-overlay .yui-widget-bd{position:relative;top:0;left:0;z-index:1;padding:2px 5px;color:#000;background-color:#ffee69;border:1px solid #a6982b;border-top-color:#d4c237}.clearer{display:block;height:1px;padding:0;margin:0;clear:both;background:transparent;border-width:0}.bold,.warning,.errorbox .title,.pagingbar .title,.pagingbar .thispage,.headingblock{font-weight:bold}img.resize{width:1em;height:1em}.block img.resize,.breadcrumb img.resize{width:.8em;height:.9em}img.icon{width:16px;height:16px;padding-right:6px;vertical-align:text-bottom}.dir-rtl img.icon{padding-right:0;padding-left:6px}img.iconsmall{width:12px;height:12px;margin-right:3px;vertical-align:middle}img.iconhelp,.helplink img{width:16px;height:16px;padding-left:3px;vertical-align:text-bottom}h1 img.iconhelp,h1 img.icon,h2 img.iconhelp,h2 img.icon,h3 img.iconhelp,h3 img.icon,h4 img.iconhelp,h4 img.icon,h5 img.iconhelp,h5 img.icon,h6 img.iconhelp,h6 img.icon{vertical-align:middle}.dir-rtl img.iconhelp,.dir-rtl .helplink img{padding-right:3px;padding-left:0}img.iconlarge{width:24px;height:24px;vertical-align:middle}img.iconsort{padding-left:.3em;margin-bottom:.15em;vertical-align:text-bottom}.dir-rtl img.iconsort{padding-right:.3em;padding-left:0}img.icontoggle{width:50px;height:17px;vertical-align:middle}img.iconkbhelp{width:49px;height:17px}img.icon-pre,.dir-rtl img.icon-post{padding-right:3px;padding-left:0}img.icon-post,.dir-rtl img.icon-pre{padding-right:0;padding-left:3px}.boxaligncenter{margin-right:auto;margin-left:auto}.boxalignright{margin-right:0;margin-left:auto}.boxalignleft{margin-right:auto;margin-left:0}.boxwidthnarrow{width:30%}.boxwidthnormal{width:50%}.boxwidthwide{width:80%}.headermain{font-weight:bold}#maincontent{display:block;height:1px;overflow:hidden}img.uihint{cursor:help}#addmembersform table{margin-right:auto;margin-left:auto}.flexible th{white-space:nowrap}table.flexible .emptyrow{display:none}img.emoticon{width:15px;height:15px;vertical-align:middle}form.popupform,form.popupform div{display:inline}.arrow_button input{overflow:hidden}.action-icon img.smallicon{margin:0 .3em;vertical-align:text-bottom}.no-overflow{padding-bottom:1px;overflow:auto}.pagelayout-report .no-overflow{overflow:visible}.no-overflow>.generaltable{margin-bottom:0}.accesshide{position:absolute;left:-10000px;font-size:1em;font-weight:normal}.dir-rtl .accesshide{top:-30000px;left:auto}span.hide,div.hide{display:none}a.skip-block,a.skip{position:absolute;top:-1000em;font-size:.85em;text-decoration:none}a.skip-block:focus,a.skip-block:active,a.skip:focus,a.skip:active{position:static;display:block}.skip-block-to{display:block;height:1px;overflow:hidden}.addbloglink{text-align:center}.blog_entry .audience{padding-right:4px;text-align:right}.blog_entry .tags{margin-top:15px}.blog_entry .tags .action-icon img.smallicon{width:16px;height:16px}.blog_entry .content{margin-left:43px}#page-group-index #groupeditform{text-align:center}#doc-contents h1{margin:1em 0 0 0}#doc-contents ul{width:90%;padding:0;margin:0}#doc-contents ul li{list-style-type:none}.groupmanagementtable td{vertical-align:top}.groupmanagementtable #existingcell,.groupmanagementtable #potentialcell{width:42%}.groupmanagementtable #buttonscell{width:16%}.groupmanagementtable #buttonscell p.arrow_button input{width:auto;min-width:80%;margin:0 auto}.groupmanagementtable #removeselect_wrapper,.groupmanagementtable #addselect_wrapper{width:100%}.groupmanagementtable #removeselect_wrapper label,.groupmanagementtable #addselect_wrapper label{font-weight:normal}.dir-rtl .groupmanagementtable p{text-align:right}#group-usersummary{width:14em}.groupselector{margin-top:3px;margin-bottom:3px}.loginbox{margin:15px;overflow:visible}.loginbox.twocolumns{margin:15px}.loginbox h2,.loginbox .subcontent{padding:10px;margin:5px;text-align:center}.loginbox .loginpanel .desc{padding:0;margin:0;margin-top:15px;margin-bottom:5px}.loginbox .signuppanel .subcontent{text-align:left}.dir-rtl .loginbox .signuppanel .subcontent{text-align:right}.loginbox .loginsub{margin-right:0;margin-left:0}.loginbox .guestsub,.loginbox .forgotsub,.loginbox .potentialidps{margin:5px 12%}.loginbox .potentialidps .potentialidplist{margin-left:40%}.loginbox .potentialidps .potentialidplist div{text-align:left}.loginbox .loginform{margin-top:1em;text-align:left}.loginbox .loginform .form-label{float:left;width:44%;text-align:right;white-space:nowrap;direction:rtl}.dir-rtl .loginbox .loginform .form-label{float:left;width:44%;text-align:right;white-space:nowrap;direction:ltr}.loginbox .loginform .form-input{float:right;width:55%}.loginbox .loginform .form-input input{width:6em}.loginbox .signupform{margin-top:1em;text-align:center}.loginbox.twocolumns .loginpanel,.loginbox.twocolumns .signuppanel{display:block;float:left;width:48%;min-height:30px;padding:0;padding-bottom:2000px;margin:0;margin-bottom:-2000px;margin-left:2.76243%;border:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.loginbox .potentialidp .smallicon{margin:0 .3em;vertical-align:text-bottom}.notepost{margin-bottom:1em}.notepost .userpicture{float:left;margin-right:5px}.notepost .content,.notepost .footer{clear:both}.notesgroup{margin-left:20px}.path-my .coursebox .overview{margin:15px 30px 10px 30px}.path-my .coursebox .info{float:none;margin:0}.mod_introbox{padding:10px}table.mod_index{width:100%}.comment-ctrl{display:none;padding:0;margin:0;font-size:12px}.comment-ctrl h5{padding:5px;margin:0}.comment-area{max-width:400px;padding:5px}.comment-area textarea{width:100%;overflow:auto}.comment-area .fd{text-align:right}.comment-meta span{color:gray}.comment-link img{vertical-align:text-bottom}.comment-list{padding:0;margin:0;overflow:auto;font-size:11px;list-style:none}.comment-list li{position:relative;padding:.3em;margin:2px;margin-bottom:5px;clear:both;list-style:none}.comment-list li.first{display:none}.comment-paging{text-align:center}.comment-paging .pageno{padding:2px}.comment-paging .curpage{border:1px solid #CCC}.comment-message .picture{float:left;width:20px}.dir-rtl .comment-message .picture{float:right}.comment-message .text{padding:0;margin:0}.comment-message .text p{padding:0;margin:0 18px 0 0}.comment-delete{position:absolute;top:0;right:0;margin:.3em}.dir-rtl .comment-delete{position:absolute;right:auto;left:0;margin:.3em}.comment-delete-confirm{width:5em;padding:2px;text-align:center;background:#eee}.comment-container{float:left;margin:4px}.comment-report-selectall{display:none}.comment-link{display:none}.jsenabled .comment-link{display:block}.jsenabled .showcommentsnonjs{display:none}.jsenabled .comment-report-selectall{display:inline}.completion-expired{background:#f2dede}.completion-expected{font-size:10.5px}.completion-sortchoice,.completion-identifyfield{font-size:10.5px;vertical-align:bottom}.completion-progresscell{text-align:right}.completion-expired .completion-expected{font-weight:bold}#page-tag-coursetags_edit .coursetag_edit_centered{position:relative;width:600px;margin:20px auto}#page-tag-coursetags_edit .coursetag_edit_row{clear:both}#page-tag-coursetags_edit .coursetag_edit_row .coursetag_edit_left{float:left;width:50%;text-align:right}#page-tag-coursetags_edit .coursetag_edit_row .coursetag_edit_right{margin-left:50%}#page-tag-coursetags_edit .coursetag_edit_input3{display:none}#page-tag-coursetags_more .coursetag_more_large{font-size:120%}#page-tag-coursetags_more .coursetag_more_small{font-size:80%}#page-tag-coursetags_more .coursetag_more_link{font-size:80%}#tag-description,#tag-blogs{width:100%}#tag-management-box{margin-bottom:10px;line-height:20px}#tag-user-table{width:100%;padding:3px;clear:both}#tag-user-table{*zoom:1}#tag-user-table:before,#tag-user-table:after{display:table;line-height:0;content:""}#tag-user-table:after{clear:both}img.user-image{width:100px;height:100px}#small-tag-cloud-box{width:300px;margin:0 auto}#big-tag-cloud-box{float:none;width:600px;margin:0 auto}ul#tag-cloud-list{padding:5px;margin:0;list-style:none}ul#tag-cloud-list li{display:inline;margin:0;list-style-type:none}#tag-search-box{margin:10px auto;text-align:center}#tag-search-results-container{width:100%;padding:0}#tag-search-results{display:block;float:left;width:60%;padding:0;margin:15px 20% 0 20%}#tag-search-results li{float:left;width:30%;padding-right:1%;padding-left:1%;line-height:20px;text-align:left;list-style:none}span.flagged-tag,span.flagged-tag a{color:#b94a48}table#tag-management-list{width:100%;text-align:left}table#tag-management-list td,table#tag-management-list th{padding:4px;text-align:left;vertical-align:middle}.tag-management-form{text-align:center}#relatedtags-autocomplete-container{width:100%;min-height:4.6em;margin-right:auto;margin-left:auto}#relatedtags-autocomplete{position:relative;display:block;width:60%;margin-right:auto;margin-left:auto}#relatedtags-autocomplete .yui-ac-content{position:absolute;left:20%;z-index:9050;width:420px;overflow:hidden;background:#fff;border:1px solid #404040}#relatedtags-autocomplete .ysearchquery{position:absolute;right:10px;z-index:10;color:#808080}#relatedtags-autocomplete .yui-ac-shadow{position:absolute;z-index:9049;width:100%;margin:.3em;background:#a0a0a0}#relatedtags-autocomplete ul{width:100%;padding:0;margin:0;list-style-type:none}#relatedtags-autocomplete li{padding:0 5px;white-space:nowrap;cursor:default}#relatedtags-autocomplete li.yui-ac-highlight{background:#ffc}h2.tag-heading,div#tag-description,div#tag-blogs,body.tag .managelink{padding:5px}.tag_cloud .s20{font-size:1.5em;font-weight:bold}.tag_cloud .s19{font-size:1.5em}.tag_cloud .s18{font-size:1.4em;font-weight:bold}.tag_cloud .s17{font-size:1.4em}.tag_cloud .s16{font-size:1.3em;font-weight:bold}.tag_cloud .s15{font-size:1.3em}.tag_cloud .s14{font-size:1.2em;font-weight:bold}.tag_cloud .s13{font-size:1.2em}.tag_cloud .s12,.tag_cloud .s11{font-size:1.1em;font-weight:bold}.tag_cloud .s10,.tag_cloud .s9{font-size:1.1em}.tag_cloud .s8,.tag_cloud .s7{font-size:1em;font-weight:bold}.tag_cloud .s6,.tag_cloud .s5{font-size:1em}.tag_cloud .s4,.tag_cloud .s3{font-size:.9em;font-weight:bold}.tag_cloud .s2,.tag_cloud .s1{font-size:.9em}.tag_cloud .s0{font-size:.8em}#webservice-doc-generator td{text-align:left;border:0 solid black}.smartselect{position:absolute}.smartselect .smartselect_mask{background-color:#fff}.smartselect ul{padding:0;margin:0}.smartselect ul li{list-style:none}.smartselect .smartselect_menu{margin-right:5px}.safari .smartselect .smartselect_menu{margin-left:2px}.smartselect .smartselect_menu,.smartselect .smartselect_submenu{display:none;background-color:#FFF;border:1px solid #000}.smartselect .smartselect_menu.visible,.smartselect .smartselect_submenu.visible{display:block}.smartselect .smartselect_menu_content ul li{position:relative;padding:2px 5px}.smartselect .smartselect_menu_content ul li a{color:#333;text-decoration:none}.smartselect .smartselect_menu_content ul li a.selectable{color:inherit}.smartselect .smartselect_submenuitem{background-image:url([[pix:moodle|t/collapsed]]);background-position:100%;background-repeat:no-repeat}.smartselect.spanningmenu .smartselect_submenu{position:absolute;top:-1px;left:100%}.smartselect.spanningmenu .smartselect_submenu a{padding-right:16px;white-space:nowrap}.smartselect.spanningmenu .smartselect_menu_content ul li a.selectable:hover{text-decoration:underline}.smartselect.compactmenu .smartselect_submenu{position:relative;z-index:1010;display:none;margin:2px -3px;margin-left:10px;border-width:0}.smartselect.compactmenu .smartselect_submenu.visible{display:block}.smartselect.compactmenu .smartselect_menu{z-index:1000;overflow:hidden}.smartselect.compactmenu .smartselect_submenu .smartselect_submenu{z-index:1020}.smartselect.compactmenu .smartselect_submenuitem:hover>.smartselect_menuitem_label{font-weight:bold}#page-admin-registration-register .registration_textfield{width:300px}.userenrolment{width:100%;border-collapse:collapse}.userenrolment td{height:41px;padding:0}.userenrolment .subfield{margin-right:5px}.userenrolment .col_userdetails .subfield_picture{float:left}.userenrolment .col_lastseen{width:150px}.userenrolment .col_role{width:262px}.userenrolment .col_role .roles{margin-right:30px}.userenrolment .col_role .role{float:left;padding:3px;margin:3px}.dir-rtl .userenrolment .col_role .role{float:right}.userenrolment .col_role .role a{margin-left:3px;cursor:pointer}.userenrolment .col_role .addrole{float:right;width:18px;height:18px;margin:3px;text-align:center;background-color:#dff0d8;border:1px solid #d6e9c6}.userenrolment .col_role .addrole img{vertical-align:baseline}.userenrolment .hasAllRoles .col_role .addrole{display:none}.userenrolment .col_group .groups{margin-right:30px}.userenrolment .col_group .group{float:left;padding:3px;margin:3px;white-space:nowrap}.userenrolment .col_group .group a{margin-left:3px;cursor:pointer}.userenrolment .col_group .addgroup{float:right;width:18px;height:18px;margin:3px;text-align:center}.userenrolment .col_group .addgroup a img{vertical-align:bottom}.userenrolment .col_enrol .enrolment{float:left;padding:3px;margin:3px}.userenrolment .col_enrol .enrolment a{float:right;margin-left:3px}#page-enrol-users .enrol_user_buttons{float:right}#page-enrol-users.dir-rtl .enrol_user_buttons{float:left}#page-enrol-users .enrol_user_buttons .enrolusersbutton{display:inline;margin-left:1em}#page-enrol-users .enrol_user_buttons .enrolusersbutton div,#page-enrol-users .enrol_user_buttons .enrolusersbutton form{display:inline}#page-enrol-users .enrol_user_buttons .enrolusersbutton input{padding-right:6px;padding-left:6px}#page-enrol-users.dir-rtl .col_userdetails .subfield_picture{float:right}#page-enrol-users .user-enroller-panel .uep-search-results .user .details{width:237px}.dir-rtl .headermain{float:right}.dir-rtl .headermenu{float:left}.dir-rtl .loginbox .loginform .form-label{float:right;text-align:left}.dir-rtl .loginbox .loginform .form-input{text-align:right}.dir-rtl .yui3-menu-hidden{left:0}#page-admin-roles-define.dir-rtl #rolesform .felement{margin-right:180px}#page-message-edit.dir-rtl table.generaltable th.c0{text-align:right}.corelightbox{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;background-color:#CCC}.corelightbox img{position:fixed;top:50%;left:50%}.mod-indent-1{margin-left:30px}.mod-indent-2{margin-left:60px}.mod-indent-3{margin-left:90px}.mod-indent-4{margin-left:120px}.mod-indent-5{margin-left:150px}.mod-indent-6{margin-left:180px}.mod-indent-7{margin-left:210px}.mod-indent-8{margin-left:240px}.mod-indent-9{margin-left:270px}.mod-indent-10{margin-left:300px}.mod-indent-11{margin-left:330px}.mod-indent-12{margin-left:360px}.mod-indent-13{margin-left:390px}.mod-indent-14{margin-left:420px}.mod-indent-15,.mod-indent-huge{margin-left:420px}.dir-rtl .mod-indent-1{margin-right:30px;margin-left:0}.dir-rtl .mod-indent-2{margin-right:60px;margin-left:0}.dir-rtl .mod-indent-3{margin-right:90px;margin-left:0}.dir-rtl .mod-indent-4{margin-right:120px;margin-left:0}.dir-rtl .mod-indent-5{margin-right:150px;margin-left:0}.dir-rtl .mod-indent-6{margin-right:180px;margin-left:0}.dir-rtl .mod-indent-7{margin-right:210px;margin-left:0}.dir-rtl .mod-indent-8{margin-right:240px;margin-left:0}.dir-rtl .mod-indent-9{margin-right:270px;margin-left:0}.dir-rtl .mod-indent-10{margin-right:300px;margin-left:0}.dir-rtl .mod-indent-11{margin-right:330px;margin-left:0}.dir-rtl .mod-indent-12{margin-right:360px;margin-left:0}.dir-rtl .mod-indent-13{margin-right:390px;margin-left:0}.dir-rtl .mod-indent-14{margin-right:420px;margin-left:0}.dir-rtl .mod-indent-15,.dir-rtl .mod-indent-huge{margin-right:420px;margin-left:0}.resourcecontent .mediaplugin_mp3 object{width:600px;height:25px}.resourcecontent audio.mediaplugin_html5audio{width:600px}.resourceimage{max-width:100%}.mediaplugin_mp3 object{width:300px;height:15px}audio.mediaplugin_html5audio{width:300px}.core_media_preview.pagelayout-embedded #content{padding:0}.core_media_preview.pagelayout-embedded #maincontent{height:0}.core_media_preview.pagelayout-embedded .mediaplugin{margin:0}.dir-rtl .ygtvtn,.dir-rtl .ygtvtm,.dir-rtl .ygtvtmh,.dir-rtl .ygtvtmhh,.dir-rtl .ygtvtp,.dir-rtl .ygtvtph,.dir-rtl .ygtvtphh,.dir-rtl .ygtvln,.dir-rtl .ygtvlm,.dir-rtl .ygtvlmh,.dir-rtl .ygtvlmhh,.dir-rtl .ygtvlp,.dir-rtl .ygtvlph,.dir-rtl .ygtvlphh,.dir-rtl .ygtvdepthcell,.dir-rtl .ygtvok,.dir-rtl .ygtvok:hover,.dir-rtl .ygtvcancel,.dir-rtl .ygtvcancel:hover{width:18px;height:22px;cursor:pointer;background-image:url([[pix:theme|yui2-treeview-sprite-rtl]]);background-repeat:no-repeat}.dir-rtl .ygtvtn{background-position:0 -5600px}.dir-rtl .ygtvtm{background-position:0 -4000px}.dir-rtl .ygtvtmh,.dir-rtl .ygtvtmhh{background-position:0 -4800px}.dir-rtl .ygtvtp{background-position:0 -6400px}.dir-rtl .ygtvtph,.dir-rtl .ygtvtphh{background-position:0 -7200px}.dir-rtl .ygtvln{background-position:0 -1600px}.dir-rtl .ygtvlm{background-position:0 0}.dir-rtl .ygtvlmh,.dir-rtl .ygtvlmhh{background-position:0 -800px}.dir-rtl .ygtvlp{background-position:0 -2400px}.dir-rtl .ygtvlph,.dir-rtl .ygtvlphh{background-position:0 -3200px}.dir-rtl .ygtvdepthcell{background-position:0 -8000px}.dir-rtl .ygtvok{background-position:0 -8800px}.dir-rtl .ygtvok:hover{background-position:0 -8844px}.dir-rtl .ygtvcancel{background-position:0 -8822px}.dir-rtl .ygtvcancel:hover{background-position:0 -8866px}.dir-rtl.yui-skin-sam .yui-panel .hd{text-align:right}.dir-rtl .yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd{text-align:right}.dir-rtl .clearlooks2.ie9 .mceAlert .mceMiddle span,.dir-rtl .clearlooks2 .mceConfirm .mceMiddle span{top:44px}.dir-rtl .o2k7Skin table,.dir-rtl .o2k7Skin tbody,.dir-rtl .o2k7Skin a,.dir-rtl .o2k7Skin img,.dir-rtl .o2k7Skin tr,.dir-rtl .o2k7Skin div,.dir-rtl .o2k7Skin td,.dir-rtl .o2k7Skin iframe,.dir-rtl .o2k7Skin span,.dir-rtl .o2k7Skin *,.dir-rtl .o2k7Skin .mceText,.dir-rtl .o2k7Skin .mceListBox .mceText{text-align:right}.path-rating .ratingtable{width:100%;margin-bottom:1em}.path-rating .ratingtable th.rating{width:100%}.path-rating .ratingtable td.rating,.path-rating .ratingtable td.time{text-align:center;white-space:nowrap}.initialbar a{padding-right:2px}.moodle-dialogue-base .moodle-dialogue-lightbox{background-color:#AAA}.moodle-dialogue-base .hidden,.moodle-dialogue-base .moodle-dialogue-hidden{display:none}.no-scrolling{overflow:hidden}.moodle-dialogue-base .moodle-dialogue-fullscreen{position:fixed;top:0;right:0;bottom:-50px;left:0}.moodle-dialogue-base .moodle-dialogue-fullscreen .closebutton{width:28px;height:16px;background-size:100%}.moodle-dialogue-base .moodle-dialogue{z-index:600;padding:0;margin:0;background:0;border:0;outline:#000 dotted 0}.moodle-dialogue-base .moodle-dialogue-wrap{margin-top:-3px;margin-left:-3px;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd{padding:5px;margin:0;font-size:12px;font-weight:normal;letter-spacing:1px;color:#333;text-align:center;text-shadow:1px 1px 1px #fff;background:#ccc;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border-bottom:1px solid #bbb;-webkit-border-radius:10px 10px 0 0;-moz-border-radius:10px 10px 0 0;border-radius:10px 10px 0 0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0);filter:dropshadow(color=#ffffff,offx=1,offy=1)}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd h1{display:inline;padding:0;margin:0;font-size:100%;font-weight:bold}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd .yui3-widget-buttons{padding:5px}.moodle-dialogue-base .closebutton{display:inline-block;float:right;width:25px;height:15px;padding:0;vertical-align:middle;cursor:pointer;background-image:url([[pix:theme|sprite]]);background-repeat:no-repeat;border-style:none}.dir-rtl .moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd .yui3-widget-buttons{right:auto;left:0}.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-bd{padding:1em;overflow:auto;font-size:12px;line-height:2em;color:#555}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-content{padding:0;background:#FFF}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-hd{padding:10px;font-size:16px}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-content{position:absolute;top:0;right:0;bottom:50px;left:0;margin:0;overflow:auto;border:0}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-hd,.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-wrap{border-radius:0}.moodle-dialogue-confirm .confirmation-dialogue{text-align:center}.moodle-dialogue-confirm .confirmation-dialogue input{text-align:center}.moodle-dialogue-exception .moodle-exception-message{text-align:center}.moodle-dialogue-exception .moodle-exception-param label{font-weight:bold}.moodle-dialogue-exception .param-stacktrace label{background-color:#EEE;border:1px solid #ccc;border-bottom-width:0}.moodle-dialogue-exception .param-stacktrace pre{background-color:#fff;border:1px solid #ccc}.moodle-dialogue-exception .param-stacktrace .stacktrace-file{font-size:11.9px;color:navy}.moodle-dialogue-exception .param-stacktrace .stacktrace-line{font-size:11.9px;color:#b94a48}.moodle-dialogue-exception .param-stacktrace .stacktrace-call{font-size:90%;color:#333;border-bottom:1px solid #eee}.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-content .moodle-dialogue-ft{padding:0;margin:.7em 1em;font-size:12px;text-align:right;background-color:#FFF}.moodle-dialogue-confirm .confirmation-message{margin:.5em 1em}.moodle-dialogue-confirm .confirmation-dialogue input{min-width:80px}.moodle-dialogue-exception .moodle-exception-message{margin:1em}.moodle-dialogue-exception .moodle-exception-param{margin-bottom:.5em}.moodle-dialogue-exception .moodle-exception-param label{width:150px}.moodle-dialogue-exception .param-stacktrace label{display:block;padding:4px 1em;margin:0}.moodle-dialogue-exception .param-stacktrace pre{display:block;height:200px;overflow:auto}.moodle-dialogue-exception .param-stacktrace .stacktrace-file{display:inline-block;margin:4px 0}.moodle-dialogue-exception .param-stacktrace .stacktrace-line{display:inline-block;width:50px;margin:4px 1em}.moodle-dialogue-exception .param-stacktrace .stacktrace-call{padding-bottom:4px;padding-left:25px;margin-bottom:4px}.moodle-dialogue .moodle-dialogue-bd .content-lightbox{top:0;left:0;width:100%;height:100%;padding:10% 0;text-align:center;background-color:white;opacity:.75;filter:alpha(opacity=75)}.moodle-dialogue .tooltiptext{max-height:300px}.moodle-dialogue-base .moodle-dialogue.moodle-dialogue-tooltip{z-index:3001}#page-question-edit.dir-rtl a.container-close{right:auto;left:6px}.chooserdialoguebody,.choosertitle{display:none}.moodle-dialogue.chooserdialogue .moodle-dialogue-content .moodle-dialogue-ft{margin:0}.chooserdialogue .moodle-dialogue-wrap .moodle-dialogue-bd{padding:0;background:#f2f2f2;-webkit-border-bottom-right-radius:10px;border-bottom-right-radius:10px;-webkit-border-bottom-left-radius:10px;border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-moz-border-radius-bottomleft:10px}.choosercontainer #chooseform .submitbuttons{margin:.7em 0;text-align:center}.choosercontainer #chooseform .submitbuttons input{min-width:100px;margin:0 .5em}.choosercontainer #chooseform .options{position:relative;border-bottom:1px solid #bbb}.jsenabled .choosercontainer #chooseform .alloptions{max-width:20.3em;overflow-x:hidden;overflow-y:auto;-webkit-box-shadow:inset 0 0 30px 0 #ccc;-moz-box-shadow:inset 0 0 30px 0 #ccc;box-shadow:inset 0 0 30px 0 #ccc}.dir-rtl.jsenabled .choosercontainer #chooseform .alloptions{max-width:18.3em}.choosercontainer #chooseform .moduletypetitle,.choosercontainer #chooseform .option,.choosercontainer #chooseform .nonoption{padding:0 1.6em 0 1.6em;margin-bottom:0}.choosercontainer #chooseform .moduletypetitle{padding-top:1.2em;padding-bottom:.4em;text-transform:uppercase}.choosercontainer #chooseform .option .typename,.choosercontainer #chooseform .option span.modicon img.icon,.choosercontainer #chooseform .nonoption .typename,.choosercontainer #chooseform .nonoption span.modicon img.icon{padding:0 0 0 .5em}.dir-rtl .choosercontainer #chooseform .option .typename,.dir-rtl .choosercontainer #chooseform .option span.modicon img.icon,.dir-rtl .choosercontainer #chooseform .nonoption .typename,.dir-rtl .choosercontainer #chooseform .nonoption span.modicon img.icon{padding:0 .5em 0 0}.choosercontainer #chooseform .option span.modicon img.icon,.choosercontainer #chooseform .nonoption span.modicon img.icon{width:24px;height:24px}.choosercontainer #chooseform .option input[type=radio],.choosercontainer #chooseform .option span.typename,.choosercontainer #chooseform .option span.modicon{vertical-align:middle}.choosercontainer #chooseform .option label{display:block;padding:.3em 0 .1em 0;border-bottom:1px solid #fff}.choosercontainer #chooseform .nonoption{padding-top:.3em;padding-bottom:.1em;padding-left:2.7em}.dir-rtl .choosercontainer #chooseform .nonoption{padding-right:2.7em;padding-left:0}.choosercontainer #chooseform .subtype{padding:0 1.6em 0 3.2em;margin-bottom:0}.dir-rtl .choosercontainer #chooseform .subtype{padding:0 3.2em 0 1.6em}.choosercontainer #chooseform .subtype .typename{margin:0 0 0 .2em}.dir-rtl .choosercontainer #chooseform .subtype .typename{margin:0 .2em 0 0}.jsenabled .choosercontainer #chooseform .instruction,.jsenabled .choosercontainer #chooseform .typesummary{position:absolute;top:0;right:0;bottom:0;left:20.3em;display:none;padding:1.6em;margin:0;overflow-x:hidden;overflow-y:auto;line-height:2em;background-color:#fff}.dir-rtl.jsenabled .choosercontainer #chooseform .instruction,.dir-rtl.jsenabled .choosercontainer #chooseform .typesummary{right:18.5em;left:0;border-right:1px solid grey}.jsenabled .choosercontainer #chooseform .instruction,.choosercontainer #chooseform .selected .typesummary{display:block}.choosercontainer #chooseform .selected{background-color:#fff;-webkit-box-shadow:0 0 10px 0 #ccc;-moz-box-shadow:0 0 10px 0 #ccc;box-shadow:0 0 10px 0 #ccc}.section-modchooser-link img.smallicon{padding:3px}.formlistingradio{padding-right:10px;padding-bottom:25px}.formlistinginputradio{float:left}.formlistingmain{min-height:225px}.formlisting{position:relative;padding:1px 19px 14px;margin:15px 0;background-color:white;border:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.formlistingmore{position:absolute;right:-1px;bottom:-1px;padding:3px 7px;font-size:12px;font-weight:bold;color:#9da0a4;cursor:pointer;background-color:whiteSmoke;border:1px solid #ddd;-webkit-border-radius:4px 0 4px 0;-moz-border-radius:4px 0 4px 0;border-radius:4px 0 4px 0}.formlistingall{padding:0;margin:15px 0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.formlistingrow{top:50%;left:50%;float:left;width:150px;min-height:34px;padding:6px;cursor:pointer;background-color:#f7f7f9;border-right:1px solid #e1e1e8;border-bottom:1px solid;border-left:1px solid #e1e1e8;border-color:#e1e1e8;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}body.jsenabled .formlistingradio{display:none}body.jsenabled .formlisting{display:block}table.collection{width:100%;margin-bottom:20px;border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}table.collection th,table.collection td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}table.collection th{font-weight:bold}table.collection thead th{vertical-align:bottom}table.collection caption+thead tr:first-child th,table.collection caption+thead tr:first-child td,table.collection colgroup+thead tr:first-child th,table.collection colgroup+thead tr:first-child td,table.collection thead:first-child tr:first-child th,table.collection thead:first-child tr:first-child td{border-top:0}table.collection tbody+tbody{border-top:2px solid #ddd}table.collection .table{background-color:#fff}table.collection th,table.collection td{border-left:1px solid #ddd}table.collection caption+thead tr:first-child th,table.collection caption+tbody tr:first-child th,table.collection caption+tbody tr:first-child td,table.collection colgroup+thead tr:first-child th,table.collection colgroup+tbody tr:first-child th,table.collection colgroup+tbody tr:first-child td,table.collection thead:first-child tr:first-child th,table.collection tbody:first-child tr:first-child th,table.collection tbody:first-child tr:first-child td{border-top:0}table.collection thead:first-child tr:first-child>th:first-child,table.collection tbody:first-child tr:first-child>td:first-child,table.collection tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}table.collection thead:first-child tr:first-child>th:last-child,table.collection tbody:first-child tr:first-child>td:last-child,table.collection tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}table.collection thead:last-child tr:last-child>th:first-child,table.collection tbody:last-child tr:last-child>td:first-child,table.collection tbody:last-child tr:last-child>th:first-child,table.collection tfoot:last-child tr:last-child>td:first-child,table.collection tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}table.collection thead:last-child tr:last-child>th:last-child,table.collection tbody:last-child tr:last-child>td:last-child,table.collection tbody:last-child tr:last-child>th:last-child,table.collection tfoot:last-child tr:last-child>td:last-child,table.collection tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}table.collection tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}table.collection tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}table.collection caption+thead tr:first-child th:first-child,table.collection caption+tbody tr:first-child td:first-child,table.collection colgroup+thead tr:first-child th:first-child,table.collection colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}table.collection caption+thead tr:first-child th:last-child,table.collection caption+tbody tr:first-child td:last-child,table.collection colgroup+thead tr:first-child th:last-child,table.collection colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}table.collection tbody>tr:nth-child(odd)>td,table.collection tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}table.collection .name{text-align:left;vertical-align:middle}table.collection .awards{width:10%;text-align:center;vertical-align:middle}table.collection .criteria{width:40%;text-align:left;vertical-align:top}table.collection .badgeimage,table.collection .status{width:15%;text-align:center;vertical-align:middle}table.collection .description{width:25%;text-align:left}table.collection .actions{width:11em;text-align:center;vertical-align:middle}a.criteria-action{float:right;padding:0 3px}table.issuedbadgebox{width:750px;background-color:#fff}table.badgeissuedimage{width:150px;text-align:center}table.badgeissuedinfo{width:600px}table.badgeissuedinfo .bvalue{text-align:left;vertical-align:middle}table.badgeissuedinfo .bfield{width:125px;font-style:italic;text-align:left}.dir-rtl table.badgeissuedinfo .bvalue,.dir-rtl table.badgeissuedinfo .bfield{text-align:right}ul.badges{margin:0;list-style:none}.badges li{position:relative;display:inline-block;width:150px;padding-bottom:2em;text-align:center;vertical-align:top}.badges li .badge-name{display:block;padding:5px}.badges li>img{position:absolute}.badges li .badge-image{top:0;left:10px;z-index:1;width:90px;height:90px}.badges li .badge-actions{position:relative}div.badge{position:relative;display:block}div.badge .expireimage{top:0;left:20px;width:100px;height:100px}.expireimage{position:absolute;top:0;left:30px;z-index:10;width:90px;height:90px;opacity:.85;filter:alpha(opacity=85)}.badge-profile{vertical-align:top}.connected{color:#468847}.notconnected{color:#b94a48}.connecting{color:#c09853}#page-badges-award .recipienttable tr td{vertical-align:top}#page-badges-award .recipienttable tr td.actions .actionbutton{width:100%;padding:.5em 0;margin:.3em 0}#page-badges-award .recipienttable tr td.existing,#page-badges-award .recipienttable tr td.potential{width:42%}.statustable{margin-bottom:0}.statusbox.active{background-color:#dff0d8}.statusbox.inactive{background-color:#fcf8e3}.activatebadge{margin:0;text-align:left;vertical-align:middle}.dir-rtl .activatebadge{text-align:right}img#persona_signin{cursor:pointer}.addcourse{float:right}.invisiblefieldset{display:inline;padding:0;margin:0;border-width:0}.breadcrumb-nav{float:left;margin-bottom:10px}.dir-rtl .breadcrumb-nav{float:right}.breadcrumb-button .singlebutton div{margin-right:0}.breadcrumb-nav .breadcrumb{margin:0}.moodle-actionmenu,.moodle-actionmenu>ul,.moodle-actionmenu>ul>li{display:inline-block}.moodle-actionmenu ul{padding:0;margin:0;list-style-type:none}.moodle-actionmenu .toggle-display,.moodle-actionmenu .menu-action-text{display:none}.jsenabled .moodle-actionmenu[data-enhance]{display:block}.jsenabled .moodle-actionmenu[data-enhance] .menu{display:none}.jsenabled .moodle-actionmenu[data-enhance] .toggle-display{display:inline;opacity:.5;filter:alpha(opacity=50)}.jsenabled .moodle-actionmenu[data-enhanced] .toggle-display{opacity:1;filter:alpha(opacity=100)}.jsenabled .moodle-actionmenu[data-enhanced] .menu-action-text{display:inline}.moodle-actionmenu[data-enhanced].show{position:relative}.moodle-actionmenu[data-enhanced].show .menu{position:absolute;z-index:1000;display:block;text-align:left;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}.moodle-actionmenu[data-enhanced].show .menu a{display:block;padding:2px 1em 2px .5em;color:#333}.moodle-actionmenu[data-enhanced].show .menu a:hover,.moodle-actionmenu[data-enhanced].show .menu a:focus{color:#fff;background-color:#08c}.moodle-actionmenu[data-enhanced].show .menu a:first-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.moodle-actionmenu[data-enhanced].show .menu a:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.moodle-actionmenu[data-enhanced].show .menu a.hidden{display:none}.moodle-actionmenu[data-enhanced].show .menu img{vertical-align:middle}.moodle-actionmenu[data-enhanced].show .menu .iconsmall{margin-right:8px}.moodle-actionmenu[data-enhanced].show .menu>li{display:block}.moodle-actionmenu[data-enhanced].show .menu.align-tl-bl{top:100%;left:0;margin-top:4px}.moodle-actionmenu[data-enhanced].show .menu.align-tr-bl{top:100%;right:100%}.moodle-actionmenu[data-enhanced].show .menu.align-bl-bl{bottom:100%;left:0}.moodle-actionmenu[data-enhanced].show .menu.align-br-bl{right:100%;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-br{top:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tr-br{top:100%;right:0;margin-top:4px}.moodle-actionmenu[data-enhanced].show .menu.align-bl-br{bottom:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-br-br{right:0;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-tl{top:0;left:0}.moodle-actionmenu[data-enhanced].show .menu.align-tr-tl{top:0;right:100%;margin-right:4px}.moodle-actionmenu[data-enhanced].show .menu.align-bl-tl{bottom:100%;left:0;margin-bottom:4px}.moodle-actionmenu[data-enhanced].show .menu.align-br-tl{right:100%;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-tr{top:0;left:100%;margin-left:4px}.moodle-actionmenu[data-enhanced].show .menu.align-tr-tr{top:0;right:0}.moodle-actionmenu[data-enhanced].show .menu.align-bl-tr{bottom:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-br-tr{right:0;bottom:100%;margin-bottom:4px}.action-menu-shown .moodle-actionmenu[data-enhanced] .toggle-display{background-color:#FFF}.block .moodle-actionmenu{text-align:right}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu{right:auto;left:0;text-align:right}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu .iconsmall{margin-right:0;margin-left:8px}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-bl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-bl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-bl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-bl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-br{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-br{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-br{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-br{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-tl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-tl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-tl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-tl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-tr{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-tr{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-tr{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-tr{right:auto;left:0}.dir-rtl .block .moodle-actionmenu{text-align:right}ul.dragdrop-keyboard-drag li{list-style-type:none}.block-control-actions .moodle-core-dragdrop-draghandle img{width:12px;height:12px}a.disabled:hover,a.disabled{font-style:italic;color:#808080;text-decoration:none;cursor:default}.formtable tbody th{font-weight:normal;text-align:right}.path-admin #assignrole{width:60%;margin-right:auto;margin-left:auto}.path-admin .admintable .leftalign{text-align:left}.environmenttable p.warn{color:#c09853;background-color:#fcf8e3}.environmenttable .error,.environmenttable span.warn,.environmenttable .ok{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.environmenttable .error:empty,.environmenttable span.warn:empty,.environmenttable .ok:empty{display:none}.environmenttable .error-important,.environmenttable span.warn-important,.environmenttable .ok-important{background-color:#b94a48}.environmenttable .error-important[href],.environmenttable span.warn-important[href],.environmenttable .ok-important[href]{background-color:#953b39}.environmenttable .error-warning,.environmenttable span.warn-warning,.environmenttable .ok-warning{background-color:#f89406}.environmenttable .error-warning[href],.environmenttable span.warn-warning[href],.environmenttable .ok-warning[href]{background-color:#c67605}.environmenttable .error-success,.environmenttable span.warn-success,.environmenttable .ok-success{background-color:#468847}.environmenttable .error-success[href],.environmenttable span.warn-success[href],.environmenttable .ok-success[href]{background-color:#356635}.environmenttable .error-info,.environmenttable span.warn-info,.environmenttable .ok-info{background-color:#3a87ad}.environmenttable .error-info[href],.environmenttable span.warn-info[href],.environmenttable .ok-info[href]{background-color:#2d6987}.environmenttable .error-inverse,.environmenttable span.warn-inverse,.environmenttable .ok-inverse{background-color:#333}.environmenttable .error-inverse[href],.environmenttable span.warn-inverse[href],.environmenttable .ok-inverse[href]{background-color:#1a1a1a}.environmenttable .error{background-color:#b94a48}.environmenttable span.warn{background-color:#f89406}.environmenttable .ok{background-color:#468847}.path-admin .admintable.environmenttable .name,.path-admin .admintable.environmenttable .info,.path-admin #assignrole .admintable .role,.path-admin #assignrole .admintable .userrole,.path-admin #assignrole .admintable .roleholder{white-space:nowrap}.path-admin .incompatibleblockstable td.c0{font-weight:bold}#page-admin-course-category .addcategory{padding:10px}#page-admin-course-index .editcourse{margin:20px auto}#page-admin-course-index .editcourse th,#page-admin-course-index .editcourse td{padding-right:10px;padding-left:10px}.timewarninghidden{display:none}.statusok,.statuswarning,.statusserious,.statuscritical{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.statusok:empty,.statuswarning:empty,.statusserious:empty,.statuscritical:empty{display:none}.statusok-important,.statuswarning-important,.statusserious-important,.statuscritical-important{background-color:#b94a48}.statusok-important[href],.statuswarning-important[href],.statusserious-important[href],.statuscritical-important[href]{background-color:#953b39}.statusok-warning,.statuswarning-warning,.statusserious-warning,.statuscritical-warning{background-color:#f89406}.statusok-warning[href],.statuswarning-warning[href],.statusserious-warning[href],.statuscritical-warning[href]{background-color:#c67605}.statusok-success,.statuswarning-success,.statusserious-success,.statuscritical-success{background-color:#468847}.statusok-success[href],.statuswarning-success[href],.statusserious-success[href],.statuscritical-success[href]{background-color:#356635}.statusok-info,.statuswarning-info,.statusserious-info,.statuscritical-info{background-color:#3a87ad}.statusok-info[href],.statuswarning-info[href],.statusserious-info[href],.statuscritical-info[href]{background-color:#2d6987}.statusok-inverse,.statuswarning-inverse,.statusserious-inverse,.statuscritical-inverse{background-color:#333}.statusok-inverse[href],.statuswarning-inverse[href],.statusserious-inverse[href],.statuscritical-inverse[href]{background-color:#1a1a1a}.statusok{background-color:#468847}.statuswarning{background-color:#c09853}.statusserious{background-color:#f89406}.statuscritical{background-color:#b94a48}#page-admin-report-capability-index #capabilitysearch{width:30em}#page-admin-report-backups-index .backup-error,#page-admin-report-backups-index .backup-unfinished{color:#b94a48}#page-admin-report-backups-index .backup-skipped,#page-admin-report-backups-index .backup-ok{color:#468847}#page-admin-report-backups-index .backup-warning{color:#c09853}#page-admin-qtypes .disabled,#page-admin-qbehaviours .disabled{color:#999}#page-admin-qtypes #qtypes div,#page-admin-qtypes #qtypes form,#page-admin-qbehaviours #qbehaviours div,#page-admin-qbehaviours #qbehaviours form{display:inline}#page-admin-qtypes #qtypes img.spacer,#page-admin-qbehaviours #qbehaviours img.spacer{width:16px}img.iconsmall{padding:.3em;margin:0}#page-admin-qbehaviours .cell.c3,#page-admin-qtypes .cell.c3{font-size:10.5px}#page-admin-lang .generalbox,#page-admin-course-index .singlebutton,#page-admin-course-index .addcategory,#page-course-index .buttons,#page-course-index-category .buttons,#page-admin-course-category .addcategory,#page-admin-stickyblocks .generalbox,#page-admin-maintenance .buttons,#page-admin-course-index .buttons,#page-admin-course-category .buttons,#page-admin-index .copyright,#page-admin-index .copyrightnotice,#page-admin-index .adminerror,#page-admin-index .availableupdatesinfo,#page-admin-index .adminerror .singlebutton,#page-admin-index .adminwarning .singlebutton,#page-admin-index #layout-table .singlebutton{margin-bottom:1em;text-align:center}.path-admin-roles .capabilitysearchui{margin-right:auto;margin-left:auto;text-align:left}#page-admin-roles-define .topfields{margin:1em 0 2em}#page-admin-roles-define .capdefault{background-color:#eee;border:1px solid #cecece}#page-filter-manage .backlink,.path-admin-roles .backlink{margin-top:1em}#page-admin-roles-explain #chooseuser h3,#page-admin-roles-usersroles .contextname{margin-top:0}#page-admin-roles-explain #chooseusersubmit{margin-top:0;text-align:center}#page-admin-roles-usersroles p{margin:0}#page-admin-roles-override .cell.c1,#page-admin-roles-assign .cell.c3,#page-admin-roles-assign .cell.c1{padding-top:.75em}#page-admin-roles-override .overridenotice,#page-admin-roles-define .definenotice{margin:1em 10% 2em 10%;text-align:left}#notice{width:60%;min-width:220px;margin:auto}#page-admin-index .releasenoteslink,#page-admin-index .adminwarning,#page-admin-index .maturitywarning,#page-admin-index .testsitewarning,#page-admin-index .maturityinfo{width:60%;min-width:220px;padding:8px 35px 8px 14px;margin:auto;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}#page-admin-index .maturitywarning,#page-admin-index .testsitewarning,#page-admin-index .adminwarning.maturityinfo.maturity50{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}#page-admin-index .adminwarning.availableupdatesinfo,#page-admin-index .releasenoteslink{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo span{display:block}#page-admin-index .updateplugin div,#page-admin-plugins .updateplugin div{margin-bottom:.5em}#page-admin-index .updateplugin .updatepluginconfirmexternal,#page-admin-plugins .updateplugin .updatepluginconfirmexternal{padding:1em;background-color:#f2dede;border:1px solid #eed3d7}#page-admin-user-user_bulk #users .fgroup{white-space:nowrap}#page-admin-report-stats-index .graph{margin-bottom:1em;text-align:center}#page-admin-report-courseoverview-index .graph{margin-bottom:1em;text-align:center}#page-admin-lang .translator{border-style:solid;border-width:1px}.path-admin .roleassigntable{width:100%}.path-admin .roleassigntable td{padding:.2em .3em;vertical-align:top}.path-admin .roleassigntable p{margin:.2em 0;text-align:left}.path-admin .roleassigntable #existingcell,.path-admin .roleassigntable #potentialcell{width:42%}.path-admin .roleassigntable #existingcell p>label:first-child,.path-admin .roleassigntable #potentialcell p>label:first-child{font-weight:bold}.path-admin .roleassigntable #buttonscell{width:16%}.path-admin .roleassigntable #buttonscell #assignoptions{font-size:10.5px}.path-admin .roleassigntable #removeselect_wrapper,.path-admin .roleassigntable #addselect_wrapper{width:100%}.path-admin table.rolecap tr.rolecap th{font-weight:normal;text-align:left}.path-admin.dir-rtl table.rolecap tr.rolecap th{text-align:right}.path-admin .rolecap .hiddenrow{display:none}.path-admin #defineroletable .rolecap .inherit,.path-admin #defineroletable .rolecap .allow,.path-admin #defineroletable .rolecap .prevent,.path-admin #defineroletable .rolecap .prohibit{min-width:3.5em;padding:0;text-align:center}.path-admin .rolecap .cap-name,.path-admin .rolecap .note{display:block;font-size:10.5px;font-weight:normal;white-space:nowrap}.path-admin .rolecap label{display:block;padding:.5em;margin:0;text-align:center}.plugincheckwrapper{width:100%}.environmentbox{margin-top:1em}#mnetconfig table{margin-right:auto;margin-left:auto}.environmenttable .cell{padding:.15em .5em}.environmenttable img.iconhelp{padding-right:.3em}.dir-rtl .environmenttable img.iconhelp{padding-right:0;padding-left:.3em}#trustedhosts .generaltable{width:500px;margin-right:auto;margin-left:auto}#trustedhosts .standard{width:auto}#adminsettings legend{display:none}#adminsettings fieldset.error{margin:.2em 0 .5em 0}#adminsettings fieldset.error legend{display:block}.dir-rtl #admin-spelllanguagelist textarea,#page-admin-setting-editorsettingstinymce.dir-rtl .form-textarea textarea{text-align:left;direction:ltr}.adminsettingsflags{float:right}.dir-rtl .adminsettingsflags{float:left}.adminsettingsflags label{margin-right:7px}.dir-rtl .adminsettingsflags label{margin-left:7px}.form-description{clear:right}.dir-rtl .form-description{clear:left}.form-item .form-setting .form-htmlarea{display:inline;width:640px}.form-item .form-setting .form-htmlarea .htmlarea{display:block;width:640px}.form-item .form-setting .form-multicheckbox ul{padding:0;margin:7px 0 0 0;list-style:none}.form-item .form-setting .defaultsnext{display:inline;margin-right:.5em}.dir-rtl .form-item .form-setting .defaultsnext{margin-right:0;margin-left:.5em}.form-item .form-setting .locked-checkbox{display:inline;margin-right:.2em;margin-left:.5em}.dir-rtl .form-item .form-setting .locked-checkbox{display:inline;margin-right:.5em;margin-left:.2em}.form-item .form-setting .form-password .unmask,.form-item .form-setting .form-defaultinfo{display:inline-block}.form-item .pathok,.form-item .patherror{margin-left:.5em}#admin-devicedetectregex table{border:0}#admin-emoticons td input{width:8em}#admin-emoticons td.c0 input{width:4em}#adminthemeselector .selectedtheme td.c0{border:1px solid;border-right-width:0}#adminthemeselector .selectedtheme td.c1{border:1px solid;border-left-width:0}.admin_colourpicker,.admin_colourpicker_preview{display:none}.jsenabled .admin_colourpicker_preview{display:inline}.jsenabled .admin_colourpicker{display:block;width:410px;height:102px;margin-bottom:10px}.admin_colourpicker .loadingicon{margin-left:auto;vertical-align:middle}.admin_colourpicker .colourdialogue{float:left;border:1px solid #000}.admin_colourpicker .previewcolour{margin-left:301px;border:1px solid #000}.admin_colourpicker .currentcolour{margin-left:301px;border:1px solid #000;border-top-width:0}.dir-rtl .form-item .form-setting,.dir-rtl .form-item .form-label,.dir-rtl .form-item .form-description,.dir-rtl.path-admin .roleassigntable p{text-align:right}#page-admin-index #notice .checkforupdates{text-align:center}#plugins-check-info{margin:1em;text-align:center}#plugins-check .displayname .pluginicon{width:16px}#plugins-check .status-new .status{background-color:#dff0d8}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release,#plugins-check .status-upgrade .status,#plugins-check .status-delete .status{background-color:#d9edf7}#plugins-control-panel .extension .source,#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity100 .info.release,#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity150 .info.release,.pluginupdateinfo.maturity100,.pluginupdateinfo.maturity150,#plugins-check .extension .source{background-color:#fcf8e3}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity50 .info.release,.pluginupdateinfo.maturity50,#plugins-check .requires-failed,#plugins-check .missingfromdisk .displayname,#plugins-check .status-missing .status,#plugins-check .status-downgrade .status{background-color:#f2dede}#plugins-control-panel .statusmsg{padding:3px;background-color:#eee;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#plugins-control-panel .status-missing .pluginname{background-color:#f2dede}#plugins-control-panel .status-missing .statusmsg{color:#b94a48}#plugins-control-panel .status-new .pluginname{background-color:#dff0d8}#plugins-control-panel .status-new .statusmsg{color:#468847}#plugins-control-panel .disabled .availability{background-color:#eee}#plugins-check .standard .source,#plugins-check .status-nodb .status,#plugins-check .status-uptodate .status,#plugins-check .requires-ok{color:#999}#plugins-check .requires ul{margin:0;font-size:10.5px}#plugins-check .status .pluginupdateinfo{padding:5px 10px;margin:10px;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-check .status .pluginupdateinfo span,#plugins-check .status .pluginupdateinfo a{padding-right:1em}#page-admin-index .upgradepluginsinfo{text-align:center}#page-admin-plugins .checkforupdates{margin:0 auto 1em;text-align:center}#plugins-control-panel .requiredby,#plugins-control-panel .pluginname .componentname{font-size:11.9px;color:#999}#plugins-control-panel .pluginname .componentname{margin-left:22px}#plugins-overview-filter .filter-item,#plugins-overview-panel .info{padding:0 10px}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo .separator,#plugins-check .status .pluginupdateinfo .separator,#page-admin-plugins .separator{border-left:1px dotted #999}#plugins-control-panel .msg td{text-align:center}#plugins-overview-filter,#plugins-overview-panel{margin:1em auto;text-align:center}#plugins-overview-panel .info.updatable{margin-left:10px;font-weight:bold;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-overview-filter .filter-item.active{font-weight:bold}#plugins-control-panel .displayname img.icon{padding-top:0;padding-bottom:0}#plugins-control-panel .uninstall a{color:#b94a48}#plugins-control-panel .notes .pluginupdateinfo{padding:5px 10px;margin:10px;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-control-panel .notes .pluginupdateinfo span,#plugins-control-panel .notes .pluginupdateinfo a{padding-right:1em}.dir-rtl #plugins-check .pluginupdateinfo{text-align:center;direction:ltr}.dir-rtl #plugins-check .rootdir,.dir-rtl #plugins-check .requires-ok{text-align:left;direction:ltr}#page-admin-mnet-peers .box.deletedhosts{margin-bottom:1em;font-size:11.9px}#page-admin-mnet-peers .mform .certdetails{background-color:white}#page-admin-mnet-peers .mform .deletedhostinfo{padding:4px;margin-bottom:5px;background-color:#f2dede;border:2px solid #eed3d7}#core-cache-plugin-summaries table,#core-cache-store-summaries table{width:100%}#core-cache-lock-summary table,#core-cache-definition-summaries table,#core-cache-mode-mappings table{margin:0 auto}#core-cache-store-summaries .default-store td{font-style:italic;color:#333}#core-cache-rescan-definitions,#core-cache-mode-mappings .edit-link,#core-cache-lock-summary .new-instance{margin-top:.5em;text-align:center}.tinymcesubplugins img.icon{padding-top:0;padding-bottom:0}#page-admin-roles-assign div.box.generalbox{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;color:#b94a48;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;background-color:#f2dede;border:1px solid #fbeed5;border-color:#eed3d7;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.calendartable{width:100%}.calendartable th,.calendartable td{width:14%;text-align:center;vertical-align:top;border:0}.calendar_event_course{background-color:#ffd3bd}.calendar_event_global{background-color:#d6f8cd}.calendar_event_group{background-color:#fee7ae}.calendar_event_user{background-color:#dce7ec}.path-calendar .calendar-controls .previous,.path-calendar .calendar-controls .next,.path-calendar .calendar-controls .current{display:block;float:left;width:12%}.path-calendar .calendar-controls .previous{text-align:left}.path-calendar .calendar-controls .current{width:76%;text-align:center}.path-calendar .calendar-controls .next{text-align:right}.path-calendar .maincalendar{padding:0;vertical-align:top}.path-calendar .maincalendar .bottom{padding:5px 0 0 0;text-align:center}.path-calendar .maincalendar .heightcontainer{position:relative;height:100%}.path-calendar .maincalendar .calendarmonth{width:98%;margin:10px auto}.path-calendar .maincalendar .calendarmonth ul{margin:0}.path-calendar .maincalendar .calendarmonth ul li{margin-top:4px;list-style-type:none}.path-calendar .maincalendar .calendarmonth td{height:5em}.path-calendar .maincalendar .calendar-controls .previous,.path-calendar .maincalendar .calendar-controls .next{width:30%}.path-calendar .maincalendar .calendar-controls .current{width:39.95%}.path-calendar .maincalendar .controls{width:98%;margin:10px auto}.path-calendar .maincalendar .eventlist .event{width:100%;margin-bottom:10px;border-collapse:separate;border-spacing:0;border-style:solid;border-width:1px}.path-calendar .maincalendar .eventlist .event .topic .name{float:left}.dir-rtl.path-calendar .maincalendar .eventlist .event .topic .name,.path-calendar .maincalendar .eventlist .event .topic .date{float:right}.dir-rtl.path-calendar .maincalendar .eventlist .event .topic .date{float:left}.path-calendar .maincalendar .eventlist .event .subscription,.path-calendar .maincalendar .eventlist .event .course{float:left;clear:left}.dir-rtl.path-calendar .maincalendar .eventlist .event .subscription,.dir-rtl.path-calendar .maincalendar .eventlist .event .course{float:right;clear:right}.path-calendar .maincalendar .eventlist .event .side{width:32px}.path-calendar .maincalendar .eventlist .event .commands a{margin:0 3px}.path-calendar .maincalendar .header{overflow:hidden}.path-calendar .maincalendar .header .buttons{float:right}.dir-rtl.path-calendar .maincalendar .header .buttons{float:left}.path-calendar .filters table{width:100%;border-collapse:separate;border-spacing:2px}#page-calendar-export .indent{padding-left:20px}.path-calendar .cal_courses_flt label{margin-right:.45em}.dir-rtl.path-calendar .cal_courses_flt label{margin-right:0;margin-left:.45em}.block .minicalendar th,.block .minicalendar td{padding:2px;font-size:.8em}.block .minicalendar{max-width:280px;margin-right:auto;margin-left:auto}.block .minicalendar td.weekend{color:#A00}.block .calendar-controls .previous{display:block;float:left;width:12%;text-align:left}.block .calendar-controls .current{display:block;float:left;width:76%;text-align:center}.block .calendar-controls .next{display:block;float:left;width:12%;text-align:right}.block .calendar_filters ul{margin:0;list-style:none}.block .calendar_filters li{margin-bottom:.2em}.block .calendar_filters li span img{padding:0 .2em}.block .calendar_filters .eventname{padding-left:.2em}.dir-rtl .block .calendar_filters .eventname{padding-right:.2em;padding-left:0}.block .content h3.eventskey{margin-top:.5em}@media(min-width:768px){#page-calender-view .container fluid{min-width:1024px}}.section_add_menus{text-align:right}.dir-rtl .section_add_menus{text-align:left}.section_add_menus .horizontal div,.section_add_menus .horizontal form{display:inline}.section_add_menus optgroup{font-style:italic;font-weight:normal}.section_add_menus .urlselect{margin-left:.4em}.dir-rtl .section_add_menus .urlselect{margin-right:.4em;margin-left:0}.section_add_menus .urlselect select{margin-left:.2em}.dir-rtl .section_add_menus .urlselect select{margin-right:.2em;margin-left:0}.section_add_menus .urlselect img.iconhelp{padding:0;margin:0;vertical-align:text-bottom}.site-topic ul.section,.course-content ul.section{margin:1em}.section .activity img.activityicon{margin-right:6px}.dir-rtl .section .activity img.activityicon{margin-right:0;margin-left:6px}.section .activity .activityinstance,.section .activity .activityinstance div{display:inline-block}.editing .section .activity .activityinstance{min-width:40%}.section .activity .activityinstance>a{display:block}.editing_show+.editing_assign,.editing_hide+.editing_assign{margin-left:20px}.section .activity .commands{display:inline;white-space:nowrap}.section .activity.modtype_label .commands{padding-left:.2em;margin-left:40%}.section .activity.modtype_label.label{padding:.2em;font-weight:normal}.modtype_label .no-overflow>p:last-child{margin-bottom:0}.section li.activity{padding:.2em;clear:both}.section .activity .activityinstance .groupinglabel{padding-left:30px}.dir-rtl .section .activity .activityinstance .groupinglabel{padding-right:30px}.section .activity .availabilityinfo,.section .activity .contentafterlink{margin-top:.5em;margin-left:30px}.dir-rtl .section .activity .availabilityinfo,.dir-rtl .section .activity .contentafterlink{margin-right:30px;margin-left:0}.section .activity .contentafterlink p{margin:.5em 0}.editing .section .activity:hover,.editing .section .activity.action-menu-shown{background-color:#eee}.course-content .current{background-color:#d9edf7}.course-content .section-summary{margin-top:5px;list-style:none;border:1px solid #DDD}.course-content .section-summary .section-title{margin:2px 5px 10px 5px}.course-content .section-summary .summarytext{margin:2px 5px 2px 5px}.course-content .section-summary .section-summary-activities .activity-count{display:inline-block;margin:3px;font-size:11.9px;color:#999;white-space:nowrap}.course-content .section-summary .summary{margin-top:5px}.course-content .single-section{margin-top:1em}.course-content .single-section .section-navigation{display:block;padding:.5em;margin-bottom:-0.5em}.course-content .single-section .section-navigation .title{clear:both;font-size:108%;font-weight:bold}.course-content .single-section .section-navigation .mdl-left{float:left;margin-right:1em;font-weight:normal}.dir-rtl .course-content .single-section .section-navigation .mdl-left{float:right}.course-content .single-section .section-navigation .mdl-left .larrow{margin-right:.1em}.course-content .single-section .section-navigation .mdl-right{float:right;margin-left:1em;font-weight:normal}.dir-rtl .course-content .single-section .section-navigation .mdl-right{float:left}.course-content .single-section .section-navigation .mdl-right .rarrow{margin-left:.1em}.course-content .single-section .section-navigation .mdl-bottom{margin-top:0}.course-content ul li.section.main{margin-top:0;border-bottom:2px solid #eee}.course-content ul li.section.hidden{opacity:.5}.course-content ul.topics li.section .content,.course-content ul.weeks li.section .content{padding:0;margin-right:20px;margin-left:20px}.course-content{margin-top:0}.course-content ul.topics li.section{padding-bottom:20px}.course-content ul.topics li.section .summary{margin-left:25px}.path-course-view .completionprogress{margin-left:25px}.path-course-view .completionprogress{position:relative;z-index:1000;display:block;float:right;height:20px}#page-site-index .subscribelink{text-align:right}#page-site-index .headingblock{margin-bottom:9px}.path-course-view a.reduce-sections{padding-left:.2em}.path-course-view .headingblock{margin-bottom:9px}.path-course-view .subscribelink{text-align:right}.path-course-view .unread{margin-left:30px}.dir-rtl.path-course-view .unread{margin-right:30px}.path-course-view .block.drag .header{cursor:move}.path-course-view .completionprogress{text-align:right}.dir-rtl.path-course-view .completionprogress{text-align:left}.path-course-view .single-section .completionprogress{margin-right:5px}.path-course-view .section .summary{line-height:normal}.path-site li.activity>div,.path-course-view li.activity>div{position:relative}.path-course-view li.activity span.autocompletion,.path-course-view li.activity form.togglecompletion{float:right}.path-course-view li.activity form.togglecompletion .ajaxworking{width:16px;height:16px;background:url([[pix:i/ajaxloader]]) no-repeat}.dir-rtl.path-course-view li.activity form.togglecompletion,.dir-rtl.path-course-view li.activity span.autocompletion{float:left}.dir-rtl.path-course-view .completionprogress{float:none}.dir-rtl.path-course-view li.activity form.togglecompletion .ajaxworking{right:-22px}li.section.hidden span.commands a.editing_hide,li.section.hidden span.commands a.editing_show{cursor:default}ul.weeks h3.sectionname{white-space:nowrap}.editing ul.weeks h3.sectionname{white-space:normal}.single-section h3.sectionname{clear:both;text-align:center}.section img.movetarget{width:80px;height:16px}input.titleeditor{width:330px;vertical-align:text-bottom}span.editinstructions{position:absolute;top:0;left:0;z-index:9999;padding:.1em .4em;margin-top:-22px;margin-left:30px;font-size:11.9px;line-height:16px;color:#3a87ad;text-decoration:none;background-color:#d9edf7;border:1px solid #bce8f1;-webkit-box-shadow:2px 2px 5px 1px #ccc;-moz-box-shadow:2px 2px 5px 1px #ccc;box-shadow:2px 2px 5px 1px #ccc}.dir-rtl span.editinstructions{right:32px;left:auto}#dndupload-status{position:absolute;z-index:9999;z-index:0;width:40%;padding:6px;margin:0 30%;color:#3a87ad;text-align:center;background:#d9edf7;border:1px solid #bce8f1;-webkit-border-bottom-right-radius:8px;border-bottom-right-radius:8px;-webkit-border-bottom-left-radius:8px;border-bottom-left-radius:8px;-moz-border-radius-bottomright:8px;-moz-border-radius-bottomleft:8px;-webkit-box-shadow:2px 2px 5px 1px #ccc;-moz-box-shadow:2px 2px 5px 1px #ccc;box-shadow:2px 2px 5px 1px #ccc}.dndupload-preview{padding:.3em;margin-top:.2em;color:#909090;list-style:none;border:1px dashed #909090}.dndupload-preview img.icon{padding:0;vertical-align:text-bottom}.dndupload-progress-outer{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.dndupload-progress-inner{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.dndupload-hidden{display:none}#page-course-pending .singlebutton,#page-course-index .singlebutton,#page-course-index-category .singlebutton,#page-course-editsection .singlebutton{text-align:center}#page-admin-course-manage #movecourses td img{margin:0 .22em;vertical-align:text-bottom}#page-admin-course-manage #movecourses td img.icon{padding:0}#coursesearch{margin-top:1em;text-align:center}#page-course-pending .pendingcourserequests{margin-bottom:1em}#page-course-pending .pendingcourserequests .singlebutton{display:inline}#page-course-pending .pendingcourserequests .cell{padding:0 5px}#page-course-pending .pendingcourserequests .cell.c6{white-space:nowrap}.coursebox{padding:5px;margin-bottom:15px;border:1px dotted #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.coursebox>.info>.name a{display:block;padding-left:21px;background-image:url([[pix:moodle|i/course]]);background-position:center left;background-repeat:no-repeat}.coursebox.remotehost>.info>.name a{background-image:url([[pix:moodle|i/mnethost]])}.coursebox>.info>.name,.coursebox .content .teachers,.coursebox .content .courseimage,.coursebox .content .coursefile{float:left;width:40%;clear:left}.coursebox>.info>h3.name{margin:5px}.coursebox>.info>.name{padding:0;margin:5px}.coursebox .content .teachers li{padding:0;margin:0;list-style-type:none}.coursebox .enrolmenticons{float:right;padding:3px 0}.coursebox .moreinfo{float:right;padding:3px 0}.coursebox .enrolmenticons img,.coursebox .moreinfo img{margin:0 .2em}.coursebox .content{clear:both}.coursebox .content .summary,.coursebox .content .coursecat{float:right;width:55%}.coursebox .content .coursecat{clear:right;text-align:right}.coursebox.remotecoursebox .remotecourseinfo{float:left;width:40%}.coursebox .content .courseimage img{max-width:100px;max-height:100px}.coursebox .content .coursecat,.coursebox .content .summary,.coursebox .content .courseimage,.coursebox .content .coursefile,.coursebox .content .teachers,.coursebox.remotecoursebox .remotecourseinfo{padding:0;margin:3px 5px}.dir-rtl .coursebox>.info>.name a{padding-right:21px;padding-left:0;background-position:center right}.dir-rtl .coursebox>.info>.name,.dir-rtl .coursebox .teachers,.dir-rtl .coursebox .content .courseimage,.dir-rtl .coursebox .content .coursefile{float:right;clear:right}.dir-rtl .coursebox .enrolmenticons,.dir-rtl .coursebox .moreinfo{float:left}.dir-rtl .coursebox .summary,.dir-rtl .coursebox .coursecat{float:left}.dir-rtl .coursebox .coursecat{clear:left;text-align:left}.coursebox.collapsed{margin-bottom:0}.coursebox.collapsed>.content{display:none}.courses .coursebox.collapsed{padding:3px 0;border:1px solid #eee}.courses .coursebox.even{background-color:#f6f6f6}.courses .coursebox:hover,.course_category_tree .courses>.paging.paging-morelink:hover{background-color:#eee}.course_category_tree .category .numberofcourse{font-size:11.9px}.course_category_tree .category>.info .name{padding:2px 18px;margin:3px;background-image:url([[pix:moodle|t/collapsed_empty]]);background-position:center left;background-repeat:no-repeat}.dir-rtl .course_category_tree .category>.info .name{background-image:url([[pix:moodle|t/collapsed_empty_rtl]]);background-position:center right}.course_category_tree .category.with_children>.info .name{cursor:pointer;background-image:url([[pix:moodle|t/expanded]])}.course_category_tree .category.with_children.collapsed>.info .name{background-image:url([[pix:moodle|t/collapsed]])}.dir-rtl .course_category_tree .category.with_children.collapsed>.info .name{background-image:url([[pix:moodle|t/collapsed_rtl]])}.course_category_tree .category.collapsed>.content{display:none}.course_category_tree .category>.info{min-height:20px;min-height:0;padding:19px;padding:0;margin:3px 0;margin-bottom:20px;margin-bottom:3px;clear:both;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.course_category_tree .category>.info blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.course_category_tree.frontpage-category-names .category>.info{margin:0;background:0;border:0}.course_category_tree .category>.content{padding-left:16px}.dir-rtl .course_category_tree .category>.content{padding-right:16px;padding-left:0}.course_category_tree .subcategories>.paging,.courses>.paging{padding:5px;margin:0;text-align:center}.courses>.paging.paging-morelink,.course_category_tree .subcategories>.paging.paging-morelink{text-align:left}.course_category_tree .paging.paging-morelink a{font-size:11.9px}.dir-rtl .courses>.paging.paging-morelink,.dir-rtl .course_category_tree .paging.paging-morelink{text-align:right}#page-course-index-category .generalbox.info{padding:5px;margin-bottom:15px;border:1px dotted #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}#page-course-index-category .categorypicker{margin:10px 0 20px;text-align:center}.section .activity .moodle-actionmenu .iconsmall{width:16px;width:1rem;height:16px;height:1rem;max-width:none!important;padding:.3em}.filemanager,.filepicker,.file-picker{font-size:11px}.filemanager a,.file-picker a,.filemanager a:hover,.file-picker a:hover{color:#555;text-decoration:none}.filemanager input[type="text"],.file-picker input[type="text"]{width:265px}.filemanager .fp-license td,.file-picker .fp-setlicense td{max-width:265px}.filemanager .fp-license select,.file-picker .fp-setlicense select{max-width:100%}.fp-content-center{display:table-cell;width:100%;height:100%;vertical-align:middle}.fp-content-hidden{visibility:hidden}.yui3-panel-focused{outline:0}#filesskin .yui3-panel-content{display:inline-block;*display:inline;padding-bottom:20px;background:#f2f2f2;border:1px solid #fff;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;*zoom:1;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}#filesskin .yui3-widget-hd{padding:5px;font-size:12px;letter-spacing:1px;color:#333;text-align:center;text-shadow:1px 1px 1px #fff;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border-bottom:1px solid #bbb;-webkit-border-radius:10px 10px 0 0;-moz-border-radius:10px 10px 0 0;border-radius:10px 10px 0 0;filter:dropshadow(color=#ffffff,offx=1,offy=1);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}.fp-panel-button{display:inline-block;*display:inline;padding:3px 20px 2px 20px;margin:10px;text-align:center;background:#fff;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;*zoom:1;-webkit-box-shadow:2px 2px 3px .1px #999;-moz-box-shadow:2px 2px 3px .1px #999;box-shadow:2px 2px 3px .1px #999}.filepicker .moodle-dialogue-wrap .moodle-dialogue-bd{padding:0}#filesskin .file-picker.fp-generallayout{position:relative;width:859px;background:#fff;border:1px solid #ccc;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.file-picker .fp-repo-area{display:inline-block;*display:inline;float:left;width:180px;height:525px;overflow:auto;border-right:1px solid #bbb;*zoom:1}.dir-rtl .file-picker .fp-repo-area{float:right;border-right:0;border-left:1px solid #bbb}.file-picker .fp-repo-items{float:left;width:693px}.dir-rtl .file-picker .fp-repo-items{float:right}.file-picker .fp-navbar{min-height:22px;padding:5px 8px;background:#f2f2f2;border-bottom:1px solid #bbb}.file-picker .fp-content{height:468px;overflow:auto;clear:both;background:#fff}.filepicker.moodle-dialogue-fullscreen .file-picker .fp-content{width:100%;height:100%}.dir-rtl .file-picker .fp-repo-items{margin-right:181px}.file-picker .fp-content-loading{display:table;width:100%;height:100%;text-align:center}.file-picker .fp-content .fp-object-container{width:98%;height:98%}.dir-rtl .file-picker .fp-list{text-align:right}.dir-rtl .file-picker .fp-toolbar{padding:0}.dir-rtl .file-picker .fp-list{text-align:right}.dir-rtl .file-picker .fp-repo-name{display:inline}.dir-rtl .file-picker .fp-pathbar{display:block;text-align:right;border-top:0}.dir-rtl .file-picker div.bd{text-align:right}.dir-rtl #filemenu .yuimenuitemlabel{text-align:right}.dir-rtl .filepicker .yui-layout-unit-left{left:500px}.dir-rtl .filepicker .yui-layout-unit-center{left:0}.dir-rtl .filemanager-toolbar a{padding:0}.file-picker .fp-list{float:left;width:100%;padding:0;margin:0;list-style-type:none}.dir-rtl .file-picker .fp-list{float:left;text-align:right}.file-picker .fp-list .fp-repo a{display:block;padding:.5em .7em}.file-picker .fp-list .fp-repo.active{background:#f2f2f2}.file-picker .fp-list .fp-repo-icon{padding:0 7px 0 5px}.fp-toolbar{display:table-row;float:left;max-width:70%;line-height:22px}.dir-rtl .fp-toolbar{float:right}.fp-toolbar.empty{display:none}.fp-toolbar .disabled{display:none}.fp-toolbar div{display:inline-block;*display:inline;padding:0 2px;padding-right:10px;*zoom:1}.dir-rtl .fp-toolbar div{width:100px;padding-right:0}.fp-toolbar img{margin-right:5px;vertical-align:-15%}.fp-toolbar .fp-tb-search{width:228px;height:14px}.fp-toolbar .fp-tb-search input{width:200px;height:16px;padding:2px 6px 1px 20px;background:#fff url('[[pix:a/search]]') no-repeat 3px 3px;border:1px solid #bbb}.fp-viewbar{float:right;width:69px;height:22px;margin-right:8px}.dir-rtl .fp-toolbar img{vertical-align:-35%}.dir-rtl .fp-viewbar{float:left;width:100px}.fp-vb-icons{display:inline-block;*display:inline;width:22px;height:22px;background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-icons{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0}.fp-vb-icons.checked{background:url('[[pix:theme|fp/view_icon_selected]]')}.dir-rtl .fp-vb-icons.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_icon_selected]]')}.fp-viewbar.disabled .fp-vb-icons{background:url('[[pix:theme|fp/view_icon_inactive]]')}.fp-vb-details{display:inline-block;*display:inline;width:23px;height:22px;margin-left:-4px;background:url('[[pix:theme|fp/view_list_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-details{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_list_active]]') no-repeat 0 0}.fp-vb-details.checked{background:url('[[pix:theme|fp/view_list_selected]]')}.dir-rtl .fp-vb-details.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_list_selected]]')}.fp-viewbar.disabled .fp-vb-details{background:url('[[pix:theme|fp/view_list_inactive]]')}.fp-vb-tree{display:inline-block;*display:inline;width:23px;height:22px;margin-left:-4px;background:url('[[pix:theme|fp/view_tree_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-tree{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_tree_active]]') no-repeat 0 0}.fp-vb-tree.checked{background:url('[[pix:theme|fp/view_tree_selected]]')}.dir-rtl .fp-vb-tree.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_tree_selected]]')}.fp-viewbar.disabled .fp-vb-tree{background:url('[[pix:theme|fp/view_tree_inactive]]')}.file-picker .fp-clear-left{clear:left}.dir-rtl .filemanager-toolbar .fp-vb-icons a:hover{background:url('[[pix:theme|fp/view_icon_selected]]')}.dir-rtl .filemanager-toolbar .fp-vb-icons.checked a:hover{background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0}.dir-rtl .fp-vb-details a:hover{background:0;border:20px solid black}.dir-rtl .fp-vb-details.checked a:hover{background:0;border:40px solid black}.dir-rtl .fp-vb-tree a:hover{background:0;border:30px solid black}.dir-rtl .fp-vb-tree.checked a:hover{background:0;border:50px solid black}.file-picker .fp-pathbar{display:table-row}.fp-pathbar.empty{display:none}.fp-pathbar .fp-path-folder{width:27px;height:12px;margin-left:4px;background:url('[[pix:theme|fp/path_folder]]') no-repeat 0 0}.dir-rtl .fp-pathbar .fp-path-folder{width:auto;height:12px;margin-left:4px;background:url('[[pix:theme|fp/path_folder_rtl]]') no-repeat right top}.dir-rtl .fp-pathbar span{display:inline-block;*display:inline;float:right;margin-left:32px;*zoom:1}.fp-pathbar .fp-path-folder-name{margin-left:32px;line-height:20px}.dir-rtl .fp-pathbar .fp-path-folder-name{margin-right:32px;line-height:20px}.fp-iconview .fp-file{position:relative;float:left;margin:10px 10px 35px;text-align:center}.fp-iconview .fp-thumbnail{display:block;min-width:110px;min-height:110px;line-height:110px;text-align:center;border:1px solid #fff}.fp-iconview .fp-thumbnail img{padding:3px;vertical-align:middle;border:1px solid #ddd;-webkit-box-shadow:1px 1px 2px 0 #ccc;-moz-box-shadow:1px 1px 2px 0 #ccc;box-shadow:1px 1px 2px 0 #ccc}.fp-iconview .fp-thumbnail:hover{background:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 0 10px 0 #ccc;-moz-box-shadow:inset 0 0 10px 0 #ccc;box-shadow:inset 0 0 10px 0 #ccc}.fp-iconview .fp-filename-field{position:absolute;height:33px;overflow:hidden;word-wrap:break-word}.fp-iconview .fp-filename-field:hover{z-index:1000;overflow:visible}.fp-iconview .fp-filename-field .fp-filename{min-width:112px;padding-top:5px;padding-bottom:12px;background:#fff}.dir-rtl .fp-iconview .fp-file{float:right}.file-picker .yui3-datatable table{width:100%;border:0 solid #bbb}#filesskin .file-picker .yui3-datatable-header{color:#555;background:#fff;border-bottom:1px solid #ccc;border-left:0 solid #fff}#filesskin .file-picker .yui3-datatable-odd .yui3-datatable-cell{background-color:#f6f6f6;border-left:0 solid #f6f6f6}#filesskin .file-picker .yui3-datatable-even .yui3-datatable-cell{background-color:#fff;border-left:0 solid #fff}.dir-rtl .file-picker .yui3-datatable-header{text-align:right}.file-picker .ygtvtn,.filemanager .ygtvtn{width:17px;height:22px;background:url('[[pix:moodle|y/tn]]') 0 0 no-repeat}.dir-rtl .filemanager .ygtvtn,.dir-rtl .file-picker .ygtvtn{width:17px;height:22px;background:url('[[pix:moodle|y/tn_rtl]]') 0 0 no-repeat}.file-picker .ygtvtm,.filemanager .ygtvtm{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tm]]') 0 10px no-repeat}.file-picker .ygtvtmh,.filemanager .ygtvtmh{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tm]]') 0 10px no-repeat}.file-picker .ygtvtp,.filemanager .ygtvtp{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvtp,.dir-rtl .filemanager .ygtvtp{background:url('[[pix:moodle|y/tp_rtl]]') 0 10px no-repeat}.file-picker .ygtvtph,.filemanager .ygtvtph{width:13px;height:22px;cursor:pointer;background:url('[[pix:moodle|y/tp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvtph,.dir-rtl .filemanager .ygtvtph{background:url('[[pix:moodle|y/tp_rtl]]') 0 10px no-repeat}.file-picker .ygtvln,.filemanager .ygtvln{width:17px;height:22px;background:url('[[pix:moodle|y/ln]]') 0 0 no-repeat}.dir-rtl .file-picker .ygtvln,.dir-rtl .filemanager .ygtvln{background:url('[[pix:moodle|y/ln_rtl]]') 0 0 no-repeat}.file-picker .ygtvlm,.filemanager .ygtvlm{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lm]]') 0 10px no-repeat}.file-picker .ygtvlmh,.filemanager .ygtvlmh{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lm]]') 0 10px no-repeat}.file-picker .ygtvlp,.filemanager .ygtvlp{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvlp,.dir-rtl .filemanager .ygtvlp{background:url('[[pix:moodle|y/lp_rtl]]') 0 10px no-repeat}.file-picker .ygtvlph,.filemanager .ygtvlph{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvlph,.dir-rtl .filemanager .ygtvlph{background:url('[[pix:moodle|y/lp_rtl]]') 0 10px no-repeat}.file-picker .ygtvloading,.filemanager .ygtvloading{width:16px;height:22px;background:transparent url('[[pix:moodle|y/loading]]') 0 0 no-repeat}.file-picker .ygtvdepthcell,.filemanager .ygtvdepthcell{width:17px;height:32px;background:url('[[pix:moodle|y/vline]]') 0 0 no-repeat}.file-picker .ygtvblankdepthcell,.filemanager .ygtvblankdepthcell{width:17px;height:22px}a.ygtvspacer:hover{color:transparent;text-decoration:none}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;cursor:pointer;background-color:transparent}.file-picker .ygtvfocus,.filemanager .ygtvfocus{background-color:#eee}.fp-filename-icon{position:relative;display:block;margin-top:10px}.fp-icon{float:left;width:24px;height:24px;margin-top:-7px;margin-right:10px;line-height:24px;text-align:center}.dir-rtl .fp-icon{float:right;margin-right:0;margin-left:10px}.fp-icon img{max-width:24px;max-height:24px;vertical-align:middle}.fp-filename{padding-right:10px}.dir-rtl .fp-filename{padding-right:0;padding-left:10px}.file-picker .fp-login-form{display:table;width:100%;height:100%}.file-picker .fp-login-form table{margin:0 auto}.file-picker .fp-login-form p{margin-top:3em;text-align:center}.file-picker .fp-login-form .fp-login-input label{display:block;text-align:right}.file-picker .fp-login-form .fp-login-input .input{text-align:left}.file-picker .fp-login-form input[type="checkbox"]{width:15px;height:15px}.file-picker .fp-upload-form{display:table;width:100%;height:100%}.file-picker .fp-upload-form table{margin:0 auto}.file-picker.fp-dlg{text-align:center}.file-picker.fp-dlg .fp-dlg-text{padding:30px 20px 10px;font-size:12px}.file-picker.fp-dlg .fp-dlg-buttons{margin:0 20px}.file-picker.fp-msg{text-align:center}.file-picker.fp-msg .fp-msg-text{max-width:500px;max-height:300px;min-width:200px;padding:40px 20px 10px 20px;overflow:auto;font-size:12px}.file-picker.fp-msg.fp-msg-error .fp-msg-text{padding:40px 20px 10px 20px;font-size:12px}.file-picker .fp-content-error{display:table;width:100%;height:100%;text-align:center}.file-picker .fp-content-error .fp-error{display:table-cell;width:100%;height:100%;padding:40px 20px 10px 20px;font-size:12px;vertical-align:middle}.file-picker .fp-nextpage{clear:both}.file-picker .fp-nextpage .fp-nextpage-loading{display:none}.file-picker .fp-nextpage.loading .fp-nextpage-link{display:none}.file-picker .fp-nextpage.loading .fp-nextpage-loading{display:block;height:100px;padding-top:50px;text-align:center}.fp-select form{padding:20px 20px 0}.fp-select .fp-select-loading{margin-top:20px;text-align:center}.fp-select .fp-hr{width:auto;height:1px;margin:10px 0;clear:both;background-color:#fff;border-bottom:1px solid #bbb}.fp-select table{padding:0 0 10px}.fp-select table .mdl-right{min-width:84px}.fp-select .fp-reflist .mdl-right{vertical-align:top}.fp-select .fp-select-buttons{float:right}.fp-select .fp-info{display:block;padding:1px 20px 0;clear:both}.fp-select .fp-thumbnail{float:left;min-width:110px;min-height:110px;margin:10px 20px 0 0;line-height:110px;text-align:center;background:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 0 10px 0 #ccc;-moz-box-shadow:inset 0 0 10px 0 #ccc;box-shadow:inset 0 0 10px 0 #ccc}.fp-select .fp-thumbnail img{padding:3px;margin:10px;vertical-align:middle;border:1px solid #ddd}.fp-select .fp-fileinfo{display:inline-block;*display:inline;margin-top:10px;*zoom:1}.file-picker.fp-select .fp-fileinfo{max-width:240px}.fp-select .fp-fileinfo div{padding-bottom:5px}.file-picker.fp-select .uneditable{display:none}.file-picker.fp-select .fp-select-loading{display:none}.file-picker.fp-select.loading .fp-select-loading{display:block}.file-picker.fp-select.loading form{display:none}.fp-select .fp-dimensions.fp-unknown{display:none}.filemanager-loading{display:none}.jsenabled .filemanager-loading{display:block;margin-top:100px}.filemanager.fm-loading .filemanager-toolbar,.filemanager.fm-loading .fp-pathbar,.filemanager.fm-loading .filemanager-container,.filemanager.fm-loaded .filemanager-loading,.filemanager.fm-maxfiles .fp-btn-add,.filemanager.fm-maxfiles .dndupload-message,.filemanager.fm-noitems .fp-btn-download,.filemanager .fm-empty-container,.filemanager.fm-noitems .filemanager-container .fp-content{display:none}.filemanager .filemanager-updating{display:none;text-align:center}.filemanager.fm-updating .filemanager-updating{display:block;margin-top:37px}.filemanager.fm-updating .fm-content-wrapper,.filemanager.fm-nomkdir .fp-btn-mkdir,.fitem.disabled .filemanager .filemanager-toolbar,.fitem.disabled .filemanager .fp-pathbar,.fitem.disabled .filemanager .fp-restrictions,.fitem.disabled .filemanager .fm-content-wrapper{display:none}.fp-restrictions{text-align:right}.filemanager .fp-navbar{background:#f2f2f2;border:1px solid #bbb;border-bottom:0}.filemanager-toolbar{min-height:22px;padding:5px 8px;overflow:hidden}.fp-pathbar{min-height:20px;padding:5px 8px 1px;border-top:1px solid #bbb}.filemanager .fp-pathbar.empty{display:none}.filepicker-filelist,.filemanager-container{position:relative;min-height:140px;overflow:auto;clear:both;background:#fff;border:1px solid #bbb}.filemanager .fp-content{max-height:472px;min-height:157px;overflow:auto}.filemanager-container,.filepicker-filelist{overflow:hidden}.fitem.disabled .filepicker-filelist,.fitem.disabled .filemanager-container{background-color:#ebebe4}.fitem.disabled .fp-btn-choose{color:#999}.fitem.disabled .filepicker-filelist .filepicker-filename{display:none}.fp-iconview .fp-reficons1{position:absolute;top:0;left:0;width:100%;height:100%}.fp-iconview .fp-reficons2{position:absolute;top:0;left:0;width:100%;height:100%}.fp-iconview .fp-file.fp-hasreferences .fp-reficons1{background:url('[[pix:theme|fp/link]]') no-repeat;background-position:bottom right}.fp-iconview .fp-file.fp-isreference .fp-reficons2{background:url('[[pix:theme|fp/alias]]') no-repeat;background-position:bottom left}.filemanager .fp-iconview .fp-file.fp-originalmissing .fp-thumbnail img{display:none}.filemanager .fp-iconview .fp-file.fp-originalmissing .fp-thumbnail{background:url([[pix:s/dead]]) no-repeat;background-position:center center}.filemanager .yui3-datatable table{width:100%;border:0 solid #bbb}.filemanager .yui3-datatable-header{color:#555!important;background:#fff!important;border-bottom:1px solid #ccc!important;border-left:0 solid #fff!important}.filemanager .yui3-datatable-odd .yui3-datatable-cell{background-color:#f6f6f6!important;border-left:0 solid #f6f6f6}.filemanager .yui3-datatable-even .yui3-datatable-cell{background-color:#fff!important;border-left:0 solid #fff}.filemanager .fp-filename-icon.fp-hasreferences .fp-reficons1{position:absolute;top:8px;left:17px;z-index:1000;width:100%;height:100%;background:url('[[pix:theme|fp/link_sm]]') no-repeat 0 0}.filemanager .fp-filename-icon.fp-isreference .fp-reficons2{position:absolute;top:9px;left:-6px;z-index:1001;width:100%;height:100%;background:url('[[pix:theme|fp/alias_sm]]') no-repeat 0 0}.filemanager .fp-contextmenu{display:none}.filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu{position:absolute;right:7px;bottom:5px;display:block}.filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,.filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu{position:absolute;top:6px;left:14px;display:inline;margin-right:-20px}.dir-rtl .filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu{right:inherit;left:7px}.dir-rtl .filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,.dir-rtl .filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu{right:16px;left:inherit;margin-right:0}.filepicker-filelist .filepicker-container,.filemanager.fm-noitems .fm-empty-container{position:absolute;top:10px;right:10px;bottom:10px;left:10px;display:block;padding-top:85px;text-align:center;border:2px dashed #bbb}.filepicker-filelist .dndupload-target,.filemanager-container .dndupload-target{position:absolute;top:10px;right:10px;bottom:10px;left:10px;padding-top:85px;text-align:center;background:#fff;border:2px dashed #fb7979;-webkit-box-shadow:0 0 0 10px #fff;-moz-box-shadow:0 0 0 10px #fff;box-shadow:0 0 0 10px #fff}.filepicker-filelist.dndupload-over .dndupload-target,.filemanager-container.dndupload-over .dndupload-target{position:absolute;top:10px;right:10px;bottom:10px;left:10px;padding-top:85px;text-align:center;background:#fff;border:2px dashed #6c8cd3}.dndupload-message{display:none}.dndsupported .dndupload-message{display:inline}.dnduploadnotsupported-message{display:none}.dndnotsupported .dnduploadnotsupported-message{display:inline}.dndupload-target{display:none}.dndsupported .dndupload-ready .dndupload-target{display:block}.dndupload-uploadinprogress{display:none;text-align:center}.dndupload-uploading .dndupload-uploadinprogress{display:block}.dndupload-arrow{position:absolute;top:5px;width:100%;height:80px;margin-left:-28px;background:url([[pix:theme|fp/dnd_arrow]]) center no-repeat}.fitem.disabled .filepicker-container,.fitem.disabled .fm-empty-container{display:none}.dndupload-progressbars{display:none;padding:10px}.dndupload-inprogress .dndupload-progressbars{display:block}.dndupload-inprogress .fp-content{display:none}.filemanager.fm-noitems .dndupload-inprogress .fm-empty-container{display:none}.filepicker-filelist.dndupload-inprogress .filepicker-container{display:none}.filepicker-filelist.dndupload-inprogress a{display:none}.filemanager.fp-select .fp-select-loading{display:none}.filemanager.fp-select.loading .fp-select-loading{display:block}.filemanager.fp-select.loading form{display:none}.filemanager.fp-select.fp-folder .fp-license,.filemanager.fp-select.fp-folder .fp-author,.filemanager.fp-select.fp-file .fp-file-unzip,.filemanager.fp-select.fp-folder .fp-file-unzip,.filemanager.fp-select.fp-file .fp-file-zip,.filemanager.fp-select.fp-zip .fp-file-zip{display:none}.filemanager.fp-select .fp-file-setmain{display:none}.filemanager.fp-select.fp-cansetmain .fp-file-setmain{display:inline-block;*display:inline;*zoom:1}.filemanager .fp-mainfile .fp-filename{font-weight:bold}.filemanager.fp-select.fp-folder .fp-file-download{display:none}.fm-operation{font-weight:bold}.filemanager.fp-select .fp-original.fp-unknown,.filemanager.fp-select .fp-original .fp-originloading{display:none}.filemanager.fp-select .fp-original.fp-loading .fp-originloading{display:inline}.filemanager.fp-select .fp-reflist.fp-unknown,.filemanager.fp-select .fp-reflist .fp-reflistloading{display:none}.filemanager.fp-select .fp-refcount{max-width:265px}.filemanager.fp-select .fp-reflist.fp-loading .fp-reflistloading{display:inline}.filemanager.fp-select .fp-reflist .fp-value{max-width:265px;max-height:75px;padding:8px 7px;margin:0;overflow:auto;background:#f9f9f9;border:1px solid #bbb}.filemanager.fp-select .fp-reflist .fp-value li{padding-bottom:7px}.filemanager.fp-mkdir-dlg{text-align:center}.filemanager.fp-mkdir-dlg .fp-mkdir-dlg-text{margin:20px;text-align:left}.dir-rtl .filemanager .fp-mkdir-dlg p{text-align:right}.filemanager.fp-dlg{text-align:center}.filemanager.fp-dlg .fp-dlg-text{max-width:340px;max-height:300px;min-width:200px;padding:0 10px;margin:40px 20px 20px;overflow:auto;font-size:12px;line-height:22px}.file-picker div.bd{text-align:left}.dir-rtl .file-picker div.bd,.dir-rtl .file-picker .fp-pathbar,.dir-rtl .file-picker .fp-list,.dir-rtl #filemenu .yuimenuitemlabel,.dir-rtl .filemanager-container .yui3-skin-sam .yui3-datatable-header{text-align:right}.dir-rtl .filepicker .yui-layout-unit-left{left:500px}.dir-rtl .filepicker .yui-layout-unit-center{left:0}.message-discussion-noframes h1{font-size:1em}.message-discussion-noframes #userinfo .commands,.message .noframesjslink,.message .link{font-size:11.9px}.message .heading{font-size:1em;font-weight:bold}.message .author{font-weight:bold}.message .time{font-style:italic}#page-message-user .commands span{font-size:.7em}#page-message-user .name{font-size:1.1em;font-weight:bold}table.message_search_results td{border-color:#ddd}.message .time,.message.me .author{color:#999}.message.other .author{color:#88c}#page-message-messages{padding:10px}#page-message-send .notifysuccess{padding:1px}#page-message-send td.fixeditor{text-align:center}.message .note{padding:10px}table.message .searchresults td{padding:5px}.message .contactselector{float:left;width:24%}.message .contactselector .contact{text-align:left}.message .contactselector .messageselecteduser{font-weight:bold}.message .contactselector .paging{position:relative;z-index:1}.message .messagearea{float:right;width:74%;min-height:200px;padding-left:1%;border-left:1px solid #d3d3d3}.message .messagearea .messagehistorytype{padding-bottom:20px;clear:both}.message .messagearea .messagehistory .message_user_pictures{margin-right:auto;margin-left:auto}.message .messagearea .messagehistory .message_user_pictures #user1{width:200px;vertical-align:top}.message .messagearea .messagehistory .message_user_pictures #user2{width:200px;vertical-align:top}.message .messagearea .messagehistory .message_user_pictures .useractionlinks{font-size:.9em}.message .messagearea .messagehistory .heading{width:100%;clear:both}.message .messagearea .messagehistory .left{float:left;width:50%;padding-bottom:10px;clear:both}.message .messagearea .messagehistory .right{float:right;width:50%;padding-bottom:10px;clear:both}.message .messagearea .messagehistory .notification{padding:10px;margin-top:5px;background-color:#eee}.message .messagearea .messagesend{padding-top:20px;clear:both}.message .messagearea .messagesend .messagesendbox{width:100%}.message .messagearea .messagesend fieldset{padding:0;margin:0}.message .messagearea .messagerecent{width:100%;text-align:left}.message .messagearea .messagerecent .singlemessage{padding:10px;border-bottom:1px solid #d3d3d3}.message .messagearea .messagerecent .singlemessage .otheruser span{padding:5px}.message .messagearea .messagerecent .singlemessage .messagedate{float:right}.message .hiddenelement{display:none}.message .visible{display:inline}.message #usergroupselector.fieldset,.message #viewing{width:100%}.messagesearchresults{margin-bottom:40px}.messagesearchresults td{padding:0 10px 0 20px}.messagesearchresults td span{white-space:nowrap}.messagesearchresults td img.userpicture{padding-right:.45em;vertical-align:text-bottom}.dir-rtl .messagesearchresults td img.userpicture{padding-right:0;padding-left:.45em}.messagesearchresults td span img{padding:0 0 0 .45em;vertical-align:text-bottom}.dir-rtl .messagesearchresults td span img{padding:0 .45em 0 0}#newmessageoverlay{position:fixed;right:0;bottom:0;padding:20px;background-color:#d3d3d3;border:1px solid black}#newmessageoverlay #usermessage{padding:10px}.questionbank h2{margin-top:0}.questioncategories h3{margin-top:0}#chooseqtypebox{margin-top:1em}#chooseqtype h3{margin:0 0 .3em}#chooseqtype .instruction{display:none}#chooseqtype .fakeqtypes{border-top:1px solid silver}#chooseqtype .qtypeoption{margin-bottom:.5em}#chooseqtype label{display:block}#chooseqtype .qtypename img{padding:0 .3em}#chooseqtype .qtypename{display:inline-table;width:16em}#chooseqtype .qtypesummary{display:block;margin:0 2em}#chooseqtype .submitbuttons{margin:.7em 0;text-align:center}#qtypechoicecontainer{display:none}#qtypechoicecontainer_c.yui-panel-container.shadow .underlay{background:0}#qtypechoicecontainer.yui-panel .hd{letter-spacing:1px;color:#333;text-shadow:1px 1px 1px #fff;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border:1px solid #ccc;border-bottom:1px solid #bbb;-webkit-border-top-right-radius:10px;border-top-right-radius:10px;-webkit-border-top-left-radius:10px;border-top-left-radius:10px;-moz-border-radius-topright:10px;-moz-border-radius-topleft:10px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}#qtypechoicecontainer{font-size:12px;color:#333;background:#f2f2f2;border:1px solid #ccc;border-top:0 none;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}#chooseqtype{width:40em}#chooseqtypehead h3{margin:0;font-weight:normal}#chooseqtype .qtypes{position:relative;padding:.24em 0;border-bottom:1px solid #bbb}#chooseqtype .qtypeoption{padding:.3em .3em .3em 1.6em;margin-bottom:0}#chooseqtype .qtypeoption img{padding-right:.5em;padding-left:1em;vertical-align:text-bottom}#chooseqtype .selected{background-color:#fff;-webkit-box-shadow:0 0 10px 0 #ccc;-moz-box-shadow:0 0 10px 0 #ccc;box-shadow:0 0 10px 0 #ccc}#chooseqtype .instruction,#chooseqtype .qtypesummary{position:absolute;top:0;right:0;bottom:0;left:60%;display:none;padding:1.5em 1.6em;margin:0;overflow-y:auto;background-color:#fff}#chooseqtype .instruction,#chooseqtype .selected .qtypesummary{display:block}#categoryquestions{margin:0}#categoryquestions td,#categoryquestions th{padding:0 .2em}#categoryquestions th{font-weight:normal;text-align:left}#categoryquestions .checkbox{padding-left:20px}.dir-rtl #categoryquestions th{text-align:right}.questionbank .singleselect{margin:0}#combinedfeedbackhdr div.fhtmleditor{padding:0}#combinedfeedbackhdr div.fcheckbox{margin-bottom:1em}#multitriesheader div.fitem_feditor{margin-top:1em}#multitriesheader div.fitem_fgroup{margin-bottom:1em}#multitriesheader div.fitem_fgroup fieldset.felement label{margin-right:.3em;margin-left:.3em}body.path-question-type .fitem_fgroup .accesshide{position:static;left:0;padding-right:.3em;font:inherit}.que{margin:0 auto 1.8em auto;clear:left;text-align:left}.dir-rtl .que{text-align:right}.que .info{float:left;width:7em;padding:.5em;margin-bottom:1.8em;background-color:#eee;border:1px solid #dcdcdc;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.que h2.no{margin:0;font-size:.8em;line-height:1}.que span.qno{font-size:1.5em;font-weight:bold}.que .info>div{margin-top:.7em;font-size:.8em}.que .info .questionflag.editable{cursor:pointer}.que .info .editquestion img,.que .info .questionflag img,.que .info .questionflag input{vertical-align:bottom}.que .content{margin:0 0 0 8.5em}.que .formulation,.que .outcome,.que .comment{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.que .formulation{color:#3a87ad;color:#333;background-color:#d9edf7;border-color:#bce8f1}.formulation input[type="text"],.formulation select{width:auto}.path-mod-quiz input[size]{width:auto}.que .comment{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.que .history{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.que .history blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.que .ablock{margin:.7em 0 .3em 0}.que .im-controls{margin-top:.5em;text-align:left}.dir-rtl .que .im-controls{text-align:right}.que .specificfeedback,.que .generalfeedback,.que .rightanswer,.que .im-feedback,.que .feedback,.que p{margin:0 0 .5em}.que .qtext{margin-bottom:1.5em}.que .correctness{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.que .correctness:empty{display:none}.que .correctness-important{background-color:#b94a48}.que .correctness-important[href]{background-color:#953b39}.que .correctness-warning{background-color:#f89406}.que .correctness-warning[href]{background-color:#c67605}.que .correctness-success{background-color:#468847}.que .correctness-success[href]{background-color:#356635}.que .correctness-info{background-color:#3a87ad}.que .correctness-info[href]{background-color:#2d6987}.que .correctness-inverse{background-color:#333}.que .correctness-inverse[href]{background-color:#1a1a1a}.que .correctness.correct{background-color:#468847}.que .correctness.partiallycorrect{background-color:#f89406}.que .correctness.notanswered,.que .correctness.incorrect{background-color:#b94a48}.que .validationerror{color:#b94a48}.formulation .correct{background-color:#dff0d8}.formulation .partiallycorrect{background-color:#fcf8e3}.formulation .incorrect{background-color:#f2dede}.formulation select.correct,.formulation input.correct{color:#468847;background-color:#dff0d8;border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.correct:focus,.formulation input.correct:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.formulation select.partiallycorrect,.formulation input.partiallycorrect{color:#c09853;background-color:#fcf8e3;border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.partiallycorrect:focus,.formulation input.partiallycorrect:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.formulation select.incorrect,.formulation input.incorrect{color:#b94a48;background-color:#f2dede;border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.incorrect:focus,.formulation input.incorrect:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.que .grading,.que .comment,.que .commentlink,.que .history{margin-top:.5em}.que .history h3{margin:0 0 .2em;font-size:1em}.que .history table{width:100%;margin:0}.que .history .current{font-weight:bold}.que .questioncorrectnessicon{vertical-align:text-bottom}.que input.questionflagimage{padding-right:3px}.dir-rtl .que input.questionflagimage{padding-right:0;padding-left:3px}.importerror{margin-top:10px;border-bottom:1px solid #555}.mform .que.comment .fitemtitle{width:20%}#page-question-preview #techinfo{margin:1em 0}.dir-rtl #chooseqtype .instruction,.dir-rtl #chooseqtype .qtypesummary{right:60%;left:0;border-right:1px solid grey;border-left:0}#page-mod-quiz-edit .questionbankwindow div.header{padding:3px;padding:2px 10px 2px 10px;margin:0 -10px 0 -10px;color:#444;text-shadow:none;background:transparent;-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}#page-mod-quiz-edit .questionbankwindow div.header a:link,#page-mod-quiz-edit .questionbankwindow div.header a:visited{color:#08c}#page-mod-quiz-edit .questionbankwindow div.header a:hover{color:#005580}#page-mod-quiz-edit .questionbankwindow div.header .title{color:#333}#page-mod-quiz-edit div.container div.generalbox{padding:1.5em;background-color:transparent}#page-mod-quiz-edit .categoryinfo{background-color:#fff;border-bottom:0}#page-mod-quiz-edit div.questionbank .categoryquestionscontainer,#page-mod-quiz-edit div.questionbank .categorysortopotionscontainer,#page-mod-quiz-edit div.questionbank .categorypagingbarcontainer,#page-mod-quiz-edit div.questionbank .categoryselectallcontainer{padding:0 0 1.5em 0}#page-mod-quiz-edit div.questionbank .categorypagingbarcontainer{padding:1em;margin:0 -1.2em;background-color:transparent;border-top:0;border-bottom:0}#page-mod-quiz-edit div.questionbank .categoryquestionscontainer{margin:0 -1.2em -1em -1.2em}#page-mod-quiz-edit div.question div.content div.questioncontrols{background-color:#fff}#page-mod-quiz-edit div.question div.content div.points{padding-bottom:.5em;margin-top:-0.5em;background-color:#fff;border:0}#page-mod-quiz-edit div.question div.content div.points label{display:inline-block}#page-mod-quiz-edit div.quizpage .pagecontent .pagestatus{background-color:#fff}#page-mod-quiz-edit .quizpagedelete,#page-mod-quiz-edit .quizpagedelete img{background-color:transparent}#page-mod-quiz-edit div.quizpage .pagecontent{overflow:hidden;border:1px solid #ddd;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}#page-mod-quiz-edit .modulespecificbuttonscontainer{width:220px}.questionbankwindow .module{width:auto}#page-mod-quiz-edit div.editq div.question div.content{overflow:hidden;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.path-mod-quiz .statedetails{display:block;font-size:.9em}a#hidebankcmd{color:#08c}.que.shortanswer .answer{padding:0}.que label{display:inline}.userprofile .fullprofilelink{margin:10px;text-align:center}.userprofile .description{margin-bottom:20px}.userprofile dl.list{*zoom:1}.userprofile dl.list:before,.userprofile dl.list:after{display:table;line-height:0;content:""}.userprofile dl.list:after{clear:both}.userprofile dl.list dt{float:left;width:180px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.userprofile dl.list dd{margin-left:200px}.user-box{float:left;width:115px;height:160px;margin:8px;clear:none;text-align:center}.userlist .action-icon img{vertical-align:middle}.userlist #showall{margin:10px 0}.userlist .buttons{text-align:center}.userlist .buttons label{padding:0 3px}.userlist table#participants{text-align:center}.userlist table#participants td,.userlist table#participants th{padding:4px;text-align:left;vertical-align:middle}.userlist table.controls{width:100%}.userlist table.controls tr{vertical-align:top}.userlist table.controls td.right,.userlist table.controls td.left{padding:4px}.userlist table.controls .right{text-align:right}.userinfobox{width:100%;padding:10px;border:1px solid;border-collapse:separate}.userinfobox .left,.userinfobox .side{width:100px;vertical-align:top}.userinfobox .userpicture{width:100px;height:100px}.userinfobox .content{vertical-align:top}.userinfobox .links{width:100px;padding:5px;vertical-align:bottom}.userinfobox .links a{display:block}.userinfobox .list td{padding:3px}.userinfobox .username{padding-bottom:20px;font-weight:bold}.userinfobox td.label{font-weight:bold;text-align:right;white-space:nowrap;vertical-align:top}.groupinfobox{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.groupinfobox blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.groupinfobox .left{width:100px;padding:10px;vertical-align:top}.course-participation #showall{margin:10px 0;text-align:center}#user-policy .noticebox{width:80%;height:250px;margin-right:auto;margin-bottom:10px;margin-left:auto;text-align:center}#user-policy #policyframe{width:100%;height:100%}.iplookup #map{margin:auto}.userselector select{width:100%}.userselector div{margin-top:.2em}.userselector div label{margin-right:.3em}.userselector .userselector-infobelow{font-size:.8em}#userselector_options{padding:.3em 0}#userselector_options .collapsibleregioncaption{font-weight:bold}#userselector_options p{margin:.2em 0;text-align:left}.dir-rtl #userselector_options p{text-align:right}#page-user-profile .messagebox{margin-right:auto;margin-left:auto;text-align:center}#page-course-view-weeks .messagebox{margin-right:auto;margin-left:auto;text-align:center}.dir-rtl .descriptionbox{margin-right:110px;margin-left:0}.dir-rtl .userlist table#participants td,.dir-rtl .userlist table#participants th{text-align:right}.dir-rtl .userlist table#participants{margin:0 auto}#page-my-index.dir-rtl .block h3{text-align:right}/*!
  * Bootstrap v2.3.0
  *
  * Copyright 2012 Twitter, Inc
index 2a060d1..7c479ef 100644 (file)
@@ -236,15 +236,15 @@ if ($usernew = $userform->get_data()) {
     // save custom profile fields data
     profile_save_data($usernew);
 
-    // If email was changed and confirmation is required, send confirmation email now
+    // If email was changed and confirmation is required, send confirmation email now to the new address.
     if ($email_changed && $CFG->emailchangeconfirmation) {
-        $temp_user = fullclone($user);
+        $temp_user = $DB->get_record('user', array('id'=>$user->id), '*', MUST_EXIST);
         $temp_user->email = $usernew->preference_newemail;
 
         $a = new stdClass();
         $a->url = $CFG->wwwroot . '/user/emailupdate.php?key=' . $usernew->preference_newemailkey . '&id=' . $user->id;
         $a->site = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID)));
-        $a->fullname = fullname($user, true);
+        $a->fullname = fullname($temp_user, true);
 
         $emailupdatemessage = get_string('emailupdatemessage', 'auth', $a);
         $emailupdatetitle = get_string('emailupdatetitle', 'auth', $a);
@@ -256,12 +256,16 @@ if ($usernew = $userform->get_data()) {
         }
     }
 
-    // reload from db
-    $usernew = $DB->get_record('user', array('id'=>$user->id));
+    // Reload from db, we need new full name on this page if we do not redirect.
+    $user = $DB->get_record('user', array('id'=>$user->id), '*', MUST_EXIST);
 
     if ($USER->id == $user->id) {
         // Override old $USER session variable if needed
-        foreach ((array)$usernew as $variable => $value) {
+        foreach ((array)$user as $variable => $value) {
+            if ($variable === 'description' or $variable === 'password') {
+                // These are not set for security nad perf reasons.
+                continue;
+            }
             $USER->$variable = $value;
         }
         // preload custom fields
index 924ebb1..122a4cc 100644 (file)
@@ -240,6 +240,10 @@ if ($usernew = $userform->get_data()) {
     if ($user->id == $USER->id) {
         // Override old $USER session variable
         foreach ((array)$usernew as $variable => $value) {
+            if ($variable === 'description' or $variable === 'password') {
+                // These are not set for security nad perf reasons.
+                continue;
+            }
             $USER->$variable = $value;
         }
         // preload custom fields
index 14acbaa..a8830c7 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2013092700.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2013092700.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.
 
index 1723d72..56d437a 100644 (file)
@@ -69,16 +69,36 @@ class webservice {
             throw new moodle_exception('invalidtoken', 'webservice');
         }
 
+        $loginfaileddefaultparams = array(
+            'other' => array(
+                'method' => WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN,
+                'reason' => null,
+                'tokenid' => $token->id
+            )
+        );
+
         // Validate token date
         if ($token->validuntil and $token->validuntil < time()) {
-            add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '', get_string('invalidtimedtoken', 'webservice'), 0);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'token_expired';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '',
+                get_string('invalidtimedtoken', 'webservice'), 0));
+            $event->trigger();
             $DB->delete_records('external_tokens', array('token' => $token->token));
             throw new webservice_access_exception('Invalid token - token expired - check validuntil time for the token');
         }
 
         // Check ip
         if ($token->iprestriction and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
-            add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '', get_string('failedtolog', 'webservice') . ": " . getremoteaddr(), 0);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'ip_restricted';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '',
+                get_string('failedtolog', 'webservice') . ": " . getremoteaddr(), 0));
+            $event->trigger();
             throw new webservice_access_exception('Invalid token - IP:' . getremoteaddr()
                     . ' is not supported');
         }
@@ -141,19 +161,34 @@ class webservice {
 
         //only confirmed user should be able to call web service
         if (empty($user->confirmed)) {
-            add_to_log(SITEID, 'webservice', 'user unconfirmed', '', $user->username);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_unconfirmed';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', 'user unconfirmed', '', $user->username));
+            $event->trigger();
             throw new moodle_exception('usernotconfirmed', 'moodle', '', $user->username);
         }
 
         //check the user is suspended
         if (!empty($user->suspended)) {
-            add_to_log(SITEID, 'webservice', 'user suspended', '', $user->username);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_suspended';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', 'user suspended', '', $user->username));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for suspended username: ' . $user->username);
         }
 
         //check if the auth method is nologin (in this case refuse connection)
         if ($user->auth == 'nologin') {
-            add_to_log(SITEID, 'webservice', 'nologin auth attempt with web service', '', $user->username);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'nologin';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', 'nologin auth attempt with web service', '', $user->username));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for nologin authentication username: ' . $user->username);
         }
 
@@ -162,7 +197,12 @@ class webservice {
         if (!empty($auth->config->expiration) and $auth->config->expiration == 1) {
             $days2expire = $auth->password_expire($user->username);
             if (intval($days2expire) < 0) {
-                add_to_log(SITEID, 'webservice', 'expired password', '', $user->username);
+                $params = $loginfaileddefaultparams;
+                $params['other']['reason'] = 'password_expired';
+                $event = \core\event\webservice_login_failed::create($params);
+                $event->add_record_snapshot('external_tokens', $token);
+                $event->set_legacy_logdata(array(SITEID, 'webservice', 'expired password', '', $user->username));
+                $event->trigger();
                 throw new moodle_exception('passwordisexpired', 'webservice');
             }
         }
@@ -822,6 +862,15 @@ abstract class webservice_server implements webservice_server_interface {
             throw new coding_exception('Cookies must be disabled in WS servers!');
         }
 
+        $loginfaileddefaultparams = array(
+            'context' => context_system::instance(),
+            'other' => array(
+                'method' => $this->authmethod,
+                'reason' => null,
+                'token' => $this->token
+            )
+        );
+
         if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) {
 
             //we check that authentication plugin is enabled
@@ -845,8 +894,16 @@ abstract class webservice_server implements webservice_server_interface {
             }
 
             if (!$auth->user_login_webservice($this->username, $this->password)) {
-                // log failed login attempts
-                add_to_log(SITEID, 'webservice', get_string('simpleauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".$this->username."/".$this->password." - ".getremoteaddr() , 0);
+
+                // Log failed login attempts.
+                $params = $loginfaileddefaultparams;
+                $params['other']['reason'] = 'password';
+                $params['other']['username'] = $this->username;
+                $event = \core\event\webservice_login_failed::create($params);
+                $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('simpleauthlog', 'webservice'), '' ,
+                    get_string('failedtolog', 'webservice').": ".$this->username."/".$this->password." - ".getremoteaddr() , 0));
+                $event->trigger();
+
                 throw new moodle_exception('wrongusernamepassword', 'webservice');
             }
 
@@ -866,19 +923,37 @@ abstract class webservice_server implements webservice_server_interface {
 
         //only confirmed user should be able to call web service
         if (!empty($user->deleted)) {
-            add_to_log(SITEID, '', '', '', get_string('wsaccessuserdeleted', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_deleted';
+            $params['other']['username'] = $user->username;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserdeleted', 'webservice',
+                $user->username) . " - ".getremoteaddr(), 0, $user->id));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for deleted username: ' . $user->username);
         }
 
         //only confirmed user should be able to call web service
         if (empty($user->confirmed)) {
-            add_to_log(SITEID, '', '', '', get_string('wsaccessuserunconfirmed', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_unconfirmed';
+            $params['other']['username'] = $user->username;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserunconfirmed', 'webservice',
+                $user->username) . " - ".getremoteaddr(), 0, $user->id));
+            $event->trigger();
             throw new moodle_exception('wsaccessuserunconfirmed', 'webservice', '', $user->username);
         }
 
         //check the user is suspended
         if (!empty($user->suspended)) {
-            add_to_log(SITEID, '', '', '', get_string('wsaccessusersuspended', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_unconfirmed';
+            $params['other']['username'] = $user->username;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessusersuspended', 'webservice',
+                $user->username) . " - ".getremoteaddr(), 0, $user->id));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for suspended username: ' . $user->username);
         }
 
@@ -891,14 +966,26 @@ abstract class webservice_server implements webservice_server_interface {
         if (!empty($auth->config->expiration) and $auth->config->expiration == 1) {
             $days2expire = $auth->password_expire($user->username);
             if (intval($days2expire) < 0 ) {
-                add_to_log(SITEID, '', '', '', get_string('wsaccessuserexpired', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+                $params = $loginfaileddefaultparams;
+                $params['other']['reason'] = 'password_expired';
+                $params['other']['username'] = $user->username;
+                $event = \core\event\webservice_login_failed::create($params);
+                $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserexpired', 'webservice',
+                    $user->username) . " - ".getremoteaddr(), 0, $user->id));
+                $event->trigger();
                 throw new webservice_access_exception('Refused web service access for password expired username: ' . $user->username);
             }
         }
 
         //check if the auth method is nologin (in this case refuse connection)
         if ($user->auth=='nologin') {
-            add_to_log(SITEID, '', '', '', get_string('wsaccessusernologin', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'login';
+            $params['other']['username'] = $user->username;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessusernologin', 'webservice',
+                $user->username) . " - ".getremoteaddr(), 0, $user->id));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for nologin authentication username: ' . $user->username);
         }
 
@@ -923,9 +1010,24 @@ abstract class webservice_server implements webservice_server_interface {
      */
     protected function authenticate_by_token($tokentype){
         global $DB;
+
+        $loginfaileddefaultparams = array(
+            'context' => context_system::instance(),
+            'other' => array(
+                'method' => $this->authmethod,
+                'reason' => null,
+                'token' => $this->token
+            )
+        );
+
         if (!$token = $DB->get_record('external_tokens', array('token'=>$this->token, 'tokentype'=>$tokentype))) {
-            // log failed login attempts
-            add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".$this->token. " - ".getremoteaddr() , 0);
+            // Log failed login attempts.
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'invalid_token';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' ,
+                get_string('failedtolog', 'webservice').": ".$this->token. " - ".getremoteaddr() , 0));
+            $event->trigger();
             throw new moodle_exception('invalidtoken', 'webservice');
         }
 
@@ -942,7 +1044,14 @@ abstract class webservice_server implements webservice_server_interface {
         }
 
         if ($token->iprestriction and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
-            add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".getremoteaddr() , 0);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'ip_restricted';
+            $params['other']['tokenid'] = $token->id;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' ,
+                get_string('failedtolog', 'webservice').": ".getremoteaddr() , 0));
+            $event->trigger();
             throw new webservice_access_exception('Invalid service - IP:' . getremoteaddr()
                     . ' is not supported - check this allowed user');
         }
@@ -1055,8 +1164,15 @@ abstract class webservice_zend_server extends webservice_server {
         // tell server what functions are available
         $this->zend_server->setClass($this->service_class);
 
-        //log the web service request
-        add_to_log(SITEID, 'webservice', '', '' , $this->zend_class." ".getremoteaddr() , 0, $this->userid);
+        // Log the web service request.
+        $params = array(
+            'other' => array(
+                'function' => 'unknown'
+            )
+        );
+        $event = \core\event\webservice_function_called::create($params);
+        $event->set_legacy_logdata(array(SITEID, 'webservice', '', '', $this->zend_class.' '.getremoteaddr(), 0, $this->userid));
+        $event->trigger();
 
         //send headers
         $this->send_headers();
@@ -1516,8 +1632,15 @@ abstract class webservice_base_server extends webservice_server {
         // find all needed function info and make sure user may actually execute the function
         $this->load_function_info();
 
-        //log the web service request
-        add_to_log(SITEID, 'webservice', $this->functionname, '' , getremoteaddr() , 0, $this->userid);
+        // Log the web service request.
+        $params = array(
+            'other' => array(
+                'function' => $this->functionname
+            )
+        );
+        $event = \core\event\webservice_function_called::create($params);
+        $event->set_legacy_logdata(array(SITEID, 'webservice', $this->functionname, '' , getremoteaddr() , 0, $this->userid));
+        $event->trigger();
 
         // finally, execute the function - any errors are catched by the default exception handler
         $this->execute();
diff --git a/webservice/tests/events.php b/webservice/tests/events.php
new file mode 100644 (file)
index 0000000..b196100
--- /dev/null
@@ -0,0 +1,342 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit tests for Web service events.
+ *
+ * @package    webservice
+ * @category   phpunit
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Unit tests for Web service events.
+ *
+ * @package    webservice
+ * @category   phpunit
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_events_testcase extends advanced_testcase {
+
+    public function setUp() {
+        $this->resetAfterTest();
+    }
+
+    public function test_function_called() {
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $fakelogdata = array(1, 'B', true, null);
+        $params = array(
+            'other' => array(
+                'function' => 'A function'
+            )
+        );
+        $event = \core\event\webservice_function_called::create($params);
+        $event->set_legacy_logdata($fakelogdata);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals('A function', $event->other['function']);
+        $this->assertEventLegacyLogData($fakelogdata, $event);
+    }
+
+    public function test_login_failed() {
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $fakelogdata = array(1, 'B', true, null);
+        $params = array(
+            'other' => array(
+                'reason' => 'Unit Test',
+                'method' => 'Some method',
+                'token' => 'A fake token'
+            )
+        );
+        $event = \core\event\webservice_login_failed::create($params);
+        $event->set_legacy_logdata($fakelogdata);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals($params['other']['reason'], $event->other['reason']);
+        $this->assertEquals($params['other']['method'], $event->other['method']);
+        $this->assertEquals($params['other']['token'], $event->other['token']);
+        $this->assertEventLegacyLogData($fakelogdata, $event);
+    }
+
+    public function test_service_created() {
+        global $CFG, $DB;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        // Creating a fake service.
+        $service = (object) array(
+            'name' => 'Test',
+            'enabled' => 1,
+            'requiredcapability' => '',
+            'restrictedusers' => 0,
+            'component' => null,
+            'timecreated' => time(),
+            'timemodified' => time(),
+            'shortname' => null,
+            'downloadfiles' => 0,
+            'uploadfiles' => 0
+        );
+        $service->id = $DB->insert_record('external_services', $service);
+
+        // Trigger the event.
+        $params = array(
+            'objectid' => $service->id,
+        );
+        $event = \core\event\webservice_service_created::create($params);
+        $event->add_record_snapshot('external_services', $service);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        // Assert that the event contains the right information.
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals($service->id, $event->objectid);
+        $returnurl = $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices";
+        $expected = array(SITEID, 'webservice', 'add', $returnurl, get_string('addservice', 'webservice', $service));
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_service_updated() {
+        global $CFG, $DB;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        // Creating a fake service.
+        $service = (object) array(
+            'name' => 'Test',
+            'enabled' => 1,
+            'requiredcapability' => '',
+            'restrictedusers' => 0,
+            'component' => null,
+            'timecreated' => time(),
+            'timemodified' => time(),
+            'shortname' => null,
+            'downloadfiles' => 0,
+            'uploadfiles' => 0
+        );
+        $service->id = $DB->insert_record('external_services', $service);
+
+        // Trigger the event.
+        $params = array(
+            'objectid' => $service->id,
+        );
+        $event = \core\event\webservice_service_updated::create($params);
+        $event->add_record_snapshot('external_services', $service);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        // Assert that the event contains the right information.
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals($service->id, $event->objectid);
+        $returnurl = $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices";
+        $expected = array(SITEID, 'webservice', 'edit', $returnurl, get_string('editservice', 'webservice', $service));
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_service_deleted() {
+        global $CFG, $DB;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        // Creating a fake service.
+        $service = (object) array(
+            'name' => 'Test',
+            'enabled' => 1,
+            'requiredcapability' => '',
+            'restrictedusers' => 0,
+            'component' => null,
+            'timecreated' => time(),
+            'timemodified' => time(),
+            'shortname' => null,
+            'downloadfiles' => 0,
+            'uploadfiles' => 0
+        );
+        $service->id = $DB->insert_record('external_services', $service);
+
+        // Trigger the event.
+        $params = array(
+            'objectid' => $service->id,
+        );
+        $event = \core\event\webservice_service_deleted::create($params);
+        $event->add_record_snapshot('external_services', $service);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        // Assert that the event contains the right information.
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals($service->id, $event->objectid);
+        $returnurl = $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices";
+        $expected = array(SITEID, 'webservice', 'delete', $returnurl, get_string('deleteservice', 'webservice', $service));
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_service_user_added() {
+        global $CFG;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $params = array(
+            'objectid' => 1,
+            'relateduserid' => 2
+        );
+        $event = \core\event\webservice_service_user_added::create($params);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals(1, $event->objectid);
+        $this->assertEquals(2, $event->relateduserid);
+        $expected = array(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id=' . $params['objectid'],
+            'add', '', $params['relateduserid']);
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_service_user_removed() {
+        global $CFG;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $params = array(
+            'objectid' => 1,
+            'relateduserid' => 2
+        );
+        $event = \core\event\webservice_service_user_removed::create($params);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals(1, $event->objectid);
+        $this->assertEquals(2, $event->relateduserid);
+        $expected = array(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id=' . $params['objectid'],
+            'remove', '', $params['relateduserid']);
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_token_created() {
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $params = array(
+            'objectid' => 1,
+            'relateduserid' => 2,
+            'other' => array(
+                'auto' => true
+            )
+        );
+        $event = \core\event\webservice_token_created::create($params);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals(1, $event->objectid);
+        $this->assertEquals(2, $event->relateduserid);
+        $expected = array(SITEID, 'webservice', 'automatically create user token', '' , 'User ID: ' . 2);
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_token_sent() {
+        $user = $this->getDataGenerator()->create_user();
+        $this->setUser($user);
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $params = array(
+            'objectid' => 1,
+            'other' => array(
+                'auto' => true
+            )
+        );
+        $event = \core\event\webservice_token_sent::create($params);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals(1, $event->objectid);
+        $expected = array(SITEID, 'webservice', 'sending requested user token', '' , 'User ID: ' . $user->id);
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+}