Merge branch 'MDL-39947' of https://github.com/aolley/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 10 Jun 2013 08:19:56 +0000 (16:19 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 10 Jun 2013 08:19:56 +0000 (16:19 +0800)
128 files changed:
auth/cas/auth.php
auth/ldap/auth.php
backup/moodle2/restore_course_task.class.php
backup/moodle2/restore_final_task.class.php
backup/moodle2/restore_root_task.class.php
backup/moodle2/restore_stepslib.php
blocks/badges/block_badges.php
blocks/course_overview/renderer.php
cohort/index.php
config-dist.php
course/edit_form.php
course/externallib.php
course/format/lib.php
course/format/topics/lib.php
course/format/topics/renderer.php
course/format/weeks/lib.php
course/lib.php
course/manage.php
course/renderer.php
course/tests/externallib_test.php
course/view.php
enrol/manual/lib.php
enrol/manual/settings.php
enrol/manual/tests/lib_test.php
grade/edit/tree/grade.php
grade/grading/form/guide/lib.php
grade/grading/form/rubric/lib.php
grade/report/grader/ajax_callbacks.php
grade/report/grader/lib.php
index.php
install/lang/ca_valencia/error.php
install/lang/ca_valencia/install.php
install/lang/it/error.php
install/lang/sr_cr/langconfig.php
install/lang/sr_lt/langconfig.php
lang/en/group.php
lang/en/hub.php
lib/blocklib.php
lib/completionlib.php
lib/datalib.php
lib/db/upgrade.php
lib/dml/oci_native_moodle_database.php
lib/filelib.php
lib/form/dateselector.php
lib/form/yui/dateselector/dateselector.js
lib/moodlelib.php
lib/navigationlib.php
lib/outputlib.php
lib/outputrenderers.php
lib/pagelib.php
lib/portfolio/exporter.php
lib/questionlib.php
lib/tests/completionlib_advanced_test.php [new file with mode: 0644]
lib/tests/completionlib_test.php
lib/tests/datalib_test.php
lib/tests/environment_test.php [new file with mode: 0644]
lib/tests/navigationlib_test.php
lib/tests/weblib_test.php
lib/upgrade.txt
lib/weblib.php
lib/xsendfilelib.php
lib/yui/build/moodle-core-blocks/moodle-core-blocks-debug.js
lib/yui/build/moodle-core-blocks/moodle-core-blocks-min.js
lib/yui/build/moodle-core-blocks/moodle-core-blocks.js
lib/yui/dragdrop/dragdrop.js
lib/yui/src/blocks/build.json
lib/yui/src/blocks/js/blockregion.js [new file with mode: 0644]
lib/yui/src/blocks/js/blocks.js
lib/yui/src/blocks/js/manager.js [new file with mode: 0644]
login/index.php
login/signup.php
mod/assign/gradingbatchoperationsform.php
mod/assign/gradingtable.php
mod/assign/locallib.php
mod/feedback/mapcourse.php
mod/imscp/locallib.php
mod/quiz/startattempt.php
mod/scorm/module.js
mod/scorm/report/basic/lang/en/scormreport_basic.php
mod/scorm/styles.css
notes/edit_form.php
question/engine/datalib.php
question/engine/lib.php
question/format/multianswer/format.php
question/format/xml/format.php
question/type/multianswer/edit_multianswer_form.php
question/type/multianswer/lang/en/qtype_multianswer.php
question/type/multianswer/lib.php [new file with mode: 0644]
question/type/multianswer/questiontype.php
question/type/multianswer/renderer.php
question/type/multichoice/question.php
question/type/multichoice/tests/question_multi_test.php [new file with mode: 0644]
question/type/multichoice/tests/question_single_test.php [moved from question/type/multichoice/tests/question_test.php with 56% similarity]
question/type/numerical/questiontype.php
question/type/questiontypebase.php
report/log/graph.php
report/progress/lib.php
theme/bootstrapbase/config.php
theme/bootstrapbase/layout/columns1.php [new file with mode: 0644]
theme/bootstrapbase/layout/columns2.php [new file with mode: 0644]
theme/bootstrapbase/layout/columns3.php [new file with mode: 0644]
theme/bootstrapbase/layout/embedded.php
theme/bootstrapbase/layout/general.php [deleted file]
theme/bootstrapbase/layout/secure.php [new file with mode: 0644]
theme/bootstrapbase/less/moodle.less
theme/bootstrapbase/less/moodle/core.less
theme/bootstrapbase/less/moodle/filemanager.less
theme/bootstrapbase/less/moodle/modules.less
theme/bootstrapbase/less/moodle/question.less
theme/bootstrapbase/less/moodle/responsive.less
theme/bootstrapbase/renderers/core_renderer.php
theme/bootstrapbase/style/moodle.css
theme/clean/config.php
theme/clean/layout/columns1.php [new file with mode: 0644]
theme/clean/layout/columns2.php [new file with mode: 0644]
theme/clean/layout/columns3.php [new file with mode: 0644]
theme/clean/layout/embedded.php [new file with mode: 0644]
theme/clean/layout/general.php [deleted file]
theme/clean/layout/secure.php [new file with mode: 0644]
theme/clean/lib.php
theme/sky_high/pix/footer-rtl.jpg [deleted file]
theme/sky_high/pix/footer-rtl.png [new file with mode: 0644]
theme/sky_high/pix/footer.png
theme/sky_high/style/admin.css
theme/sky_high/style/pagelayout.css
theme/sky_high/style/report.css
theme/upgrade.txt
version.php

index 7e8e5d0..95ab725 100644 (file)
@@ -174,7 +174,7 @@ class auth_plugin_cas extends auth_plugin_ldap {
      *
      */
     function connectCAS() {
-        global $PHPCAS_CLIENT;
+        global $CFG, $PHPCAS_CLIENT;
 
         if (!is_object($PHPCAS_CLIENT)) {
             // Make sure phpCAS doesn't try to start a new PHP session when connecting to the CAS server.
@@ -185,6 +185,27 @@ class auth_plugin_cas extends auth_plugin_ldap {
             }
         }
 
+        // If Moodle is configured to use a proxy, phpCAS needs some curl options set.
+        if (!empty($CFG->proxyhost) && !is_proxybypass($this->config->hostname)) {
+            phpCAS::setExtraCurlOption(CURLOPT_PROXY, $CFG->proxyhost);
+            if (!empty($CFG->proxyport)) {
+                phpCAS::setExtraCurlOption(CURLOPT_PROXYPORT, $CFG->proxyport);
+            }
+            if (!empty($CFG->proxytype)) {
+                // Only set CURLOPT_PROXYTYPE if it's something other than the curl-default http
+                if ($CFG->proxytype == 'SOCKS5') {
+                    phpCAS::setExtraCurlOption(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
+                }
+            }
+            if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) {
+                phpCAS::setExtraCurlOption(CURLOPT_PROXYUSERPWD, $CFG->proxyuser.':'.$CFG->proxypassword);
+                if (defined('CURLOPT_PROXYAUTH')) {
+                    // any proxy authentication if PHP 5.1
+                    phpCAS::setExtraCurlOption(CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM);
+                }
+            }
+        }
+
         if($this->config->certificate_check && $this->config->certificate_path){
             phpCAS::setCasServerCACert($this->config->certificate_path);
         }else{
index d32f6bd..54a987e 100644 (file)
@@ -598,6 +598,8 @@ class auth_plugin_ldap extends auth_plugin_base {
                 if ($user->firstaccess == 0) {
                     $DB->set_field('user', 'firstaccess', time(), array('id'=>$user->id));
                 }
+                $euser = $DB->get_record('user', array('id' => $user->id));
+                events_trigger('user_updated', $euser);
                 return AUTH_CONFIRM_OK;
             }
         } else {
@@ -770,6 +772,8 @@ class auth_plugin_ldap extends auth_plugin_base {
                         $updateuser->auth = 'nologin';
                         $DB->update_record('user', $updateuser);
                         echo "\t"; print_string('auth_dbsuspenduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)); echo "\n";
+                        $euser = $DB->get_record('user', array('id' => $user->id));
+                        events_trigger('user_updated', $euser);
                     }
                 }
             } else {
@@ -795,6 +799,8 @@ class auth_plugin_ldap extends auth_plugin_base {
                     $updateuser->auth = $this->authtype;
                     $DB->update_record('user', $updateuser);
                     echo "\t"; print_string('auth_dbreviveduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)); echo "\n";
+                    $euser = $DB->get_record('user', array('id' => $user->id));
+                    events_trigger('user_updated', $euser);
                 }
             } else {
                 print_string('nouserentriestorevive', 'auth_ldap');
@@ -908,6 +914,8 @@ class auth_plugin_ldap extends auth_plugin_base {
 
                 $id = $DB->insert_record('user', $user);
                 echo "\t"; print_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)); echo "\n";
+                $euser = $DB->get_record('user', array('id' => $user->id));
+                events_trigger('user_created', $euser);
                 if (!empty($this->config->forcechangepassword)) {
                     set_user_preference('auth_forcepasswordchange', 1, $id);
                 }
@@ -978,6 +986,10 @@ class auth_plugin_ldap extends auth_plugin_base {
                     }
                 }
             }
+            if (!empty($updatekeys)) {
+                $euser = $DB->get_record('user', array('id' => $userid));
+                events_trigger('user_updated', $euser);
+            }
         } else {
             return false;
         }
index 5f231e9..74bfef4 100644 (file)
@@ -73,8 +73,20 @@ class restore_course_task extends restore_task {
 
         $this->add_step(new restore_course_legacy_files_step('legacy_files'));
 
-        // Restore course enrolments (plugins and membership). Conditionally prevented for any IMPORT/HUB operation
-        if ($this->plan->get_mode() != backup::MODE_IMPORT && $this->plan->get_mode() != backup::MODE_HUB) {
+        // Deal with enrolment methods and user enrolments.
+        if ($this->plan->get_mode() == backup::MODE_IMPORT) {
+            // No need to do anything with enrolments.
+
+        } else if (!$this->get_setting_value('users') or $this->plan->get_mode() == backup::MODE_HUB) {
+            if ($this->get_target() == backup::TARGET_CURRENT_ADDING or $this->get_target() == backup::TARGET_EXISTING_ADDING) {
+                // Keep current enrolments unchanged.
+            } else {
+                // If no instances yet add default enrol methods the same way as when creating new course in UI.
+                $this->add_step(new restore_default_enrolments_step('default_enrolments'));
+            }
+
+        } else {
+            // Restore course enrolment data.
             $this->add_step(new restore_enrolments_structure_step('course_enrolments', 'enrolments.xml'));
         }
 
index d336631..f4a2d46 100644 (file)
@@ -143,6 +143,9 @@ class restore_final_task extends restore_task {
         $rules[] = new restore_log_rule('course', 'report stats', 'report/stats/index.php?id={course}', '{course}');
         $rules[] = new restore_log_rule('course', 'view section', 'view.php?id={course}&sectionid={course_section}', '{course_section}');
 
+        // module 'grade' rules
+        $rules[] = new restore_log_rule('grade', 'update', 'report/grader/index.php?id={course}', null);
+
         // module 'user' rules
         $rules[] = new restore_log_rule('user', 'view', 'view.php?id={user}&course={course}', '{user}');
         $rules[] = new restore_log_rule('user', 'change password', 'view.php?id={user}&course={course}', '{user}');
index f95a5b9..a0b90b8 100644 (file)
@@ -115,6 +115,7 @@ class restore_root_task extends restore_task {
         $rootenrolmanual = new restore_users_setting('enrol_migratetomanual', base_setting::IS_BOOLEAN, false);
         $rootenrolmanual->set_ui(new backup_setting_ui_checkbox($rootenrolmanual, get_string('rootenrolmanual', 'backup')));
         $rootenrolmanual->get_ui()->set_changeable(enrol_is_enabled('manual'));
+        $rootenrolmanual->get_ui()->set_changeable($changeable);
         $this->add_setting($rootenrolmanual);
         $users->add_dependency($rootenrolmanual);
 
index 8b02dc1..8797ee5 100644 (file)
@@ -477,6 +477,8 @@ class restore_rebuild_course_cache extends restore_execution_step {
 
         // Rebuild cache now that all sections are in place
         rebuild_course_cache($this->get_courseid());
+        cache_helper::purge_by_event('changesincourse');
+        cache_helper::purge_by_event('changesincoursecat');
     }
 }
 
@@ -1623,6 +1625,29 @@ class restore_ras_and_caps_structure_step extends restore_structure_step {
     }
 }
 
+/**
+ * If no instances yet add default enrol methods the same way as when creating new course in UI.
+ */
+class restore_default_enrolments_step extends restore_execution_step {
+    public function define_execution() {
+        global $DB;
+
+        $course = $DB->get_record('course', array('id'=>$this->get_courseid()), '*', MUST_EXIST);
+
+        if ($DB->record_exists('enrol', array('courseid'=>$this->get_courseid(), 'enrol'=>'manual'))) {
+            // Something already added instances, do not add default instances.
+            $plugins = enrol_get_plugins(true);
+            foreach ($plugins as $plugin) {
+                $plugin->restore_sync_course($course);
+            }
+
+        } else {
+            // Looks like a newly created course.
+            enrol_course_updated(true, $course, null);
+        }
+    }
+}
+
 /**
  * This structure steps restores the enrol plugins and their underlying
  * enrolments, performing all the mappings and/or movements required
index 2968a23..2af1c5d 100644 (file)
@@ -52,7 +52,7 @@ class block_badges extends block_base {
         return array(
                 'admin' => false,
                 'site-index' => true,
-                'course-view' => false,
+                'course-view' => true,
                 'mod' => false,
                 'my' => true
         );
@@ -88,8 +88,16 @@ class block_badges extends block_base {
 
         if (empty($CFG->enablebadges)) {
             $this->content->text .= get_string('badgesdisabled', 'badges');
-        } else if ($badges = badges_get_user_badges($USER->id, null, 0, $this->config->numberofbadges)) {
-            $output = $PAGE->get_renderer('core', 'badges');
+            return $this->content;
+        }
+
+        $courseid = $this->page->course->id;
+        if ($courseid == SITEID) {
+            $courseid = null;
+        }
+
+        if ($badges = badges_get_user_badges($USER->id, $courseid, 0, $this->config->numberofbadges)) {
+            $output = $this->page->get_renderer('core', 'badges');
             $this->content->text = $output->print_badges_list($badges, $USER->id, true);
         } else {
             $this->content->text .= get_string('nothingtodisplay', 'block_badges');
index 1ac4e90..bb29569 100644 (file)
@@ -103,6 +103,9 @@ class block_course_overview_renderer extends plugin_renderer_base {
 
             // No need to pass title through s() here as it will be done automatically by html_writer.
             $attributes = array('title' => $course->fullname);
+            if (empty($course->visible)) {
+                $attributes['class'] = 'dimmed';
+            }
             if ($course->id > 0) {
                 $courseurl = new moodle_url('/course/view.php', array('id' => $course->id));
                 $coursefullname = format_string($course->fullname, true, $course->id);
index 38ecfe6..3c31556 100644 (file)
@@ -86,6 +86,7 @@ $search .= html_writer::start_tag('div');
 $search .= html_writer::label(get_string('searchcohort', 'cohort'), 'cohort_search_q'); // No : in form labels!
 $search .= html_writer::empty_tag('input', array('id'=>'cohort_search_q', 'type'=>'text', 'name'=>'search', 'value'=>$searchquery));
 $search .= html_writer::empty_tag('input', array('type'=>'submit', 'value'=>get_string('search', 'cohort')));
+$search .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'contextid', 'value'=>$contextid));
 $search .= html_writer::end_tag('div');
 $search .= html_writer::end_tag('form');
 echo $search;
index 8955f58..1d09a79 100644 (file)
@@ -554,6 +554,11 @@ $CFG->admin = 'admin';
 //=========================================================================
 // 11. BEHAT SUPPORT
 //=========================================================================
+// Behat needs a separate data directory and unique database prefix:
+//
+// $CFG->behat_prefix = 'bht_';
+// $CFG->behat_dataroot = '/home/example/bht_moodledata';
+//
 // Behat uses http://localhost:8000 as default URL to run
 // the acceptance tests, you can override this value.
 // Example:
index 2fc377d..c845331 100644 (file)
@@ -81,7 +81,7 @@ class course_edit_form extends moodleform {
                 $displaylist = coursecat::make_categories_list('moodle/course:create');
                 if (!isset($displaylist[$course->category])) {
                     //always keep current
-                    $displaylist[$course->category] = coursecat::get($course->category)->get_formatted_name();
+                    $displaylist[$course->category] = coursecat::get($course->category, MUST_EXIST, true)->get_formatted_name();
                 }
                 $mform->addElement('select', 'category', get_string('coursecategory'), $displaylist);
                 $mform->addHelpButton('category', 'coursecategory');
@@ -248,7 +248,7 @@ class course_edit_form extends moodleform {
         enrol_course_edit_form($mform, $course, $context);
 
 //--------------------------------------------------------------------------------
-        $mform->addElement('header','groups', get_string('groups', 'group'));
+        $mform->addElement('header','groups', get_string('groupsettingsheader', 'group'));
 
         $choices = array();
         $choices[NOGROUPS] = get_string('groupsnone', 'group');
index c174ce3..75b400c 100644 (file)
@@ -902,9 +902,9 @@ class core_course_external extends external_api {
                                             "users" (int) Include users (default to 0 that is equal to no),
                                             "role_assignments" (int) Include role assignments  (default to 0 that is equal to no),
                                             "comments" (int) Include user comments  (default to 0 that is equal to no),
-                                            "completion_information" (int) Include user course completion information  (default to 0 that is equal to no),
+                                            "userscompletion" (int) Include user course completion information  (default to 0 that is equal to no),
                                             "logs" (int) Include course logs  (default to 0 that is equal to no),
-                                            "histories" (int) Include histories  (default to 0 that is equal to no)'
+                                            "grade_histories" (int) Include histories  (default to 0 that is equal to no)'
                                             ),
                                 'value' => new external_value(PARAM_RAW, 'the value for the option 1 (yes) or 0 (no)'
                             )
@@ -966,9 +966,9 @@ class core_course_external extends external_api {
             'users' => 0,
             'role_assignments' => 0,
             'comments' => 0,
-            'completion_information' => 0,
+            'userscompletion' => 0,
             'logs' => 0,
-            'histories' => 0
+            'grade_histories' => 0
         );
 
         $backupsettings = array();
index a12f187..5723eff 100644 (file)
@@ -235,7 +235,7 @@ abstract class format_base {
             return null;
         }
         if ($this->course === false) {
-            $this->course = $DB->get_record('course', array('id' => $this->courseid));
+            $this->course = get_course($this->courseid);
             $options = $this->get_format_options();
             foreach ($options as $optionname => $optionvalue) {
                 if (!isset($this->course->$optionname)) {
index debe045..71a0452 100644 (file)
@@ -257,6 +257,37 @@ class format_topics extends format_base {
         return $courseformatoptions;
     }
 
+    /**
+     * Adds format options elements to the course/section edit form.
+     *
+     * This function is called from {@link course_edit_form::definition_after_data()}.
+     *
+     * @param MoodleQuickForm $mform form the elements are added to.
+     * @param bool $forsection 'true' if this is a section edit form, 'false' if this is course edit form.
+     * @return array array of references to the added form elements.
+     */
+    public function create_edit_form_elements(&$mform, $forsection = false) {
+        $elements = parent::create_edit_form_elements($mform, $forsection);
+
+        // Increase the number of sections combo box values if the user has increased the number of sections
+        // using the icon on the course page beyond course 'maxsections' or course 'maxsections' has been
+        // reduced below the number of sections already set for the course on the site administration course
+        // defaults page.  This is so that the number of sections is not reduced leaving unintended orphaned
+        // activities / resources.
+        if (!$forsection) {
+            $maxsections = get_config('moodlecourse', 'maxsections');
+            $numsections = $mform->getElementValue('numsections');
+            $numsections = $numsections[0];
+            if ($numsections > $maxsections) {
+                $element = $mform->getElement('numsections');
+                for ($i = $maxsections+1; $i <= $numsections; $i++) {
+                    $element->addOption("$i", $i);
+                }
+            }
+        }
+        return $elements;
+    }
+
     /**
      * Updates format options for a course
      *
index e293a9d..ffc7be6 100644 (file)
@@ -35,6 +35,20 @@ require_once($CFG->dirroot.'/course/format/renderer.php');
  */
 class format_topics_renderer extends format_section_renderer_base {
 
+    /**
+     * Constructor method, calls the parent constructor
+     *
+     * @param moodle_page $page
+     * @param string $target one of rendering target constants
+     */
+    public function __construct(moodle_page $page, $target) {
+        parent::__construct($page, $target);
+
+        // Since format_topics_renderer::section_edit_controls() only displays the 'Set current section' control when editing mode is on
+        // we need to be sure that the link 'Turn editing mode on' is available for a user who does not have any other managing capability.
+        $page->set_other_editing_capability('moodle/course:setcurrentsection');
+    }
+
     /**
      * Generate the starting container html for a list of sections
      * @return string HTML to output.
index 40686d4..fb3b0ee 100644 (file)
@@ -262,6 +262,37 @@ class format_weeks extends format_base {
         return $courseformatoptions;
     }
 
+    /**
+     * Adds format options elements to the course/section edit form.
+     *
+     * This function is called from {@link course_edit_form::definition_after_data()}.
+     *
+     * @param MoodleQuickForm $mform form the elements are added to.
+     * @param bool $forsection 'true' if this is a section edit form, 'false' if this is course edit form.
+     * @return array array of references to the added form elements.
+     */
+    public function create_edit_form_elements(&$mform, $forsection = false) {
+        $elements = parent::create_edit_form_elements($mform, $forsection);
+
+        // Increase the number of sections combo box values if the user has increased the number of sections
+        // using the icon on the course page beyond course 'maxsections' or course 'maxsections' has been
+        // reduced below the number of sections already set for the course on the site administration course
+        // defaults page.  This is so that the number of sections is not reduced leaving unintended orphaned
+        // activities / resources.
+        if (!$forsection) {
+            $maxsections = get_config('moodlecourse', 'maxsections');
+            $numsections = $mform->getElementValue('numsections');
+            $numsections = $numsections[0];
+            if ($numsections > $maxsections) {
+                $element = $mform->getElement('numsections');
+                for ($i = $maxsections+1; $i <= $numsections; $i++) {
+                    $element->addOption("$i", $i);
+                }
+            }
+        }
+        return $elements;
+    }
+
     /**
      * Updates format options for a course
      *
index f1663f7..a5e17f3 100644 (file)
@@ -105,6 +105,9 @@ function make_log_url($module, $url) {
         case 'role':
             $url = '/'.$url;
             break;
+        case 'grade':
+            $url = "/grade/$url";
+            break;
         default:
             $url = "/mod/$module/$url";
             break;
index fbc384d..df8c5f4 100644 (file)
@@ -183,6 +183,7 @@ if ((!empty($moveupcat) or !empty($movedowncat)) and confirm_sesskey()) {
     if ($swapcategory and $movecategory) {
         $DB->set_field('course_categories', 'sortorder', $swapcategory->sortorder, array('id' => $movecategory->id));
         $DB->set_field('course_categories', 'sortorder', $movecategory->sortorder, array('id' => $swapcategory->id));
+        cache_helper::purge_by_event('changesincoursecat');
         add_to_log(SITEID, "category", "move", "editcategory.php?id=$movecategory->id", $movecategory->id);
     }
 
index 0e3da60..9bc279d 100644 (file)
@@ -72,11 +72,11 @@ class core_course_renderer extends plugin_renderer_base {
                 $this->page->course->id == SITEID ||
                 !$this->page->user_is_editing() ||
                 !($context = context_course::instance($this->page->course->id)) ||
-                !has_capability('moodle/course:update', $context) ||
+                !has_capability('moodle/course:manageactivities', $context) ||
                 !course_ajax_enabled($this->page->course) ||
                 !($coursenode = $this->page->settingsnav->find('courseadmin', navigation_node::TYPE_COURSE)) ||
-                !$coursenode->get('editsettings')) {
-            // too late or we are on site page or we could not find the course settings node
+                !($turneditingnode = $coursenode->get('turneditingonoff'))) {
+            // too late or we are on site page or we could not find the adjacent nodes in course settings menu
             // or we are not allowed to edit
             return;
         }
@@ -97,8 +97,13 @@ class core_course_renderer extends plugin_renderer_base {
             $modchoosertogglestring = get_string('modchooserenable', 'moodle');
             $modchoosertoggleurl->param('modchooser', 'on');
         }
-        $modchoosertoggle = navigation_node::create($modchoosertogglestring, $modchoosertoggleurl, navigation_node::TYPE_SETTING);
-        $coursenode->add_node($modchoosertoggle, 'editsettings');
+        $modchoosertoggle = navigation_node::create($modchoosertogglestring, $modchoosertoggleurl, navigation_node::TYPE_SETTING, null, 'modchoosertoggle');
+
+        // Insert the modchoosertoggle after the settings node 'turneditingonoff' (navigation_node only has function to insert before, so we insert before and then swap).
+        $coursenode->add_node($modchoosertoggle, 'turneditingonoff');
+        $turneditingnode->remove();
+        $coursenode->add_node($turneditingnode, 'modchoosertoggle');
+
         $modchoosertoggle->add_class('modchoosertoggle');
         $modchoosertoggle->add_class('visibleifjs');
         user_preference_allow_ajax_update('usemodchooser', PARAM_BOOL);
@@ -369,9 +374,7 @@ class core_course_renderer extends plugin_renderer_base {
         $activities = array(MOD_CLASS_ACTIVITY => array(), MOD_CLASS_RESOURCE => array());
 
         foreach ($modules as $module) {
-            if (!array_key_exists($module->archetype, $activities)) {
-                // System modules cannot be added by user, do not add to dropdown
-            } else if (isset($module->types)) {
+            if (isset($module->types)) {
                 // This module has a subtype
                 // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
                 $subtypes = array();
@@ -381,17 +384,28 @@ class core_course_renderer extends plugin_renderer_base {
                 }
 
                 // Sort module subtypes into the list
+                $activityclass = MOD_CLASS_ACTIVITY;
+                if ($module->archetype == MOD_CLASS_RESOURCE) {
+                    $activityclass = MOD_CLASS_RESOURCE;
+                }
                 if (!empty($module->title)) {
                     // This grouping has a name
-                    $activities[$module->archetype][] = array($module->title => $subtypes);
+                    $activities[$activityclass][] = array($module->title => $subtypes);
                 } else {
                     // This grouping does not have a name
-                    $activities[$module->archetype] = array_merge($activities[$module->archetype], $subtypes);
+                    $activities[$activityclass] = array_merge($activities[$activityclass], $subtypes);
                 }
             } else {
                 // This module has no subtypes
+                $activityclass = MOD_CLASS_ACTIVITY;
+                if ($module->archetype == MOD_ARCHETYPE_RESOURCE) {
+                    $activityclass = MOD_CLASS_RESOURCE;
+                } else if ($module->archetype === MOD_ARCHETYPE_SYSTEM) {
+                    // System modules cannot be added by user, do not add to dropdown
+                    continue;
+                }
                 $link = $module->link->out(true, $urlparams);
-                $activities[$module->archetype][$link] = $module->title;
+                $activities[$activityclass][$link] = $module->title;
             }
         }
 
index 59e0c60..5fdbd41 100644 (file)
@@ -671,7 +671,15 @@ class core_course_external_testcase extends externallib_advanced_testcase {
      * Test update_courses
      */
     public function test_update_courses() {
-        global $DB, $CFG, $USER;
+        global $DB, $CFG, $USER, $COURSE;
+
+        // Get current $COURSE to be able to restore it later (defaults to $SITE). We need this
+        // trick because we are both updating and getting (for testing) course information
+        // in the same request and core_course_external::update_courses()
+        // is overwriting $COURSE all over the time with OLD values, so later
+        // use of get_course() fetches those OLD values instead of the updated ones.
+        // See MDL-39723 for more info.
+        $origcourse = clone($COURSE);
 
         $this->resetAfterTest(true);
 
@@ -724,6 +732,7 @@ class core_course_external_testcase extends externallib_advanced_testcase {
         $courses = array($course1, $course2);
 
         $updatedcoursewarnings = core_course_external::update_courses($courses);
+        $COURSE = $origcourse; // Restore $COURSE. Instead of using the OLD one set by the previous line.
 
         // Check that right number of courses were created.
         $this->assertEquals(0, count($updatedcoursewarnings['warnings']));
index 02ae982..467c390 100644 (file)
 
     $PAGE->set_pagelayout('course');
     $PAGE->set_pagetype('course-view-' . $course->format);
+    $PAGE->set_other_editing_capability('moodle/course:update');
     $PAGE->set_other_editing_capability('moodle/course:manageactivities');
+    $PAGE->set_other_editing_capability('moodle/course:activityvisibility');
+    if (course_format_uses_sections($course->format)) {
+        $PAGE->set_other_editing_capability('moodle/course:sectionvisibility');
+        $PAGE->set_other_editing_capability('moodle/course:movesections');
+    }
 
     // Preload course format renderer before output starts.
     // This is a little hacky but necessary since
             }
         }
 
-        if (has_capability('moodle/course:update', $context)) {
-            if (!empty($section)) {
-                if (!empty($move) and has_capability('moodle/course:movesections', $context) and confirm_sesskey()) {
-                    $destsection = $section + $move;
-                    if (move_section_to($course, $section, $destsection)) {
-                        if ($course->id == SITEID) {
-                            redirect($CFG->wwwroot . '/?redirect=0');
-                        } else {
-                            redirect(course_get_url($course));
-                        }
-                    } else {
-                        echo $OUTPUT->notification('An error occurred while moving a section');
-                    }
+        if (!empty($section) && !empty($move) &&
+                has_capability('moodle/course:movesections', $context) && confirm_sesskey()) {
+            $destsection = $section + $move;
+            if (move_section_to($course, $section, $destsection)) {
+                if ($course->id == SITEID) {
+                    redirect($CFG->wwwroot . '/?redirect=0');
+                } else {
+                    redirect(course_get_url($course));
                 }
+            } else {
+                echo $OUTPUT->notification('An error occurred while moving a section');
             }
         }
     } else {
index ab6f719..10e12e1 100644 (file)
@@ -340,7 +340,7 @@ class enrol_manual_plugin extends enrol_plugin {
             $rs->close();
             unset($instances);
 
-        } else if ($action == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
+        } else if ($action == ENROL_EXT_REMOVED_SUSPENDNOROLES or $action == ENROL_EXT_REMOVED_SUSPEND) {
             $instances = array();
             $sql = "SELECT ue.*, e.courseid, c.id AS contextid
                       FROM {user_enrolments} ue
@@ -355,10 +355,15 @@ class enrol_manual_plugin extends enrol_plugin {
                     $instances[$ue->enrolid] = $DB->get_record('enrol', array('id'=>$ue->enrolid));
                 }
                 $instance = $instances[$ue->enrolid];
-                // Always remove all manually assigned roles here, this may break enrol_self roles but we do not want hardcoded hacks here.
-                role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$ue->contextid, 'component'=>'', 'itemid'=>0), true);
-                $this->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED);
-                $trace->output("suspending expired user $ue->userid in course $instance->courseid", 1);
+                if ($action == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
+                    // Remove all manually assigned roles here, this may break enrol_self roles but we do not want hardcoded hacks here.
+                    role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$ue->contextid, 'component'=>'', 'itemid'=>0), true);
+                    $this->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED);
+                    $trace->output("suspending expired user $ue->userid in course $instance->courseid, roles unassigned", 1);
+                } else {
+                    $this->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED);
+                    $trace->output("suspending expired user $ue->userid in course $instance->courseid, roles kept", 1);
+                }
             }
             $rs->close();
             unset($instances);
index 8905c1f..dbfc766 100644 (file)
@@ -33,6 +33,7 @@ if ($ADMIN->fulltree) {
     //       it describes what should happend when users are not supposed to be enerolled any more.
     $options = array(
         ENROL_EXT_REMOVED_KEEP           => get_string('extremovedkeep', 'enrol'),
+        ENROL_EXT_REMOVED_SUSPEND        => get_string('extremovedsuspend', 'enrol'),
         ENROL_EXT_REMOVED_SUSPENDNOROLES => get_string('extremovedsuspendnoroles', 'enrol'),
         ENROL_EXT_REMOVED_UNENROL        => get_string('extremovedunenrol', 'enrol'),
     );
index 77ffc6b..4f4c6d2 100644 (file)
@@ -304,6 +304,30 @@ class enrol_manual_lib_testcase extends advanced_testcase {
         $this->assertEquals(4, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
         $this->assertEquals(0, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
         $this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$managerrole->id)));
+
+
+        $manualplugin->set_config('expiredaction', ENROL_EXT_REMOVED_SUSPEND);
+        $manualplugin->enrol_user($instance1, $user3->id, $studentrole->id, 0, $now-60);
+        $manualplugin->enrol_user($instance3, $user3->id, $teacherrole->id, 0, $now-60*60);
+        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+        $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+
+        $this->assertEquals(6, $DB->count_records('user_enrolments'));
+        $this->assertEquals(7, $DB->count_records('role_assignments'));
+        $this->assertEquals(5, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
+        $this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_ACTIVE)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance2->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_ACTIVE)));
+
+        $manualplugin->sync($trace, null);
+        $this->assertEquals(6, $DB->count_records('user_enrolments'));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$instance1->id, 'userid'=>$user3->id)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$instance3->id, 'userid'=>$user3->id)));
+        $this->assertEquals(7, $DB->count_records('role_assignments'));
+        $this->assertEquals(5, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
+        $this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_SUSPENDED)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance2->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_SUSPENDED)));
     }
 
     public function test_send_expiry_notifications() {
index 8850622..9287986 100644 (file)
@@ -200,6 +200,18 @@ if ($mform->is_cancelled()) {
         $data->feedback       = $old_grade_grade->feedback;
         $data->feedbackformat = $old_grade_grade->feedbackformat;
     }
+
+    // Only log a grade override if they actually changed the student grade.
+    if ($data->finalgrade != $old_grade_grade->finalgrade) {
+        $url = '/report/grader/index.php?id=' . $course->id;
+
+        $user = $DB->get_record('user', array('id'=>$data->userid), '*', MUST_EXIST);
+        $fullname = fullname($user);
+
+        $info = "{$grade_item->itemname}: $fullname";
+        add_to_log($course->id, 'grade', 'update', $url, $info);
+    }
+
     // update final grade or feedback
     // when we set override grade the first time, it happens here
     $grade_item->update_final_grade($data->userid, $data->finalgrade, 'editgrade', $data->feedback, $data->feedbackformat);
@@ -213,6 +225,19 @@ if ($mform->is_cancelled()) {
             $data->overridden = 0; // checkbox unticked
         }
         $grade_grade->set_overridden($data->overridden);
+
+        if ($data->overridden == 0 && $data->overridden != $old_grade_grade->overridden) {
+            // Log removing an override.
+            // The addition of an override is logged above.
+            // One or the other will happen but never both.
+            $url = '/report/grader/index.php?id=' . $course->id;
+
+            $user = $DB->get_record('user', array('id'=>$data->userid), '*', MUST_EXIST);
+            $fullname = fullname($user);
+
+            $info = "{$grade_item->itemname}: $fullname";
+            add_to_log($course->id, 'grade', 'update', $url, $info);
+        }
     }
 
     if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:hide', $context)) {
index b6b9ec2..c5292ba 100644 (file)
@@ -501,10 +501,16 @@ class gradingform_guide_controller extends gradingform_controller {
             throw new coding_exception('It is the caller\'s responsibility to make sure that the form is actually defined');
         }
 
-        $output = $this->get_renderer($page);
+        // Check if current user is able to see preview
+        $options = $this->get_options();
+        if (empty($options['alwaysshowdefinition']) && !has_capability('moodle/grade:managegradingforms', $page->context))  {
+            return '';
+        }
+
         $criteria = $this->definition->guide_criteria;
         $comments = $this->definition->guide_comment;
-        $options = $this->get_options();
+        $output = $this->get_renderer($page);
+
         $guide = '';
         $guide .= $output->box($this->get_formatted_description(), 'gradingform_guide-description');
         if (has_capability('moodle/grade:managegradingforms', $page->context)) {
index 7f08a4e..ae4f5d5 100644 (file)
@@ -505,15 +505,19 @@ class gradingform_rubric_controller extends gradingform_controller {
             throw new coding_exception('It is the caller\'s responsibility to make sure that the form is actually defined');
         }
 
-        $output = $this->get_renderer($page);
         $criteria = $this->definition->rubric_criteria;
         $options = $this->get_options();
         $rubric = '';
         if (has_capability('moodle/grade:managegradingforms', $page->context)) {
             $showdescription = true;
         } else {
+            if (empty($options['alwaysshowdefinition']))  {
+                // ensure we don't display unless show rubric option enabled
+                return '';
+            }
             $showdescription = $options['showdescriptionstudent'];
         }
+        $output = $this->get_renderer($page);
         if ($showdescription) {
             $rubric .= $output->box($this->get_formatted_description(), 'gradingform_rubric-description');
         }
index f0c7188..b61f579 100644 (file)
@@ -118,6 +118,14 @@ switch ($action) {
                 echo json_encode($json_object);
                 die();
             } else {
+                $url = '/report/grader/index.php?id=' . $course->id;
+
+                $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
+                $fullname = fullname($user);
+
+                $info = "{$grade_item->itemname}: $fullname";
+                add_to_log($course->id, 'grade', 'update', $url, $info);
+
                 $json_object->gradevalue = $finalvalue;
 
                 if ($grade_item->update_final_grade($userid, $finalgrade, 'gradebook', $feedback, FORMAT_MOODLE)) {
index 0734134..f1dd17e 100644 (file)
@@ -297,6 +297,12 @@ class grade_report_grader extends grade_report {
                         }
                     }
 
+                    $url = '/report/grader/index.php?id=' . $this->course->id;
+                    $fullname = fullname($this->users[$userid]);
+
+                    $info = "{$gradeitem->itemname}: $fullname";
+                    add_to_log($this->course->id, 'grade', 'update', $url, $info);
+
                     $gradeitem->update_final_grade($userid, $finalgrade, 'gradebook', $feedback, FORMAT_MOODLE);
 
                     // We can update feedback without reloading the grade item as it doesn't affect grade calculations
index b216a69..ce56de5 100644 (file)
--- a/index.php
+++ b/index.php
@@ -40,6 +40,9 @@
     }
     $PAGE->set_url('/', $urlparams);
     $PAGE->set_course($SITE);
+    $PAGE->set_other_editing_capability('moodle/course:update');
+    $PAGE->set_other_editing_capability('moodle/course:manageactivities');
+    $PAGE->set_other_editing_capability('moodle/course:activityvisibility');
 
     // Prevent caching of this page to stop confusion when changing page after making AJAX changes
     $PAGE->set_cacheable(false);
@@ -89,7 +92,6 @@
     }
 
     $PAGE->set_pagetype('site-index');
-    $PAGE->set_other_editing_capability('moodle/course:manageactivities');
     $PAGE->set_docs_path('');
     $PAGE->set_pagelayout('frontpage');
     $editing = $PAGE->user_is_editing();
 
             echo format_text($summarytext, $section->summaryformat, $summaryformatoptions);
 
-            if ($editing) {
+            if ($editing && has_capability('moodle/course:update', $context)) {
                 $streditsummary = get_string('editsummary');
                 echo "<a title=\"$streditsummary\" ".
                      " href=\"course/editsection.php?id=$section->id\"><img src=\"" . $OUTPUT->pix_url('t/edit') . "\" ".
index 9df0f04..3301110 100644 (file)
@@ -30,5 +30,5 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$string['cannotsavemd5file'] = 'No s\'ha pogut alçar el fitxer md5';
-$string['cannotsavezipfile'] = 'No s\'ha pogut alçar el fitxer zip';
+$string['cannotsavemd5file'] = 'No s\'ha pogut guardar el fitxer md5';
+$string['cannotsavezipfile'] = 'No s\'ha pogut guardar el fitxer zip';
index d8be051..ec61cf9 100644 (file)
 
 defined('MOODLE_INTERNAL') || die();
 
-$string['langdownloaderror'] = 'Dissortadament l\'idioma "{$a}" no està instal·lat. La instal·lació prosseguirà en anglés.';
+$string['clialreadyconfigured'] = 'El fitxer config.php ja existeix, feu servir dmin/cli/install_database.php si voleu instal·lar este lloc web.';
+$string['clialreadyinstalled'] = 'El fitxer config.php ja existeix, feu servir admin/cli/upgrade.php si voleu actualitzar este lloc web.';
+$string['cliinstallheader'] = 'Programa d\'instal·lació de línia d\'ordes de Moodle {$a}';
+$string['langdownloaderror'] = 'Dissortadament l\'idioma "{$a}" no es pot baixar. La instal·lació prosseguirà en anglés.';
 $string['memorylimithelp'] = '<p>El límit de memòria del PHP del vostre servidor actualment està definit en {$a}.</p>
 
 <p>Això pot causar que Moodle tinga problemes de memòria més avant, especialment si teniu molts mòduls habilitats i/o molts usuaris.</p>
@@ -41,14 +44,20 @@ $string['memorylimithelp'] = '<p>El límit de memòria del PHP del vostre servid
 <li>Si teniu accés al fitxer php.ini, podeu canviar el paràmetre <b>memory_limit</b> a 40 MB. Si no hi teniu accés podeu demanar al vostre administrador que ho faça ell.</li>
 <li>En alguns servidors PHP podeu crear un fitxer .htaccess dins del directori de Moodle amb esta línia:
 <p><blockquote>php_value memory_limit 40M</blockquote></p>
-<p>Tanmateix, en alguns servidors això farà que no funcioni <b>cap</b> pàgina PHP (es visualitzaran errors) en el qual cas hauríeu de suprimir el fitxer .htaccess.</p></li>
+<p>Tanmateix, en alguns servidors això farà que no funcione <b>cap</b> pàgina PHP (es visualitzaran errors) en el qual cas hauríeu de suprimir el fitxer .htaccess.</p></li>
 </ol>';
-$string['pathssubdataroot'] = 'Necessiteu un espai on Moodle puga alçar els fitxers penjats. Este directori hauria de tindre permisos de lectura I ESCRIPTURA per a l\'usuari del servidor web (normalment \'nobody\' o \'apache\'), però no cal que siga accessible directament via web. L\'instal·lador provarà de crear-lo si no existeix.';
-$string['phpversionhelp'] = '<p>Moodle necessita la versió de PHP 4.1.0 o posterior.</p>
+$string['pathssubadmindir'] = 'Alguns serveis d\'allotjament web (pocs) utilitzen un URL especial /admin p. ex. per a accedir a un tauler de control o quelcom paregut. Malauradament això entra en conflicte amb la ubicació estàndard de les pàgines d\'administració de Moodle. Podeu arreglar este problema canviant el nom del directori d\'administració de Moodle en la vostra instal·lació i posant el nou nom ací. Per exemple <em>moodleadmin</em>. Això modificarà els enllaços d\'administració de Moodle.';
+$string['pathssubdataroot'] = 'Necessiteu un espai on Moodle puga guardar els fitxers penjats. Este directori hauria de tindre permisos de lectura I ESCRIPTURA per a l\'usuari del servidor web (normalment \'nobody\' o \'apache\'), però no cal que siga accessible directament via web. L\'instal·lador provarà de crear-lo si no existeix.';
+$string['pathssubwwwroot'] = 'L\'adreça web completa on s\'accedirà a Moodle.
+No és possible accedir a Moodle en diferents adreces.
+Si el vostre lloc té múltiples adreces públiques haureu de configurar redireccions permanents per a totes excepte esta.
+Si el vostre lloc és accessible tant des d\'Internet com des d\'una intranet, utilitzeu ací l\'adreça pública i configureu el DNS de manera que els usuaris de la intranet puguen utilitzar també l\'adreça pública.
+Si l\'adreça no és correcta, canvieu l\'URL en el vostre navegador per reiniciar la instal·lació amb un altre valor.';
+$string['phpversionhelp'] = '<p>Moodle necessita una versió de PHP 4.3.0 o 5.1.0 (les versions 5.0.x tenien uns quants problemes coneguts).</p>
 <p>A hores d\'ara esteu utilitzant la versió {$a}.</p>
-<p>Vos caldrà actualitzar el PHP o traslladar Moodle a un ordinador amb una versió de PHP més recent.</p>';
-$string['welcomep20'] = 'Esteu veient esta pàgina perquè heu instal·lat amb èxit i heu executat el paquet <strong>{$a->packname} {$a->packversion}</strong>. Felicitacions!';
-$string['welcomep30'] = 'Esta versió de <strong>{$a->installername}</strong> inclou les aplicacions necessàries per crear un entorn en el qual funcioni <strong>Moodle</strong>:';
+<p>Vos cal actualitzar el PHP o traslladar Moodle a un ordinador amb una versió de PHP més recent.<br />(Si esteu utilitzant la versió 5.0.x, alternativament també podríeu tornar arrere a la 4.4.x)</p>';
+$string['welcomep20'] = 'Esteu veient esta pàgina perquè heu instal·lat amb èxit i heu executat el paquet <strong>{$a->packname} {$a->packversion}</strong>. Felicitacions.';
+$string['welcomep30'] = 'Esta versió de <strong>{$a->installername}</strong> inclou les aplicacions necessàries per crear un entorn en el qual funcione <strong>Moodle</strong>:';
 $string['welcomep50'] = 'L\'ús de totes les aplicacions d\'este paquet és governat per les seues llicències respectives. El paquet <strong>{$a->installername}</strong> complet és
 <a href="http://www.opensource.org/docs/definition_plain.html">codi font obert</a> i es distribueix
 sota llicència <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>.';
index 267e449..61197a5 100644 (file)
@@ -30,6 +30,8 @@
 
 defined('MOODLE_INTERNAL') || die();
 
+$string['cannotcreatedboninstall'] = '<p>Non è possibile creare il database </p> <p>Il database non esiste o l\'utente non è autorizzato a crearlo.</p>
+<p>E\' necessario che l\'amministratore del sito  verifichi  la configurazione del database.</p>';
 $string['cannotcreatelangdir'] = 'Non è possibile creare la cartella lang';
 $string['cannotcreatetempdir'] = 'Non è possibile creare la cartella temp';
 $string['cannotdownloadcomponents'] = 'Non è possibile scaricare componenti.';
index 9e1d4de..1ede2d0 100644 (file)
@@ -30,5 +30,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
+$string['parentlanguage'] = 'en';
 $string['thisdirection'] = 'ltr';
 $string['thislanguage'] = 'Српски';
index c11ac67..01b82fc 100644 (file)
@@ -30,5 +30,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
+$string['parentlanguage'] = 'en';
 $string['thisdirection'] = 'ltr';
 $string['thislanguage'] = 'Srpski';
index 3aabdfc..4edb0a0 100644 (file)
@@ -111,6 +111,7 @@ $string['groupnameexists'] = 'The group name \'{$a}\' already exists in this cou
 $string['groupnotamember'] = 'Sorry, you are not a member of that group';
 $string['groups'] = 'Groups';
 $string['groupscount'] = 'Groups ({$a})';
+$string['groupsettingsheader'] = 'Groups';
 $string['groupsgroupings'] = 'Groups &amp; groupings';
 $string['groupsinselectedgrouping'] = 'Groups in:';
 $string['groupsnone'] = 'No groups';
index 6ee12c8..6a91a6b 100644 (file)
@@ -154,7 +154,6 @@ $string['publisheremail_help'] = 'The publisher email address allows the hub adm
 $string['publishername'] = 'Publisher';
 $string['publishername_help'] = 'The publisher is the person or organisation that is the official publisher of the course.  Unless you are publishing it on behalf of someone else, it will usually be you.';
 $string['publishon'] = 'Publish on';
-$string['publishonmoodleorg'] = 'Publish on MOOCH';
 $string['publishonspecifichub'] = 'Publish on another Hub';
 $string['questionsnumber'] = 'Number of questions ({$a})';
 $string['registeredcourses'] = 'Registered courses';
@@ -192,7 +191,6 @@ $string['share'] = 'Share this course for people to download';
 $string['shared'] = 'Shared';
 $string['shareon'] = 'Upload this course to {$a}';
 $string['shareonhub'] = 'Upload this course to a hub';
-$string['shareonmoodleorg'] = 'Upload this course to MOOCH';
 $string['sharepublication_help'] = 'Uploading this course to a community hub server will enable people to download it and install it on their own Moodle sites.';
 $string['siteadmin'] = 'Administrator';
 $string['siteadmin_help'] = 'The full name of the site administrator.';
index f7ab795..54f08a8 100644 (file)
@@ -341,7 +341,7 @@ class block_manager {
      * output the blocks anyway, so we are not doing wasted effort.)
      *
      * @param string $region a block region that exists on this page.
-     * @param object $output a core_renderer. normally the global $OUTPUT.
+     * @param core_renderer $output a core_renderer. normally the global $OUTPUT.
      * @return boolean Whether there is anything in this region.
      */
     public function region_has_content($region, $output) {
index 389312f..78f9eb8 100644 (file)
@@ -1045,40 +1045,36 @@ class completion_info {
         }
     }
 
+     /**
+     * Return whether or not the course has activities with completion enabled.
+     *
+     * @return boolean true when there is at least one activity with completion enabled.
+     */
+    public function has_activities() {
+        $modinfo = get_fast_modinfo($this->course);
+        foreach ($modinfo->get_cms() as $cm) {
+            if ($cm->completion != COMPLETION_TRACKING_NONE) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Obtains a list of activities for which completion is enabled on the
      * course. The list is ordered by the section order of those activities.
      *
-     * @param array $modinfo For unit testing only, supply the value
-     *   here. Otherwise the method calls get_fast_modinfo
      * @return array Array from $cmid => $cm of all activities with completion enabled,
      *   empty array if none
      */
-    public function get_activities($modinfo=null) {
-        global $DB;
-
-        // Obtain those activities which have completion turned on
-        $withcompletion = $DB->get_records_select('course_modules', 'course='.$this->course->id.
-          ' AND completion<>'.COMPLETION_TRACKING_NONE);
-        if (!$withcompletion) {
-            return array();
-        }
-
-        // Use modinfo to get section order and also add in names
-        if (empty($modinfo)) {
-            $modinfo = get_fast_modinfo($this->course);
-        }
+    public function get_activities() {
+        $modinfo = get_fast_modinfo($this->course);
         $result = array();
-        foreach ($modinfo->sections as $sectioncms) {
-            foreach ($sectioncms as $cmid) {
-                if (array_key_exists($cmid, $withcompletion)) {
-                    $result[$cmid] = $withcompletion[$cmid];
-                    $result[$cmid]->modname = $modinfo->cms[$cmid]->modname;
-                    $result[$cmid]->name    = $modinfo->cms[$cmid]->name;
-                }
+        foreach ($modinfo->get_cms() as $cm) {
+            if ($cm->completion != COMPLETION_TRACKING_NONE) {
+                $result[$cm->id] = $cm;
             }
         }
-
         return $result;
     }
 
index 7db9eba..3f918e8 100644 (file)
@@ -556,6 +556,30 @@ function get_site() {
     }
 }
 
+/**
+ * Gets a course object from database. If the course id corresponds to an
+ * already-loaded $COURSE or $SITE object, then the loaded object will be used,
+ * saving a database query.
+ *
+ * If it reuses an existing object, by default the object will be cloned. This
+ * means you can modify the object safely without affecting other code.
+ *
+ * @param int $courseid Course id
+ * @param bool $clone If true (default), makes a clone of the record
+ * @return stdClass A course object
+ * @throws dml_exception If not found in database
+ */
+function get_course($courseid, $clone = true) {
+    global $DB, $COURSE, $SITE;
+    if (!empty($COURSE->id) && $COURSE->id == $courseid) {
+        return $clone ? clone($COURSE) : $COURSE;
+    } else if (!empty($SITE->id) && $SITE->id == $courseid) {
+        return $clone ? clone($SITE) : $SITE;
+    } else {
+        return $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
+    }
+}
+
 /**
  * Returns list of courses, for whole site, or category
  *
index 64ecd3b..8b2c407 100644 (file)
@@ -2139,6 +2139,9 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2013042300.00);
     }
 
+    // Moodle v2.5.0 release upgrade line.
+    // Put any upgrade step following this.
+
     if ($oldversion < 2013051400.01) {
         // Fix incorrect cc-nc url. Unfortunately the license 'plugins' do
         // not give a mechanism to do this.
@@ -2160,9 +2163,5 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2013051400.01);
     }
 
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
     return true;
 }
index 96f14fc..f146088 100644 (file)
@@ -51,8 +51,6 @@ class oci_native_moodle_database extends moodle_database {
     private $last_error_reporting;
     /** @var To store unique_session_id. Needed for temp tables unique naming.*/
     private $unique_session_id;
-    /** @var To cache locks support along the connection life.*/
-    private $oci_package_installed = null;
 
     /**
      * Detects if all needed PHP stuff installed.
@@ -127,9 +125,6 @@ class oci_native_moodle_database extends moodle_database {
      * @return string null means everything ok, string means problem found.
      */
     public function diagnose() {
-        if (!$this->oci_package_installed()) {
-            return 'Oracle PL/SQL Moodle support packages are not installed! Database administrator has to execute /lib/dml/oci_native_moodle_package.sql script.';
-        }
         return null;
     }
 
@@ -203,6 +198,19 @@ class oci_native_moodle_database extends moodle_database {
             throw new dml_connection_exception($dberr);
         }
 
+        // Make sure moodle package is installed - now required.
+        if (!$this->oci_package_installed()) {
+            try {
+                $this->attempt_oci_package_install();
+            } catch (Exception $e) {
+                // Ignore problems, only the result counts,
+                // admins have to fix it manually if necessary.
+            }
+            if (!$this->oci_package_installed()) {
+                throw new dml_exception('dbdriverproblem', 'Oracle PL/SQL Moodle support package MOODLELIB is not installed! Database administrator has to execute /lib/dml/oci_native_moodle_package.sql script.');
+            }
+        }
+
         // get unique session id, to be used later for temp tables stuff
         $sql = 'SELECT DBMS_SESSION.UNIQUE_SESSION_ID() FROM DUAL';
         $this->query_start($sql, null, SQL_QUERY_AUX);
@@ -1476,21 +1484,11 @@ class oci_native_moodle_database extends moodle_database {
     }
 
     public function sql_bitor($int1, $int2) {
-        // Use the MOODLELIB package if available
-        if ($this->oci_package_installed()) {
-            return 'MOODLELIB.BITOR(' . $int1 . ', ' . $int2 . ')';
-        }
-        // fallback to PHP bool operations, can break if using placeholders
-        return '((' . $int1 . ') + (' . $int2 . ') - ' . $this->sql_bitand($int1, $int2) . ')';
+        return 'MOODLELIB.BITOR(' . $int1 . ', ' . $int2 . ')';
     }
 
     public function sql_bitxor($int1, $int2) {
-        // Use the MOODLELIB package if available
-        if ($this->oci_package_installed()) {
-            return 'MOODLELIB.BITXOR(' . $int1 . ', ' . $int2 . ')';
-        }
-        // fallback to PHP bool operations, can break if using placeholders
-        return '(' . $this->sql_bitor($int1, $int2) . ' - ' . $this->sql_bitand($int1, $int2) . ')';
+        return 'MOODLELIB.BITXOR(' . $int1 . ', ' . $int2 . ')';
     }
 
     /**
@@ -1703,9 +1701,6 @@ class oci_native_moodle_database extends moodle_database {
      * @return bool
      */
     protected function oci_package_installed() {
-        if (isset($this->oci_package_installed)) { // Use cached value if available.
-            return $this->oci_package_installed;
-        }
         $sql = "SELECT 1
                 FROM user_objects
                 WHERE object_type = 'PACKAGE BODY'
@@ -1718,8 +1713,22 @@ class oci_native_moodle_database extends moodle_database {
         $records = null;
         oci_fetch_all($stmt, $records, 0, -1, OCI_FETCHSTATEMENT_BY_ROW);
         oci_free_statement($stmt);
-        $this->oci_package_installed = isset($records[0]) && reset($records[0]) ? true : false;
-        return $this->oci_package_installed;
+        return isset($records[0]) && reset($records[0]) ? true : false;
+    }
+
+    /**
+     * Try to add required moodle package into oracle server.
+     */
+    protected function attempt_oci_package_install() {
+        $sqls = file_get_contents(__DIR__.'/oci_native_moodle_package.sql');
+        $sqls = preg_split('/^\/$/sm', $sqls);
+        foreach ($sqls as $sql) {
+            $sql = trim($sql);
+            if ($sql === '' or $sql === 'SHOW ERRORS') {
+                continue;
+            }
+            $this->change_database_structure($sql);
+        }
     }
 
     /**
@@ -1729,9 +1738,6 @@ class oci_native_moodle_database extends moodle_database {
      * @return void
      */
     public function get_session_lock($rowid, $timeout) {
-        if (!$this->oci_package_installed()) {
-            return;
-        }
         parent::get_session_lock($rowid, $timeout);
 
         $fullname = $this->dbname.'-'.$this->prefix.'-session-'.$rowid;
@@ -1749,9 +1755,6 @@ class oci_native_moodle_database extends moodle_database {
     }
 
     public function release_session_lock($rowid) {
-        if (!$this->oci_package_installed()) {
-            return;
-        }
         if (!$this->used_for_db_sessions) {
             return;
         }
index 0db12ba..d73604a 100644 (file)
@@ -2021,11 +2021,7 @@ function readfile_accel($file, $mimetype, $accelerate) {
     header('Last-Modified: '. gmdate('D, d M Y H:i:s', $lastmodified) .' GMT');
 
     if (is_object($file)) {
-        if (empty($_SERVER['HTTP_RANGE'])) {
-            // Use Etag only when not byteserving,
-            // is it tag of this range or whole file?
-            header('Etag: ' . $file->get_contenthash());
-        }
+        header('Etag: "' . $file->get_contenthash() . '"');
         if (isset($_SERVER['HTTP_IF_NONE_MATCH']) and $_SERVER['HTTP_IF_NONE_MATCH'] === $file->get_contenthash()) {
             header('HTTP/1.1 304 Not Modified');
             return;
@@ -2675,10 +2671,6 @@ function byteserving_send_file($handle, $mimetype, $ranges, $filesize) {
     // better turn off any kind of compression and buffering
     @ini_set('zlib.output_compression', 'Off');
 
-    // Remove Etag because is is not strictly defined for byteserving,
-    // is it tag of this range or whole file?
-    header_remove('Etag');
-
     $chunksize = 1*(1024*1024); // 1MB chunks - must be less than 2MB!
     if ($handle === false) {
         die;
index 1a0e432..f4cb2c5 100644 (file)
@@ -119,12 +119,12 @@ class MoodleQuickForm_date_selector extends MoodleQuickForm_group
         $this->_elements[] = @MoodleQuickForm::createElement('select', 'day', get_string('day', 'form'), $days, $this->getAttributes(), true);
         $this->_elements[] = @MoodleQuickForm::createElement('select', 'month', get_string('month', 'form'), $months, $this->getAttributes(), true);
         $this->_elements[] = @MoodleQuickForm::createElement('select', 'year', get_string('year', 'form'), $years, $this->getAttributes(), true);
+        $this->_elements[] = @MoodleQuickForm::createElement('image', 'calendar', $OUTPUT->pix_url('i/calendar', 'moodle'),
+            array('title' => get_string('calendar', 'calendar'), 'class' => 'visibleifjs'));
         // If optional we add a checkbox which the user can use to turn if on
         if($this->_options['optional']) {
             $this->_elements[] = @MoodleQuickForm::createElement('checkbox', 'enabled', null, get_string('enable'), $this->getAttributes(), true);
         }
-        $this->_elements[] = @MoodleQuickForm::createElement('image', 'calendar', $OUTPUT->pix_url('i/calendar', 'moodle'),
-            array('title' => get_string('calendar', 'calendar'), 'class' => 'visibleifjs'));
         foreach ($this->_elements as $element){
             if (method_exists($element, 'setHiddenLabel')){
                 $element->setHiddenLabel(true);
index 5c48075..e1394f3 100644 (file)
@@ -166,6 +166,7 @@ YUI.add('moodle-form-dateselector', function(Y) {
             if (!this.enablecheckbox.get('checked')) {
                 this.calendarimage.set('disabled', 'disabled');
                 this.calendarimage.setStyle('cursor', 'default');
+                this.release_calendar();
             } else {
                 this.calendarimage.set('disabled', false);
                 this.calendarimage.setStyle('cursor', 'auto');
index 0d396a4..4637875 100644 (file)
@@ -10609,8 +10609,8 @@ function get_performance_info() {
     $info['html'] .= '<span class="included">Included '.$info['includecount'].' files</span> ';
     $info['txt']  .= 'includecount: '.$info['includecount'].' ';
 
-    if (!empty($CFG->early_install_lang)) {
-        // We can not track more performance before installation, sorry.
+    if (!empty($CFG->early_install_lang) or empty($PAGE)) {
+        // We can not track more performance before installation or before PAGE init, sorry.
         return $info;
     }
 
index 7e1576b..cb30e27 100644 (file)
@@ -899,8 +899,9 @@ class navigation_node_collection implements IteratorAggregate {
         $child = $this->get($key, $type);
         if ($child !== false) {
             foreach ($this->collection as $colkey => $node) {
-                if ($node->key == $key && $node->type == $type) {
+                if ($node->key === $key && $node->type == $type) {
                     unset($this->collection[$colkey]);
+                    $this->collection = array_values($this->collection);
                     break;
                 }
             }
@@ -3489,7 +3490,7 @@ class settings_navigation extends navigation_node {
             $coursenode->force_open();
         }
 
-        if (has_capability('moodle/course:update', $coursecontext)) {
+        if ($this->page->user_allowed_editing()) {
             // Add the turn on/off settings
 
             if ($this->page->url->compare(new moodle_url('/course/view.php'), URL_MATCH_BASE)) {
@@ -3509,8 +3510,10 @@ class settings_navigation extends navigation_node {
                 $editurl->param('edit', 'on');
                 $editstring = get_string('turneditingon');
             }
-            $coursenode->add($editstring, $editurl, self::TYPE_SETTING, null, null, new pix_icon('i/edit', ''));
+            $coursenode->add($editstring, $editurl, self::TYPE_SETTING, null, 'turneditingonoff', new pix_icon('i/edit', ''));
+        }
 
+        if (has_capability('moodle/course:update', $coursecontext)) {
             // Add the course settings link
             $url = new moodle_url('/course/edit.php', array('id'=>$course->id));
             $coursenode->add(get_string('editsettings'), $url, self::TYPE_SETTING, null, 'editsettings', new pix_icon('i/settings', ''));
@@ -4079,7 +4082,7 @@ class settings_navigation extends navigation_node {
             $reportfunction($reporttab, $user, $course);
         }
         $anyreport = has_capability('moodle/user:viewuseractivitiesreport', $usercontext);
-        if ($anyreport || ($course->showreports && $currentuser && $forceforcontext)) {
+        if ($anyreport || ($course->showreports && $currentuser)) {
             // Add grade hardcoded grade report if necessary.
             $gradeaccess = false;
             if (has_capability('moodle/grade:viewall', $coursecontext)) {
@@ -4105,7 +4108,6 @@ class settings_navigation extends navigation_node {
         // Check the number of nodes in the report node... if there are none remove the node
         $reporttab->trim_if_empty();
 
-
         // Login as ...
         if (!$user->deleted and !$currentuser && !session_is_loggedinas() && has_capability('moodle/user:loginas', $coursecontext) && !is_siteadmin($user->id)) {
             $url = new moodle_url('/course/loginas.php', array('id'=>$course->id, 'user'=>$user->id, 'sesskey'=>sesskey()));
@@ -4244,7 +4246,7 @@ class settings_navigation extends navigation_node {
         }
         $frontpage->id = 'frontpagesettings';
 
-        if (has_capability('moodle/course:update', $coursecontext)) {
+        if ($this->page->user_allowed_editing()) {
 
             // Add the turn on/off settings
             $url = new moodle_url('/course/view.php', array('id'=>$course->id, 'sesskey'=>sesskey()));
@@ -4256,7 +4258,9 @@ class settings_navigation extends navigation_node {
                 $editstring = get_string('turneditingon');
             }
             $frontpage->add($editstring, $url, self::TYPE_SETTING, null, null, new pix_icon('i/edit', ''));
+        }
 
+        if (has_capability('moodle/course:update', $coursecontext)) {
             // Add the course settings link
             $url = new moodle_url('/admin/settings.php', array('section'=>'frontpagesettings'));
             $frontpage->add(get_string('editsettings'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/settings', ''));
index 414f51d..35282f9 100644 (file)
@@ -325,6 +325,14 @@ class theme_config {
      */
     public $yuicssmodules = array('cssreset', 'cssfonts', 'cssgrids', 'cssbase');
 
+    /**
+     * An associative array of block manipulations that should be made if the user is using an rtl language.
+     * The key is the original block region, and the value is the block region to change to.
+     * This is used when displaying blocks for regions only.
+     * @var array
+     */
+    public $blockrtlmanipulations = array();
+
     /**
      * @var renderer_factory Instance of the renderer_factory implementation
      * we are using. Implementation detail.
@@ -418,7 +426,7 @@ class theme_config {
         $configurable = array('parents', 'sheets', 'parents_exclude_sheets', 'plugins_exclude_sheets', 'javascripts', 'javascripts_footer',
                               'parents_exclude_javascripts', 'layouts', 'enable_dock', 'enablecourseajax', 'supportscssoptimisation',
                               'rendererfactory', 'csspostprocess', 'editor_sheets', 'rarrow', 'larrow', 'hidefromselector', 'doctype',
-                              'yuicssmodules');
+                              'yuicssmodules', 'blockrtlmanipulations');
 
         foreach ($config as $key=>$value) {
             if (in_array($key, $configurable)) {
index 8b27876..0e5c959 100644 (file)
@@ -921,7 +921,7 @@ class core_renderer extends renderer_base {
         $functioncalled = true;
         $courseformat = course_get_format($this->page->course);
         if (($obj = $courseformat->course_content_header()) !== null) {
-            return $courseformat->get_renderer($this->page)->render($obj);
+            return html_writer::div($courseformat->get_renderer($this->page)->render($obj), 'course-content-header');
         }
         return '';
     }
@@ -948,7 +948,7 @@ class core_renderer extends renderer_base {
         require_once($CFG->dirroot.'/course/lib.php');
         $courseformat = course_get_format($this->page->course);
         if (($obj = $courseformat->course_content_footer()) !== null) {
-            return $courseformat->get_renderer($this->page)->render($obj);
+            return html_writer::div($courseformat->get_renderer($this->page)->render($obj), 'course-content-footer');
         }
         return '';
     }
@@ -1228,6 +1228,7 @@ class core_renderer extends renderer_base {
      * @return string the HTML to be output.
      */
     public function blocks_for_region($region) {
+        $region = $this->page->apply_theme_region_manipulations($region);
         $blockcontents = $this->page->blocks->get_content_for_region($region, $this);
         $blocks = $this->page->blocks->get_blocks_for_region($region);
         $lastblock = null;
@@ -2675,10 +2676,13 @@ EOD;
      */
     public function navbar() {
         $items = $this->page->navbar->get_items();
+        $itemcount = count($items);
+        if ($itemcount === 0) {
+            return '';
+        }
 
         $htmlblocks = array();
         // Iterate the navarray and display each node
-        $itemcount = count($items);
         $separator = get_separator();
         for ($i=0;$i < $itemcount;$i++) {
             $item = $items[$i];
@@ -2827,7 +2831,7 @@ EOD;
         $jscode = "(function(){{$jscode}})";
         $this->page->requires->yui_module('node-menunav', $jscode);
         // Build the root nodes as required by YUI
-        $content = html_writer::start_tag('div', array('id'=>'custom_menu_'.$menucount, 'class'=>'yui3-menu yui3-menu-horizontal javascript-disabled'));
+        $content = html_writer::start_tag('div', array('id'=>'custom_menu_'.$menucount, 'class'=>'yui3-menu yui3-menu-horizontal javascript-disabled custom-menu'));
         $content .= html_writer::start_tag('div', array('class'=>'yui3-menu-content'));
         $content .= html_writer::start_tag('ul');
         // Render each child
@@ -3028,6 +3032,146 @@ EOD;
 
         return $str;
     }
+
+    /**
+     * Get the HTML for blocks in the given region.
+     *
+     * @since 2.5.1 2.6
+     * @param string $region The region to get HTML for.
+     * @return string HTML.
+     */
+    public function blocks($region, $classes = array(), $tag = 'aside') {
+        $displayregion = $this->page->apply_theme_region_manipulations($region);
+        $classes = (array)$classes;
+        $classes[] = 'block-region';
+        $attributes = array(
+            'id' => 'block-region-'.preg_replace('#[^a-zA-Z0-9_\-]+#', '-', $displayregion),
+            'class' => join(' ', $classes),
+            'data-blockregion' => $displayregion,
+            'data-droptarget' => '1'
+        );
+        return html_writer::tag($tag, $this->blocks_for_region($region), $attributes);
+    }
+
+    /**
+     * Returns the CSS classes to apply to the body tag.
+     *
+     * @since 2.5.1 2.6
+     * @param array $additionalclasses Any additional classes to apply.
+     * @return string
+     */
+    public function body_css_classes(array $additionalclasses = array()) {
+        // Add a class for each block region on the page.
+        // We use the block manager here because the theme object makes get_string calls.
+        foreach ($this->page->blocks->get_regions() as $region) {
+            $additionalclasses[] = 'has-region-'.$region;
+            if ($this->page->blocks->region_has_content($region, $this)) {
+                $additionalclasses[] = 'used-region-'.$region;
+            } else {
+                $additionalclasses[] = 'empty-region-'.$region;
+            }
+        }
+        foreach ($this->page->layout_options as $option => $value) {
+            if ($value) {
+                $additionalclasses[] = 'layout-option-'.$option;
+            }
+        }
+        $css = $this->page->bodyclasses .' '. join(' ', $additionalclasses);
+        return $css;
+    }
+
+    /**
+     * The ID attribute to apply to the body tag.
+     *
+     * @since 2.5.1 2.6
+     * @return string
+     */
+    public function body_id() {
+        return $this->page->bodyid;
+    }
+
+    /**
+     * Returns HTML attributes to use within the body tag. This includes an ID and classes.
+     *
+     * @since 2.5.1 2.6
+     * @param string|array $additionalclasses Any additional classes to give the body tag,
+     * @return string
+     */
+    public function body_attributes($additionalclasses = array()) {
+        if (!is_array($additionalclasses)) {
+            $additionalclasses = explode(' ', $additionalclasses);
+        }
+        return ' id="'. $this->body_id().'" class="'.$this->body_css_classes($additionalclasses).'"';
+    }
+
+    /**
+     * Gets HTML for the page heading.
+     *
+     * @since 2.5.1 2.6
+     * @param string $tag The tag to encase the heading in. h1 by default.
+     * @return string HTML.
+     */
+    public function page_heading($tag = 'h1') {
+        return html_writer::tag($tag, $this->page->heading);
+    }
+
+    /**
+     * Gets the HTML for the page heading button.
+     *
+     * @since 2.5.1 2.6
+     * @return string HTML.
+     */
+    public function page_heading_button() {
+        return $this->page->button;
+    }
+
+    /**
+     * Returns the Moodle docs link to use for this page.
+     *
+     * @since 2.5.1 2.6
+     * @param string $text
+     * @return string
+     */
+    public function page_doc_link($text = null) {
+        if ($text === null) {
+            $text = get_string('moodledocslink');
+        }
+        $path = page_get_doc_link_path($this->page);
+        if (!$path) {
+            return '';
+        }
+        return $this->doc_link($path, $text);
+    }
+
+    /**
+     * Returns the page heading menu.
+     *
+     * @since 2.5.1 2.6
+     * @return string HTML.
+     */
+    public function page_heading_menu() {
+        return $this->page->headingmenu;
+    }
+
+    /**
+     * Returns the title to use on the page.
+     *
+     * @since 2.5.1 2.6
+     * @return string
+     */
+    public function page_title() {
+        return $this->page->title;
+    }
+
+    /**
+     * Returns the URL for the favicon.
+     *
+     * @since 2.5.1 2.6
+     * @return string The favicon URL
+     */
+    public function favicon() {
+        return $this->pix_url('favicon', 'theme');
+    }
 }
 
 /**
index 9f05f63..19940fb 100644 (file)
@@ -51,7 +51,8 @@ defined('MOODLE_INTERNAL') || die();
  *      the forum or quiz table) that this page belongs to. Will be null
  *      if this page is not within a module.
  * @property-read array $alternativeversions Mime type => object with ->url and ->title.
- * @property-read blocks_manager $blocks The blocks manager object for this page.
+ * @property-read block_manager $blocks The blocks manager object for this page.
+ * @property-read array $blockmanipulations
  * @property-read string $bodyclasses A string to use within the class attribute on the body tag.
  * @property-read string $bodyid A string to use as the id of the body tag.
  * @property-read string $button The HTML to go where the Turn editing on button normally goes.
@@ -637,6 +638,22 @@ class moodle_page {
         return $this->_theme;
     }
 
+    /**
+     * Returns an array of minipulations or false if there are none to make.
+     *
+     * @since 2.5.1 2.6
+     * @return bool|array
+     */
+    protected function magic_get_blockmanipulations() {
+        if (!right_to_left()) {
+            return false;
+        }
+        if (is_null($this->_theme)) {
+            $this->initialise_theme_and_output();
+        }
+        return $this->_theme->blockrtlmanipulations;
+    }
+
     /**
      * Please do not call this method directly, use the ->devicetypeinuse syntax. {@link moodle_page::__get()}.
      * @return string The device type being used.
@@ -1825,4 +1842,18 @@ class moodle_page {
     public function set_popup_notification_allowed($allowed) {
         $this->_popup_notification_allowed = $allowed;
     }
+
+    /**
+     * Returns the block region having made any required theme manipulations.
+     *
+     * @since 2.5.1 2.6
+     * @param string $region
+     * @return string
+     */
+    public function apply_theme_region_manipulations($region) {
+        if ($this->blockmanipulations && isset($this->blockmanipulations[$region])) {
+            return $this->blockmanipulations[$region];
+        }
+        return $region;
+    }
 }
index cc73d37..879f68b 100644 (file)
@@ -835,7 +835,7 @@ class portfolio_exporter {
             if ($f->get_filename() == $skipfile) {
                 continue;
             }
-            $returnfiles[$f->get_filepath() . '/' . $f->get_filename()] = $f;
+            $returnfiles[$f->get_filepath() . $f->get_filename()] = $f;
         }
         return $returnfiles;
     }
index f1c77be..5de7963 100644 (file)
@@ -590,7 +590,8 @@ function question_move_questions_to_category($questionids, $newcategoryid) {
             SELECT q.id, q.qtype, qc.contextid
               FROM {question} q
               JOIN {question_categories} qc ON q.category = qc.id
-             WHERE  q.id $questionidcondition", $params);
+             WHERE  q.id $questionidcondition OR q.parent $questionidcondition",
+             array_merge($params, $params));
     foreach ($questions as $question) {
         if ($newcontextid != $question->contextid) {
             question_bank::get_qtype($question->qtype)->move_files(
diff --git a/lib/tests/completionlib_advanced_test.php b/lib/tests/completionlib_advanced_test.php
new file mode 100644 (file)
index 0000000..e259554
--- /dev/null
@@ -0,0 +1,91 @@
+<?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/>.
+
+/**
+ * Completion lib advanced test case.
+ *
+ * This file contains the advanced test suite for completion lib.
+ *
+ * @package    core_completion
+ * @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();
+
+global $CFG;
+require_once($CFG->libdir.'/completionlib.php');
+
+class completionlib_advanced_testcase extends advanced_testcase {
+
+    function test_get_activities() {
+        global $DB;
+        $this->resetAfterTest(true);
+
+        // Create a course with mixed auto completion data.
+        $course = $this->getDataGenerator()->create_course();
+        $completionauto = array('completion' => COMPLETION_TRACKING_AUTOMATIC);
+        $completionmanual = array('completion' => COMPLETION_TRACKING_MANUAL);
+        $completionnone = array('completion' => COMPLETION_TRACKING_NONE);
+        $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), $completionauto);
+        $page = $this->getDataGenerator()->create_module('page', array('course' => $course->id), $completionauto);
+        $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id), $completionmanual);
+
+        $forum2 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), $completionnone);
+        $page2 = $this->getDataGenerator()->create_module('page', array('course' => $course->id), $completionnone);
+        $data2 = $this->getDataGenerator()->create_module('data', array('course' => $course->id), $completionnone);
+
+        // Create data in another course to make sure it's not considered.
+        $course2 = $this->getDataGenerator()->create_course();
+        $c2forum = $this->getDataGenerator()->create_module('forum', array('course' => $course2->id), $completionauto);
+        $c2page = $this->getDataGenerator()->create_module('page', array('course' => $course2->id), $completionmanual);
+        $c2data = $this->getDataGenerator()->create_module('data', array('course' => $course2->id), $completionnone);
+
+        $c = new completion_info($course);
+        $activities = $c->get_activities();
+        $this->assertEquals(3, count($activities));
+        $this->assertTrue(isset($activities[$forum->cmid]));
+        $this->assertEquals($activities[$forum->cmid]->name, $forum->name);
+        $this->assertTrue(isset($activities[$page->cmid]));
+        $this->assertEquals($activities[$page->cmid]->name, $page->name);
+        $this->assertTrue(isset($activities[$data->cmid]));
+        $this->assertEquals($activities[$data->cmid]->name, $data->name);
+
+        $this->assertFalse(isset($activities[$forum2->cmid]));
+        $this->assertFalse(isset($activities[$page2->cmid]));
+        $this->assertFalse(isset($activities[$data2->cmid]));
+    }
+
+    function test_has_activities() {
+        global $DB;
+        $this->resetAfterTest(true);
+
+        // Create a course with mixed auto completion data.
+        $course = $this->getDataGenerator()->create_course();
+        $course2 = $this->getDataGenerator()->create_course();
+        $completionauto = array('completion' => COMPLETION_TRACKING_AUTOMATIC);
+        $completionnone = array('completion' => COMPLETION_TRACKING_NONE);
+        $c1forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), $completionauto);
+        $c2forum = $this->getDataGenerator()->create_module('forum', array('course' => $course2->id), $completionnone);
+
+        $c1 = new completion_info($course);
+        $c2 = new completion_info($course2);
+
+        $this->assertTrue($c1->has_activities());
+        $this->assertFalse($c2->has_activities());
+    }
+}
index 5092831..2298460 100644 (file)
@@ -514,31 +514,6 @@ WHERE
         $c->internal_set_data($cm, $data);
     }
 
-    function test_get_activities() {
-        global $DB;
-
-        $c = new completion_info((object)array('id'=>42));
-
-        // Try with no activities
-        $DB->expects($this->at(0))
-            ->method('get_records_select')
-            ->with('course_modules', 'course=42 AND completion<>'.COMPLETION_TRACKING_NONE)
-            ->will($this->returnValue(array()));
-        $result = $c->get_activities();
-        $this->assertEquals(array(), $result);
-
-        // Try with an activity (need to fake up modinfo for it as well)
-        $DB->expects($this->at(0))
-            ->method('get_records_select')
-            ->with('course_modules', 'course=42 AND completion<>'.COMPLETION_TRACKING_NONE)
-            ->will($this->returnValue(array(13=>(object)array('id'=>13))));
-        $modinfo = new stdClass;
-        $modinfo->sections = array(array(1, 2, 3), array(12, 13, 14));
-        $modinfo->cms[13] = (object)array('modname'=>'frog', 'name'=>'kermit');
-        $result = $c->get_activities($modinfo);
-        $this->assertEquals(array(13=>(object)array('id'=>13, 'modname'=>'frog', 'name'=>'kermit')), $result);
-    }
-
     // get_tracked_users() cannot easily be tested because it uses
     // get_role_users, so skipping that
 
index cce2090..8a97db4 100644 (file)
@@ -267,4 +267,30 @@ class datalib_testcase extends advanced_testcase {
         get_admins(); // This should make just one query.
         $this->assertEquals($odlread+1, $DB->perf_get_reads());
     }
+
+    public function test_get_course() {
+        global $DB, $PAGE, $SITE;
+
+        $this->resetAfterTest(true);
+
+        // First test course will be current course ($COURSE).
+        $course1obj = $this->getDataGenerator()->create_course(array('shortname' => 'FROGS'));
+        $PAGE->set_course($course1obj);
+
+        // Second test course is not current course.
+        $course2obj = $this->getDataGenerator()->create_course(array('shortname' => 'ZOMBIES'));
+
+        // Check it does not make any queries when requesting the $COURSE/$SITE
+        $before = $DB->perf_get_queries();
+        $result = get_course($course1obj->id);
+        $this->assertEquals($before, $DB->perf_get_queries());
+        $this->assertEquals('FROGS', $result->shortname);
+        $result = get_course($SITE->id);
+        $this->assertEquals($before, $DB->perf_get_queries());
+
+        // Check it makes 1 query to request other courses.
+        $result = get_course($course2obj->id);
+        $this->assertEquals('ZOMBIES', $result->shortname);
+        $this->assertEquals($before + 1, $DB->perf_get_queries());
+    }
 }
diff --git a/lib/tests/environment_test.php b/lib/tests/environment_test.php
new file mode 100644 (file)
index 0000000..9dea45d
--- /dev/null
@@ -0,0 +1,45 @@
+<?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/>.
+
+/**
+ * Moodle environment test.
+ *
+ * @package    core
+ * @category   phpunit
+ * @copyright  2013 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+
+/**
+ * Do standard environment.xml tests.
+ */
+class environment_testcase extends advanced_testcase {
+
+    public function test_environment() {
+        global $CFG;
+
+        require_once($CFG->libdir.'/environmentlib.php');
+        list($envstatus, $environment_results) = check_moodle_environment(normalize_version($CFG->release), ENV_SELECT_RELEASE);
+
+        $this->assertNotEmpty($envstatus);
+        foreach ($environment_results as $environment_result) {
+            $this->assertTrue($environment_result->getStatus(), "Problem detected in environment ($environment_result->part:$environment_result->info), fix all warnings and errors!");
+        }
+    }
+}
index 430ec86..e9157e6 100644 (file)
@@ -60,6 +60,8 @@ class navigation_node_testcase extends basic_testcase {
 
         $this->node = new navigation_node('Test Node');
         $this->node->type = navigation_node::TYPE_SYSTEM;
+        // We add the first child without key. This way we make sure all keys search by comparision is performed using ===
+        $this->node->add('first child without key', null, navigation_node::TYPE_CUSTOM);
         $demo1 = $this->node->add('demo1', $this->inactiveurl, navigation_node::TYPE_COURSE, null, 'demo1', new pix_icon('i/course', ''));
         $demo2 = $this->node->add('demo2', $this->inactiveurl, navigation_node::TYPE_COURSE, null, 'demo2', new pix_icon('i/course', ''));
         $demo3 = $this->node->add('demo3', $this->inactiveurl, navigation_node::TYPE_CATEGORY, null, 'demo3',new pix_icon('i/course', ''));
@@ -251,8 +253,24 @@ class navigation_node_testcase extends basic_testcase {
         $this->assertInstanceOf('navigation_node', $this->node->get('remove2'));
         $this->assertInstanceOf('navigation_node', $remove2->get('remove3'));
 
+        // Remove element and make sure this is no longer a child.
         $this->assertTrue($remove1->remove());
+        $this->assertFalse($this->node->get('remove1'));
+        $this->assertFalse(in_array('remove1', $this->node->get_children_key_list(), true));
+
+        // Make sure that we can insert element after removal
+        $insertelement = navigation_node::create('extra element 4', null, navigation_node::TYPE_CUSTOM, null, 'element4');
+        $this->node->add_node($insertelement, 'remove2');
+        $this->assertNotEmpty($this->node->get('element4'));
+
+        // Remove more elements
         $this->assertTrue($this->node->get('remove2')->remove());
+        $this->assertFalse($this->node->get('remove2'));
+
+        // Make sure that we can add element after removal
+        $this->node->add('extra element 5', null, navigation_node::TYPE_CUSTOM, null, 'element5');
+        $this->assertNotEmpty($this->node->get('element5'));
+
         $this->assertTrue($remove2->get('remove3')->remove());
 
         $this->assertFalse($this->node->get('remove1'));
index 74362a4..8ba4a4d 100644 (file)
@@ -106,6 +106,22 @@ class web_testcase extends advanced_testcase {
             format_text_email('&#x7fd2;&#x7FD2;',FORMAT_HTML));
     }
 
+    function test_obfuscate_email() {
+        $email = 'some.user@example.com';
+        $obfuscated = obfuscate_email($email);
+        $this->assertNotSame($email, $obfuscated);
+        $back = textlib::entities_to_utf8(urldecode($email), true);
+        $this->assertSame($email, $back);
+    }
+
+    function test_obfuscate_text() {
+        $text = 'Žluťoučký koníček 32131';
+        $obfuscated = obfuscate_text($text);
+        $this->assertNotSame($text, $obfuscated);
+        $back = textlib::entities_to_utf8($obfuscated, true);
+        $this->assertSame($text, $back);
+    }
+
     function test_highlight() {
         $this->assertEquals(highlight('good', 'This is good'), 'This is <span class="highlight">good</span>');
         $this->assertEquals(highlight('SpaN', 'span'), '<span class="highlight">span</span>');
index b999955..e33f0c8 100644 (file)
@@ -1,6 +1,11 @@
 This files describes API changes in core libraries and APIs,
 information provided here is intended especially for developers.
 
+=== 2.5.1 ===
+
+* New get_course() function for use when obtaining the course record from database. Will
+  reuse existing $COURSE or $SITE globals if possible to improve performance.
+
 === 2.5 ===
 
 * The database drivers (moodle_database and subclasses) aren't using anymore the ::columns property
index 1985b7e..cd43add 100644 (file)
@@ -909,20 +909,37 @@ function close_window($delay = 0, $reloadopener = false) {
  * @return string The link to user documentation for this current page
  */
 function page_doc_link($text='') {
-    global $CFG, $PAGE, $OUTPUT;
+    global $OUTPUT, $PAGE;
+    $path = page_get_doc_link_path($PAGE);
+    if (!$path) {
+        return '';
+    }
+    return $OUTPUT->doc_link($path, $text);
+}
+
+/**
+ * Returns the path to use when constructing a link to the docs.
+ *
+ * @since 2.5.1 2.6
+ * @global stdClass $CFG
+ * @param moodle_page $page
+ * @return string
+ */
+function page_get_doc_link_path(moodle_page $page) {
+    global $CFG;
 
     if (empty($CFG->docroot) || during_initial_install()) {
         return '';
     }
-    if (!has_capability('moodle/site:doclinks', $PAGE->context)) {
+    if (!has_capability('moodle/site:doclinks', $page->context)) {
         return '';
     }
 
-    $path = $PAGE->docspath;
+    $path = $page->docspath;
     if (!$path) {
         return '';
     }
-    return $OUTPUT->doc_link($path, $text);
+    return $path;
 }
 
 
@@ -2577,19 +2594,20 @@ function redirect($url, $message='', $delay=-1) {
 function obfuscate_text($plaintext) {
 
     $i=0;
-    $length = strlen($plaintext);
+    $length = textlib::strlen($plaintext);
     $obfuscated='';
     $prev_obfuscated = false;
     while ($i < $length) {
-        $c = ord($plaintext{$i});
-        $numerical = ($c >= ord('0')) && ($c <= ord('9'));
+        $char = textlib::substr($plaintext, $i, 1);
+        $ord = textlib::utf8ord($char);
+        $numerical = ($ord >= ord('0')) && ($ord <= ord('9'));
         if ($prev_obfuscated and $numerical ) {
-            $obfuscated.='&#'.ord($plaintext{$i}).';';
+            $obfuscated.='&#'.$ord.';';
         } else if (rand(0,2)) {
-            $obfuscated.='&#'.ord($plaintext{$i}).';';
+            $obfuscated.='&#'.$ord.';';
             $prev_obfuscated = true;
         } else {
-            $obfuscated.=$plaintext{$i};
+            $obfuscated.=$char;
             $prev_obfuscated = false;
         }
       $i++;
index 5c25485..3a563fd 100644 (file)
@@ -68,12 +68,6 @@ function xsendfile($filepath) {
         }
     }
 
-    // Remove Etag because is is not strictly defined for byteserving,
-    // is it tag of this range or whole file?
-    if (!empty($_SERVER['HTTP_RANGE'])) {
-        header_remove('Etag');
-    }
-
     if ($CFG->xsendfile === 'X-LIGHTTPD-send-file') {
         // http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file says 1.4 it does not support byteserving
         header('Accept-Ranges: none');
index 8430a9b..ea694d0 100644 (file)
Binary files a/lib/yui/build/moodle-core-blocks/moodle-core-blocks-debug.js and b/lib/yui/build/moodle-core-blocks/moodle-core-blocks-debug.js differ
index 24f8901..31b92ae 100644 (file)
Binary files a/lib/yui/build/moodle-core-blocks/moodle-core-blocks-min.js and b/lib/yui/build/moodle-core-blocks/moodle-core-blocks-min.js differ
index 8430a9b..bc3bb52 100644 (file)
Binary files a/lib/yui/build/moodle-core-blocks/moodle-core-blocks.js and b/lib/yui/build/moodle-core-blocks/moodle-core-blocks.js differ
index 6d7fd45..b8904bb 100644 (file)
@@ -158,7 +158,7 @@ YUI.add('moodle-core-dragdrop', function(Y) {
                 }
                 //Add the node
                 e.drop.get('node').ancestor().insertBefore(drag, drop);
-            } else if (drop.hasClass(this.parentnodeclass) && !drop.contains(drag)) {
+            } else if ((drop.hasClass(this.parentnodeclass) || drop.test('[data-droptarget="1"]')) && !drop.contains(drag)) {
                 // We are dropping on parent node and it is empty
                 if (this.goingup) {
                     drop.append(drag);
index 41689c9..2644ec9 100644 (file)
@@ -3,7 +3,9 @@
   "builds": {
     "moodle-core-blocks": {
       "jsfiles": [
-        "blocks.js"
+        "blocks.js",
+        "manager.js",
+        "blockregion.js"
       ]
     }
   }
diff --git a/lib/yui/src/blocks/js/blockregion.js b/lib/yui/src/blocks/js/blockregion.js
new file mode 100644 (file)
index 0000000..1d854b7
--- /dev/null
@@ -0,0 +1,216 @@
+/**
+ * This file contains the Block Region class used by the drag and drop manager.
+ *
+ * Provides drag and drop functionality for blocks.
+ *
+ * @module moodle-core-blockdraganddrop
+ */
+
+/**
+ * Constructs a new block region object.
+ *
+ * @namespace M.core.blockdraganddrop
+ * @class BlockRegion
+ * @constructor
+ * @extends Y.Base
+ */
+var BLOCKREGION = function() {
+    BLOCKREGION.superclass.constructor.apply(this, arguments);
+};
+BLOCKREGION.prototype = {
+    /**
+     * Called during the initialisation process of the object.
+     * @method initializer
+     */
+    initializer : function() {
+        var node = this.get('node');
+        Y.log('Block region `'+this.get('region')+'` initialising', 'info');
+        if (!node) {
+            Y.log('block region known about but no HTML structure found for it. Guessing structure.', 'warn');
+            this.create_and_add_node();
+        }
+        var body = Y.one('body'),
+            hasblocks = node.all('.'+CSS.BLOCK).size() > 0,
+            hasregionclass = this.get_has_region_class();
+        this.set('hasblocks', hasblocks);
+        if (!body.hasClass(hasregionclass)) {
+            body.addClass(hasregionclass);
+        }
+        body.addClass((hasblocks) ? this.get_used_region_class() : this.get_empty_region_class());
+        body.removeClass((hasblocks) ? this.get_empty_region_class() : this.get_used_region_class());
+    },
+    /**
+     * Creates a generic block region node and adds it to the DOM at the best guess location.
+     * Any calling of this method is an unfortunate circumstance.
+     * @method create_and_add_node
+     */
+    create_and_add_node : function() {
+        var c = Y.Node.create,
+            region = this.get('region'),
+            node = c('<div id="block-region-'+region+'" data-droptarget="1"></div>')
+                .addClass(CSS.BLOCKREGION)
+                .setData('blockregion', region),
+            regions = this.get('manager').get('regions'),
+            i,
+            haspre = false,
+            haspost = false,
+            added = false,
+            pre,
+            post;
+
+        for (i in regions) {
+            if (regions[i].match(/(pre|left)/)) {
+                haspre = regions[i];
+            } else if (regions[i].match(/(post|right)/)) {
+                haspost = regions[i];
+            }
+        }
+
+        if (haspre !== false && haspost !== false) {
+            if (region === haspre) {
+                post = Y.one('#block-region-'+haspost);
+                if (post) {
+                    post.insert(node, 'before');
+                    added = true;
+                }
+            } else {
+                pre = Y.one('#block-region-'+haspre);
+                if (pre) {
+                    pre.insert(node, 'after');
+                    added = true;
+                }
+            }
+        }
+        if (added === false) {
+            Y.one('body').append(node);
+        }
+        this.set('node', node);
+    },
+
+    /**
+     * Removes the move icons and changes the cursor to a move icon when over the header.
+     * @method remove_block_move_icons
+     */
+    remove_block_move_icons : function() {
+        this.get('node').all('.'+CSS.BLOCK+' a.'+CSS.EDITINGMOVE).each(function(moveicon){
+            moveicon.ancestor('.'+CSS.BLOCK).one('.'+CSS.HEADER).setStyle('cursor', 'move');
+            moveicon.remove();
+        });
+    },
+
+    /**
+     * Returns the class name on the body that signifies the document knows about this region.
+     * @method get_has_region_class
+     * @return String
+     */
+    get_has_region_class : function() {
+        return 'has-region-'+this.get('region');
+    },
+
+    /**
+     * Returns the class name to use on the body if the region contains no blocks.
+     * @method get_empty_region_class
+     * @return String
+     */
+    get_empty_region_class : function() {
+        return 'empty-region-'+this.get('region');
+    },
+
+    /**
+     * Returns the class name to use on the body if the region contains blocks.
+     * @method get_used_region_class
+     * @return String
+     */
+    get_used_region_class : function() {
+        return 'used-region-'+this.get('region');
+    },
+
+    /**
+     * Returns the node to use as the drop target for this region.
+     * @method get_droptarget
+     * @return Node
+     */
+    get_droptarget : function() {
+        var node = this.get('node');
+        if (node.test('[data-droptarget="1"]')) {
+            return node;
+        }
+        return node.one('[data-droptarget="1"]');
+    },
+
+    /**
+     * Enables the block region so that we can be sure the user can see it.
+     * This is done even if it is empty.
+     * @method enable
+     */
+    enable : function() {
+        Y.one('body').addClass(this.get_used_region_class()).removeClass(this.get_empty_region_class());
+    },
+
+    /**
+     * Disables the region if it contains no blocks, essentially hiding it from the user.
+     * @method disable_if_required
+     */
+    disable_if_required : function() {
+        if (this.get('node').all('.'+CSS.BLOCK).size() === 0) {
+            Y.one('body').addClass(this.get_empty_region_class()).removeClass(this.get_used_region_class());
+        }
+    }
+};
+Y.extend(BLOCKREGION, Y.Base, BLOCKREGION.prototype, {
+    NAME : 'core-blocks-dragdrop-blockregion',
+    ATTRS : {
+
+        /**
+         * The drag and drop manager that created this block region instance.
+         * @attribute manager
+         * @type M.core.blockdraganddrop.Manager
+         * @writeOnce
+         */
+        manager : {
+            // Can only be set during initialisation and must be set then.
+            writeOnce : 'initOnly',
+            validator : function (value) {
+                return Y.Lang.isObject(value) && value instanceof MANAGER;
+            }
+        },
+
+        /**
+         * The name of the block region this object represents.
+         * @attribute region
+         * @type String
+         * @writeOnce
+         */
+        region : {
+            // Can only be set during initialisation and must be set then.
+            writeOnce : 'initOnly',
+            validator : function (value) {
+                return Y.Lang.isString(value);
+            }
+        },
+
+        /**
+         * The node the block region HTML starts at.s
+         * @attribute region
+         * @type Y.Node
+         */
+        node : {
+            validator : function (value) {
+                return Y.Lang.isObject(value) || Y.Lang.isNull(value);
+            }
+        },
+
+        /**
+         * True if the block region currently contains blocks.
+         * @attribute hasblocks
+         * @type Boolean
+         * @default false
+         */
+        hasblocks : {
+            value : false,
+            validator : function (value) {
+                return Y.Lang.isBoolean(value);
+            }
+        }
+    }
+});
\ No newline at end of file
index ff2809d..4597acc 100644 (file)
@@ -1,3 +1,9 @@
+/**
+ * Provides drag and drop functionality for blocks.
+ *
+ * @module moodle-core-blockdraganddrop
+ */
+
 var AJAXURL = '/lib/ajax/blocks.php',
 CSS = {
     BLOCK : 'block',
@@ -13,6 +19,16 @@ CSS = {
     REGIONMAIN : 'region-main'
 };
 
+/**
+ * Legacy drag and drop manager.
+ * This drag and drop manager is specifically designed for themes using side-pre and side-post
+ * that do not make use of the block output methods introduced by MDL-39824.
+ *
+ * @namespace M.core.blockdraganddrop
+ * @class LegacyManager
+ * @constructor
+ * @extends M.core.dragdrop
+ */
 var DRAGBLOCK = function() {
     DRAGBLOCK.superclass.constructor.apply(this, arguments);
 };
@@ -299,7 +315,66 @@ Y.extend(DRAGBLOCK, M.core.dragdrop, {
     }
 });
 
+/**
+ * Core namespace.
+ * @static
+ * @class core
+ */
+M.core = M.core || {};
+
+/**
+ * Block drag and drop static class.
+ * @namespace M.core
+ * @class blockdraganddrop
+ * @static
+ */
+M.core.blockdraganddrop = M.core.blockdraganddrop || {};
+
+/**
+ * True if the page is using the new blocks methods.
+ * @private
+ * @static
+ * @property _isusingnewblocksmethod
+ * @type Boolean
+ * @default null
+ */
+M.core.blockdraganddrop._isusingnewblocksmethod = null;
+
+/**
+ * Returns true if the page is using the new blocks methods.
+ * @static
+ * @method is_using_blocks_render_method
+ * @return Boolean
+ */
+M.core.blockdraganddrop.is_using_blocks_render_method = function() {
+    if (this._isusingnewblocksmethod === null) {
+        var goodregions = Y.all('.block-region[data-blockregion]').size();
+        var allregions = Y.all('.block-region').size();
+        this._isusingnewblocksmethod = (allregions === goodregions);
+    }
+    return this._isusingnewblocksmethod;
+};
+
+/**
+ * Initialises a drag and drop manager.
+ * This should only ever be called once for a page.
+ * @static
+ * @method init
+ * @param {Object} params
+ * @return Manager
+ */
+M.core.blockdraganddrop.init = function(params) {
+    if (this.is_using_blocks_render_method()) {
+        new MANAGER(params);
+    } else {
+        new DRAGBLOCK(params);
+    }
+};
+
+/**
+ * Legacy code to keep things working.
+ */
 M.core_blocks = M.core_blocks || {};
 M.core_blocks.init_dragdrop = function(params) {
-    new DRAGBLOCK(params);
-};
+    M.core.blockdraganddrop.init(params);
+};
\ No newline at end of file
diff --git a/lib/yui/src/blocks/js/manager.js b/lib/yui/src/blocks/js/manager.js
new file mode 100644 (file)
index 0000000..40490af
--- /dev/null
@@ -0,0 +1,393 @@
+/**
+ * This file contains the drag and drop manager class.
+ *
+ * Provides drag and drop functionality for blocks.
+ *
+ * @module moodle-core-blockdraganddrop
+ */
+
+/**
+ * Constructs a new Block drag and drop manager.
+ *
+ * @namespace M.core.blockdraganddrop
+ * @class Manager
+ * @constructor
+ * @extends M.core.dragdrop
+ */
+var MANAGER = function() {
+    MANAGER.superclass.constructor.apply(this, arguments);
+};
+MANAGER.prototype = {
+
+    /**
+     * The skip block link from above the block being dragged while a drag is in progress.
+     * Required by the M.core.dragdrop from whom this class extends.
+     * @private
+     * @property skipnodetop
+     * @type Node
+     * @default null
+     */
+    skipnodetop : null,
+
+    /**
+     * The skip block link from below the block being dragged while a drag is in progress.
+     * Required by the M.core.dragdrop from whom this class extends.
+     * @private
+     * @property skipnodebottom
+     * @type Node
+     * @default null
+     */
+    skipnodebottom : null,
+
+    /**
+     * An associative object of regions and the
+     * @property regionobjects
+     * @type {Object} Primitive object mocking an associative array.
+     * @type {BLOCKREGION} [regionname]* Each item uses the region name as the key with the value being
+     *      an instance of the BLOCKREGION class.
+     */
+    regionobjects : {},
+
+    /**
+     * Called during the initialisation process of the object.
+     * @method initializer
+     */
+    initializer : function() {
+        Y.log('Initialising drag and drop for blocks.', 'info');
+        var regionnames = this.get('regions'),
+            i = 0,
+            region,
+            regionname,
+            droptarget,
+            dragdelegation;
+
+        // Evil required by M.core.dragdrop.
+        this.groups = ['block'];
+        this.samenodeclass = CSS.BLOCK;
+        this.parentnodeclass = CSS.BLOCKREGION;
+
+        // Add relevant classes and ID to 'content' block region on My Home page.
+        var myhomecontent = Y.Node.all('body#'+CSS.MYINDEX+' #'+CSS.REGIONMAIN+' > .'+CSS.REGIONCONTENT);
+        if (myhomecontent.size() > 0) {
+            var contentregion = myhomecontent.item(0);
+            contentregion.addClass(CSS.BLOCKREGION);
+            contentregion.set('id', CSS.REGIONCONTENT);
+            contentregion.one('div').addClass(CSS.REGIONCONTENT);
+        }
+
+        for (i in regionnames) {
+            regionname = regionnames[i];
+            region = new BLOCKREGION({
+                manager : this,
+                region : regionname,
+                node : Y.one('#block-region-'+regionname)
+            });
+            this.regionobjects[regionname] = region;
+
+            // Setting blockregion as droptarget (the case when it is empty)
+            // The region-post (the right one)
+            // is very narrow, so add extra padding on the left to drop block on it.
+            droptarget = new Y.DD.Drop({
+                node: region.get_droptarget(),
+                groups: this.groups,
+                padding: '40 240 40 240'
+            });
+
+            // Make each div element in the list of blocks draggable
+            dragdelegation = new Y.DD.Delegate({
+                container: region.get_droptarget(),
+                nodes: '.'+CSS.BLOCK,
+                target: true,
+                handles: ['.'+CSS.HEADER],
+                invalid: '.block-hider-hide, .block-hider-show, .moveto',
+                dragConfig: {groups: this.groups}
+            });
+            dragdelegation.dd.plug(Y.Plugin.DDProxy, {
+                // Don't move the node at the end of the drag
+                moveOnEnd: false
+            });
+            dragdelegation.dd.plug(Y.Plugin.DDWinScroll);
+            // On the mouse down event we will enable all block regions so that they can be dragged to.
+            // This is VERY important as without it dnd won't work for empty block regions.
+            dragdelegation.on('drag:mouseDown', this.enable_all_regions, this);
+
+            region.remove_block_move_icons();
+        }
+        Y.log('Initialisation of drag and drop for blocks complete.', 'info');
+    },
+
+    /**
+     * Returns the ID of the block the given node represents.
+     * @method get_block_id
+     * @param {Node} node
+     * @returns {int} The blocks ID in the database.
+     */
+    get_block_id : function(node) {
+        return Number(node.get('id').replace(/inst/i, ''));
+    },
+
+    /**
+     * Returns the block region that the node is part of or belonging to.
+     * @method get_block_region
+     * @param {Y.Node} node
+     * @returns {string} The region name.
+     */
+    get_block_region : function(node) {
+        if (!node.test('[data-blockregion]')) {
+            node = node.ancestor('[data-blockregion]');
+        }
+        return node.getData('blockregion');
+    },
+
+    /**
+     * Returns the BLOCKREGION instance that represents the block region the given node is part of.
+     * @method get_region_object
+     * @param {Y.Node} node
+     * @returns {BLOCKREGION}
+     */
+    get_region_object : function(node) {
+        return this.regionobjects[this.get_block_region(node)];
+    },
+
+    /**
+     * Enables all fo the regions so that they are all visible while dragging is occuring.
+     * @method enable_all_regions
+     * @returns {undefined}
+     */
+    enable_all_regions : function() {
+        var i = 0;
+        for (i in this.regionobjects) {
+            this.regionobjects[i].enable();
+        }
+    },
+
+    /**
+     * Disables enabled regions if they contain no blocks.
+     * @method disable_regions_if_required
+     * @returns {undefined}
+     */
+    disable_regions_if_required : function() {
+        var i = 0;
+        for (i in this.regionobjects) {
+            this.regionobjects[i].disable_if_required();
+        }
+    },
+
+    /**
+     * Called by M.core.dragdrop.global_drag_start when dragging starts.
+     * @method drag_start
+     * @param {Event} e
+     * @returns {undefined}
+     */
+    drag_start : function(e) {
+        // Get our drag object
+        var drag = e.target;
+
+        // Store the parent node of original drag node (block)
+        // we will need it later for show/hide empty regions
+
+        // Determine skipnodes and store them
+        if (drag.get('node').previous() && drag.get('node').previous().hasClass(CSS.SKIPBLOCK)) {
+            this.skipnodetop = drag.get('node').previous();
+        }
+        if (drag.get('node').next() && drag.get('node').next().hasClass(CSS.SKIPBLOCKTO)) {
+            this.skipnodebottom = drag.get('node').next();
+        }
+    },
+
+    /**
+     * Called by M.core.dragdrop.global_drop_over when something is dragged over a drop target.
+     * @method drop_over
+     * @param {Event} e
+     * @returns {undefined}
+     */
+    drop_over : function(e) {
+        // Get a reference to our drag and drop nodes
+        var drag = e.drag.get('node');
+        var drop = e.drop.get('node');
+
+        // We need to fix the case when parent drop over event has determined
+        // 'goingup' and appended the drag node after admin-block.
+        if (drop.hasClass(CSS.REGIONCONTENT) && drop.one('.'+CSS.BLOCKADMINBLOCK) && drop.one('.'+CSS.BLOCKADMINBLOCK).next('.'+CSS.BLOCK)) {
+            drop.prepend(drag);
+        }
+    },
+
+    /**
+     * Called by M.core.dragdrop.global_drop_end when a drop has been completed.
+     * @method drop_end
+     * @returns {undefined}
+     */
+    drop_end : function() {
+        // Clear variables.
+        this.skipnodetop = null;
+        this.skipnodebottom = null;
+        this.disable_regions_if_required();
+    },
+
+    /**
+     * Called by M.core.dragdrop.global_drag_dropmiss when something has been dropped on a node that isn't contained by a drop target.
+     * @method drag_dropmiss
+     * @param {Event} e
+     * @returns {undefined}
+     */
+    drag_dropmiss : function(e) {
+        // Missed the target, but we assume the user intended to drop it
+        // on the last ghost node location, e.drag and e.drop should be
+        // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
+        this.drop_hit(e);
+    },
+
+    /**
+     * Called by M.core.dragdrop.global_drag_hit when something has been dropped on a drop target.
+     * @method drop_hit
+     * @param {Event} e
+     * @returns {undefined}
+     */
+    drop_hit : function(e) {
+        // Get a reference to our drag node
+        var dragnode = e.drag.get('node');
+        var dropnode = e.drop.get('node');
+
+        // Amend existing skipnodes
+        if (dragnode.previous() && dragnode.previous().hasClass(CSS.SKIPBLOCK)) {
+            // the one that belongs to block below move below
+            dragnode.insert(dragnode.previous(), 'after');
+        }
+        // Move original skipnodes
+        if (this.skipnodetop) {
+            dragnode.insert(this.skipnodetop, 'before');
+        }
+        if (this.skipnodebottom) {
+            dragnode.insert(this.skipnodebottom, 'after');
+        }
+
+        // Add lightbox if it not there
+        var lightbox = M.util.add_lightbox(Y, dragnode);
+
+        // Prepare request parameters
+        var params = {
+            sesskey : M.cfg.sesskey,
+            courseid : this.get('courseid'),
+            pagelayout : this.get('pagelayout'),
+            pagetype : this.get('pagetype'),
+            subpage : this.get('subpage'),
+            contextid : this.get('contextid'),
+            action : 'move',
+            bui_moveid : this.get_block_id(dragnode),
+            bui_newregion : this.get_block_region(dropnode)
+        };
+
+        if (this.get('cmid')) {
+            params.cmid = this.get('cmid');
+        }
+
+        if (dragnode.next('.'+CSS.BLOCK) && !dragnode.next('.'+CSS.BLOCK).hasClass(CSS.BLOCKADMINBLOCK)) {
+            params.bui_beforeid = this.get_block_id(dragnode.next('.'+CSS.BLOCK));
+        }
+
+        // Do AJAX request
+        Y.io(M.cfg.wwwroot+AJAXURL, {
+            method: 'POST',
+            data: params,
+            on: {
+                start : function() {
+                    lightbox.show();
+                },
+                success: function(tid, response) {
+                    window.setTimeout(function() {
+                        lightbox.hide();
+                    }, 250);
+                    try {
+                        var responsetext = Y.JSON.parse(response.responseText);
+                        if (responsetext.error) {
+                            new M.core.ajaxException(responsetext);
+                        }
+                    } catch (e) {}
+                },
+                failure: function(tid, response) {
+                    this.ajax_failure(response);
+                    lightbox.hide();
+                },
+                complete : function() {
+                    this.disable_regions_if_required();
+                }
+            },
+            context:this
+        });
+    }
+};
+Y.extend(MANAGER, M.core.dragdrop, MANAGER.prototype, {
+    NAME : 'core-blocks-dragdrop-manager',
+    ATTRS : {
+        /**
+         * The Course ID if there is one.
+         * @attribute courseid
+         * @type int|null
+         * @default null
+         */
+        courseid : {
+            value : null
+        },
+
+        /**
+         * The Course Module ID if there is one.
+         * @attribute cmid
+         * @type int|null
+         * @default null
+         */
+        cmid : {
+            value : null
+        },
+
+        /**
+         * The Context ID.
+         * @attribute contextid
+         * @type int|null
+         * @default null
+         */
+        contextid : {
+            value : null
+        },
+
+        /**
+         * The current page layout.
+         * @attribute pagelayout
+         * @type string|null
+         * @default null
+         */
+        pagelayout : {
+            value : null
+        },
+
+        /**
+         * The page type string, should be used as the id for the body tag in the theme.
+         * @attribute pagetype
+         * @type string|null
+         * @default null
+         */
+        pagetype : {
+            value : null
+        },
+
+        /**
+         * The subpage identifier, if any.
+         * @attribute subpage
+         * @type string|null
+         * @default null
+         */
+        subpage : {
+            value : null
+        },
+
+        /**
+         * An array of block regions that are present on the page.
+         * @attribute regions
+         * @type array|null
+         * @default Array[]
+         */
+        regions : {
+            value : []
+        }
+    }
+});
\ No newline at end of file
index a98af01..e4293dc 100644 (file)
 
 require('../config.php');
 
+// Try to prevent searching for sites that allow sign-up.
+if (!isset($CFG->additionalhtmlhead)) {
+    $CFG->additionalhtmlhead = '';
+}
+$CFG->additionalhtmlhead .= '<meta name="robots" content="noindex" />';
+
 redirect_if_major_upgrade_required();
 
 $testsession = optional_param('testsession', 0, PARAM_INT); // test session works properly
index 331f9ef..a35641f 100644 (file)
 
 require('../config.php');
 
+// Try to prevent searching for sites that allow sign-up.
+if (!isset($CFG->additionalhtmlhead)) {
+    $CFG->additionalhtmlhead = '';
+}
+$CFG->additionalhtmlhead .= '<meta name="robots" content="noindex" />';
+
 if (empty($CFG->registerauth)) {
     print_error('notlocalisederrormessage', 'error', '', 'Sorry, you may not use this page.');
 }
index 4be18c3..21788ad 100644 (file)
@@ -49,7 +49,7 @@ class mod_assign_grading_batch_operations_form extends moodleform {
         if ($instance['submissiondrafts']) {
             $options['reverttodraft'] = get_string('reverttodraft', 'assign');
         }
-        if ($instance['duedate']) {
+        if ($instance['duedate'] && has_capability('mod/assign:grantextension', $instance['context'])) {
             $options['grantextension'] = get_string('grantextension', 'assign');
         }
         if ($instance['attemptreopenmethod'] == ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL) {
index a168a0b..57df5a0 100644 (file)
@@ -166,15 +166,17 @@ class assign_grading_table extends table_sql implements renderable {
         // The filters do not make sense when there are no submissions, so do not apply them.
         if ($this->assignment->is_any_submission_plugin_enabled()) {
             if ($filter == ASSIGN_FILTER_SUBMITTED) {
-                $where .= ' AND s.timecreated > 0 ';
-            }
-            if ($filter == ASSIGN_FILTER_REQUIRE_GRADING) {
+                $where .= ' AND (s.timemodified IS NOT NULL AND
+                                 s.status = :submitted) ';
+                $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
+
+            } else if ($filter == ASSIGN_FILTER_REQUIRE_GRADING) {
                 $where .= ' AND (s.timemodified IS NOT NULL AND
                                  s.status = :submitted AND
                                  (s.timemodified > g.timemodified OR g.timemodified IS NULL))';
                 $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
-            }
-            if (strpos($filter, ASSIGN_FILTER_SINGLE_USER) === 0) {
+
+            } else if (strpos($filter, ASSIGN_FILTER_SINGLE_USER) === 0) {
                 $userfilter = (int) array_pop(explode('=', $filter));
                 $where .= ' AND (u.id = :userid)';
                 $params['userid'] = $userfilter;
index bce42d2..2267c96 100644 (file)
@@ -2876,7 +2876,8 @@ class assign {
                                  'submissiondrafts'=>$this->get_instance()->submissiondrafts,
                                  'duedate'=>$this->get_instance()->duedate,
                                  'attemptreopenmethod'=>$this->get_instance()->attemptreopenmethod,
-                                 'feedbackplugins'=>$this->get_feedback_plugins());
+                                 'feedbackplugins'=>$this->get_feedback_plugins(),
+                                 'context'=>$this->get_context());
         $classoptions = array('class'=>'gradingbatchoperationsform');
 
         $gradingbatchoperationsform = new mod_assign_grading_batch_operations_form(null,
@@ -3152,7 +3153,8 @@ class assign {
                                  'submissiondrafts'=>$this->get_instance()->submissiondrafts,
                                  'duedate'=>$this->get_instance()->duedate,
                                  'attemptreopenmethod'=>$this->get_instance()->attemptreopenmethod,
-                                 'feedbackplugins'=>$this->get_feedback_plugins());
+                                 'feedbackplugins'=>$this->get_feedback_plugins(),
+                                 'context'=>$this->get_context());
         $formclasses = array('class'=>'gradingbatchoperationsform');
         $mform = new mod_assign_grading_batch_operations_form(null,
                                                               $batchformparams,
@@ -3675,7 +3677,7 @@ class assign {
             return false;
         }
         $assign = clone $this->get_instance();
-        $assign->cmidnumber = $this->get_course_module()->id;
+        $assign->cmidnumber = $this->get_course_module()->idnumber;
 
         return assign_grade_item_update($assign, $gradebookgrade);
     }
@@ -4958,6 +4960,7 @@ class assign {
                 $gradingelement->freeze();
             } else {
                 $mform->addElement('hidden', 'advancedgradinginstanceid', $gradinginstance->get_id());
+                $mform->setType('advancedgradinginstanceid', PARAM_INT);
             }
         } else {
             // Use simple direct grading.
index 4e0d669..ba33874 100644 (file)
@@ -68,6 +68,7 @@ require_login($course, true, $cm);
 require_capability('mod/feedback:mapcourse', $context);
 
 if ($coursefilter) {
+    $map = new stdClass;
     $map->feedbackid = $feedback->id;
     $map->courseid = $coursefilter;
     // insert a map only if it does exists yet
@@ -123,6 +124,7 @@ echo '</form>';
 
 if ($coursemap = feedback_get_courses_from_sitecourse_map($feedback->id)) {
     $table = new flexible_table('coursemaps');
+    $table->baseurl = $url;
     $table->define_columns( array('course'));
     $table->define_headers( array(get_string('mappedcourses', 'feedback')));
 
@@ -130,9 +132,8 @@ if ($coursemap = feedback_get_courses_from_sitecourse_map($feedback->id)) {
 
     $unmapurl = new moodle_url('/mod/feedback/unmapcourse.php');
     foreach ($coursemap as $cmap) {
-        $cmapcontext = context_course::instance($cmap->id);
-        $cmapshortname = format_string($cmap->shortname, true, array('context' => $cmapcontext));
         $coursecontext = context_course::instance($cmap->courseid);
+        $cmapshortname = format_string($cmap->shortname, true, array('context' => $coursecontext));
         $cmapfullname = format_string($cmap->fullname, true, array('context' => $coursecontext));
         $unmapurl->params(array('id'=>$id, 'cmapid'=>$cmap->id));
         $anker = '<a href="'.$unmapurl->out().'">';
index f2755cf..d51ecf7 100644 (file)
@@ -61,10 +61,14 @@ function imscp_print_content($imscp, $cm, $course) {
 function imscp_htmllize_item($item, $imscp, $cm) {
     global $CFG;
 
-    $context = context_module::instance($cm->id);
-    $urlbase = "$CFG->wwwroot/pluginfile.php";
-    $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$item['href'];
-    $url = file_encode_url($urlbase, $path, false);
+    if (preg_match('|^https?://|', $item['href'])) {
+        $url = $item['href'];
+    } else {
+        $context = context_module::instance($cm->id);
+        $urlbase = "$CFG->wwwroot/pluginfile.php";
+        $path = '/'.$context->id.'/mod_imscp/content/'.$imscp->revision.'/'.$item['href'];
+        $url = file_encode_url($urlbase, $path, false);
+    }
     $result = "<li><a href=\"$url\">".$item['title'].'</a>';
     if ($item['subitems']) {
         $result .= '<ul>';
index f1f08ca..4a47194 100644 (file)
@@ -93,7 +93,7 @@ if ($lastattempt && ($lastattempt->state == quiz_attempt::IN_PROGRESS ||
 
     // And, if the attempt is now no longer in progress, redirect to the appropriate place.
     if ($lastattempt->state == quiz_attempt::OVERDUE) {
-         redirect($quizobj->summary_url($lastattempt->id));
+        redirect($quizobj->summary_url($lastattempt->id));
     } else if ($lastattempt->state != quiz_attempt::IN_PROGRESS) {
         redirect($quizobj->review_url($lastattempt->id));
     }
@@ -104,6 +104,10 @@ if ($lastattempt && ($lastattempt->state == quiz_attempt::IN_PROGRESS ||
     }
 
 } else {
+    while ($lastattempt && $lastattempt->preview) {
+        $lastattempt = array_pop($attempts);
+    }
+
     // Get number for the next or unfinished attempt.
     if ($lastattempt) {
         $attemptnumber = $lastattempt->attempt + 1;
index d803485..10f078f 100644 (file)
@@ -504,7 +504,10 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
 
         // navigation
         if (scorm_hide_nav == false) {
-            scorm_nav_panel = new Y.YUI2.widget.Panel('scorm_navpanel', { visible:true, draggable:true, close:false, xy: [250, 450],
+            var left = scorm_layout_widget.getUnitByPosition('left');
+            navposition = Y.YUI2.util.Dom.getXY(left);
+            navposition[1] += 200;
+            scorm_nav_panel = new Y.YUI2.widget.Panel('scorm_navpanel', { visible:true, draggable:true, close:false, xy: navposition,
                                                                     autofillheight: "body"} );
             scorm_nav_panel.setHeader(M.str.scorm.navigation);
 
index 6286973..7a03152 100644 (file)
@@ -23,5 +23,4 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['pluginname'] = 'Graph report';
-
+$string['pluginname'] = 'Basic report';
index 63ef9cf..e77f988 100644 (file)
@@ -12,6 +12,7 @@
 #page-mod-scorm-player #scormpage {position: relative;width: 100%;height: 100%;}
 #page-mod-scorm-player #scormpage #toctree {position:relative;width:100%;overflow-x: auto;overflow-y: auto;}
 #page-mod-scorm-player #tocbox {position: relative;left: 0px;width: 100%;height: 100%;font-size: 0.8em;}
+#page-mod-scorm-player #toctree { overflow: visible; }
 #page-mod-scorm-player #tochead {position: relative;text-align: center;top: 3px;height: 30px;}
 #page-mod-scorm-player #scormpage .scoframe {frameborder: 0;}
 
@@ -39,3 +40,4 @@
 .path-mod-scorm.jsenabled .scorm-center { display:block;}
 .path-mod-scorm.jsenabled .toc { display:block;}
 .path-mod-scorm.jsenabled #scormpage #tocbox { display:block;}
+
index 979b432..e66c434 100644 (file)
@@ -24,10 +24,10 @@ class note_edit_form extends moodleform {
         $this->add_action_buttons();
 
         $mform->addElement('hidden', 'courseid');
-        $mform->setType('course', PARAM_INT);
+        $mform->setType('courseid', PARAM_INT);
 
         $mform->addElement('hidden', 'userid');
-        $mform->setType('user', PARAM_INT);
+        $mform->setType('userid', PARAM_INT);
 
         $mform->addElement('hidden', 'id');
         $mform->setType('id', PARAM_INT);
index cfd0af2..9c0c7cf 100644 (file)
@@ -152,6 +152,8 @@ class question_engine_data_mapper {
         foreach ($step->get_all_data() as $name => $value) {
             if ($value instanceof question_file_saver) {
                 $value->save_files($stepid, $context);
+            }
+            if ($value instanceof question_response_files) {
                 $value = (string) $value;
             }
 
index df13890..a5e5d12 100644 (file)
@@ -759,16 +759,16 @@ abstract class question_utils {
     public static function arrays_same_at_key_integer(
             array $array1, array $array2, $key) {
         if (array_key_exists($key, $array1)) {
-            $value1 = $array1[$key];
+            $value1 = (int) $array1[$key];
         } else {
             $value1 = 0;
         }
         if (array_key_exists($key, $array2)) {
-            $value2 = $array2[$key];
+            $value2 = (int) $array2[$key];
         } else {
             $value2 = 0;
         }
-        return ((integer) $value1) === ((integer) $value2);
+        return $value1 === $value2;
     }
 
     private static $units     = array('', 'i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix');
index b7c412e..b9ea3bd 100644 (file)
@@ -61,7 +61,8 @@ class qformat_multianswer extends qformat_default {
         $question->length = 1;
         $question->penalty = 0.3333333;
 
-        if (!empty($question)) {
+        if (!empty($question) && isset($question->options) && isset($question->options->questions) &&
+            count($question->options->questions) != 0 ) {
             $question->name = $this->create_default_question_name($question->questiontext, get_string('questionname', 'question'));
             $questions[] = $question;
         }
index 69e9695..ea2e167 100644 (file)
@@ -449,12 +449,12 @@ class qformat_xml extends qformat_default {
      */
     public function import_multianswer($question) {
         global $USER;
-        question_bank::get_qtype('multianswer');
+        $qtypemultianswer = question_bank::get_qtype('multianswer');
 
         $questiontext = $this->import_text_with_files($question,
                 array('#', 'questiontext', 0));
         $qo = qtype_multianswer_extract_question($questiontext);
-
+        $qo = $qtypemultianswer->set_subquestions_elements_itemid($qo, '@@PLUGINFILE@@');
         // 'header' parts particular to multianswer
         $qo->qtype = 'multianswer';
         $qo->course = $this->course;
index cd792f7..cdecffb 100644 (file)
@@ -189,8 +189,10 @@ class qtype_multianswer_edit_form extends question_edit_form {
                     $mform->addElement('static', 'sub_'.$sub.'_layout',
                             get_string('layout', 'qtype_multianswer'));
                 }
-
+                $nbanswer = 0;
+                $choices = array();
                 foreach ($this->questiondisplay->options->questions[$sub]->answer as $key => $ans) {
+                    $nbanswer++;
                     $mform->addElement('static', 'sub_'.$sub.'_answer['.$key.']',
                             get_string('answer', 'question'));
 
@@ -205,6 +207,15 @@ class qtype_multianswer_edit_form extends question_edit_form {
 
                     $mform->addElement('static', 'sub_'.$sub.'_feedback['.$key.']',
                             get_string('feedback', 'question'));
+                    if ($this->questiondisplay->options->questions[$sub]->qtype == 'multichoice' &&
+                        $this->questiondisplay->options->questions[$sub]->layout == 0) {
+                        $choices[] = $ans['text'];
+                    }
+                }
+                if ($nbanswer > 0 && $this->questiondisplay->options->questions[$sub]->qtype == 'multichoice' &&
+                    $this->questiondisplay->options->questions[$sub]->layout == 0) {
+                    $mform->addElement('select', 'sub_'.$sub.'_layoutselectinline',
+                        get_string('layoutselectinline', 'qtype_multianswer'), $choices);
                 }
             }
 
@@ -364,6 +375,7 @@ class qtype_multianswer_edit_form extends question_edit_form {
                                             get_string('layoutundefined', 'qtype_multianswer');
                             }
                         }
+                        $choices = array();
                         foreach ($subquestion->answer as $key => $answer) {
                             if ($subquestion->qtype == 'numerical' && $key == 0) {
                                 $default_values[$prefix.'tolerance['.$key.']'] =
@@ -388,9 +400,19 @@ class qtype_multianswer_edit_form extends question_edit_form {
                                     $maxfraction = $subquestion->fraction[$key];
                                 }
                             }
-
-                            $default_values[$prefix.'answer['.$key.']'] =
-                                    htmlspecialchars($answer);
+                            if ($subquestion->qtype == 'multichoice' && $subquestion->layout == '0') {
+                                $a = new stdClass();
+                                $a->strip = strip_tags($trimmedanswer);
+                                $a->html = htmlspecialchars($trimmedanswer);
+                                $default_values[$prefix.'answer['.$key.']'] = get_string('answerselectelementshownas',
+                                        'qtype_multianswer', $a);
+                                $choices[$answercount] = $trimmedanswer;
+                            } else {
+                                $default_values[$prefix.'answer['.$key.']'] = htmlspecialchars($answer);
+                            }
+                        }
+                        if ($subquestion->qtype == 'multichoice' && $subquestion->layout == '0') {
+                            $default_values[$prefix.'_layoutselectinline'] = $choices;
                         }
                         if ($answercount == 0) {
                             if ($subquestion->qtype == 'multichoice') {
index ddc0155..0a294a4 100644 (file)
@@ -23,6 +23,8 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['answerselectelementempty'] = '{$a->html}<br />This answer will appear empty as the dropdown menu does not show HTML components.';
+$string['answerselectelementshownas'] = '{$a->html}<br />This answer will be rendered in the dropdown menu as : {$a->strip}';
 $string['confirmquestionsaveasedited'] = 'I confirm that I want the question to be saved as edited';
 $string['confirmsave'] = 'Confirm then save {$a}';
 $string['correctanswer'] = 'Correct answer';
diff --git a/question/type/multianswer/lib.php b/question/type/multianswer/lib.php
new file mode 100644 (file)
index 0000000..59faf58
--- /dev/null
@@ -0,0 +1,47 @@
+<?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/>.
+
+/**
+ * Serve question type files
+ *
+ * @since      2.0
+ * @package    qtype_multianswer
+ * @copyright  Pierre Pichet
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+defined('MOODLE_INTERNAL') || die();
+
+
+/**
+ * Checks file access for multianswer questions.
+ * @package  qtype_multianswer
+ * @category files
+ * @param stdClass $course course object
+ * @param stdClass $cm course module object
+ * @param stdClass $context context object
+ * @param string $filearea file area
+ * @param array $args extra arguments
+ * @param bool $forcedownload whether or not force download
+ * @param array $options additional options affecting the file serving
+ * @return bool
+ */
+function qtype_multianswer_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
+    global $DB, $CFG;
+    require_once($CFG->libdir . '/questionlib.php');
+    question_pluginfile($course, $context, 'qtype_multianswer', $filearea, $args, $forcedownload, $options);
+}
index 5df9f2c..0153882 100644 (file)
@@ -168,8 +168,45 @@ class qtype_multianswer extends question_type {
         $this->save_hints($question, true);
     }
 
+    /**
+     * Set the itemid if the element contains a valid file identify by (draftfile.php).
+     * param array() $question from qtype_multianswer_extract_question().
+     * param string  $searchcriteria i.e $searchcriteria ,@@PLUGINFILE@@.
+     * return $question.
+     */
+    public function set_subquestions_elements_itemid($question, $searchcriteria = '') {
+        if (isset($question->options) && isset($question->options->questions) &&
+            $question->options->questions != '' && isset($question->questiontext['itemid'])
+            && $question->questiontext['itemid'] != '' && $searchcriteria != '') {
+            $questiontextitemid = $question->questiontext['itemid'];
+            foreach ($question->options->questions as $wrapped) {
+                if (preg_match('/'.$searchcriteria.'/', $wrapped->questiontext['text'])) {
+                    $wrapped->questiontext['itemid'] = $questiontextitemid;
+                } else {
+                    $wrapped->questiontext['itemid'] = '';
+                }
+                foreach ($wrapped->answer as $key => $answer) {
+                    if (is_array($answer)) {
+                        if (preg_match('/'.$searchcriteria.'/', $answer['text'])) {
+                            $wrapped->answer[$key]['itemid'] = $questiontextitemid;
+                        } else {
+                            $wrapped->answer[$key]['itemid'] = '';
+                        }
+                    }
+                    if (preg_match('/'.$searchcriteria.'/', $wrapped->feedback[$key]['text'])) {
+                        $wrapped->feedback[$key]['itemid'] = $questiontextitemid;
+                    } else {
+                        $wrapped->feedback[$key]['itemid'] = '';
+                    }
+                }
+            }
+        }
+        return $question;
+    }
+
     public function save_question($authorizedquestion, $form) {
         $question = qtype_multianswer_extract_question($form->questiontext);
+        $question = $this->set_subquestions_elements_itemid($question, 'draftfile.php');
         if (isset($authorizedquestion->id)) {
             $question->id = $authorizedquestion->id;
         }
@@ -296,9 +333,15 @@ define('ANSWER_REGEX_ALTERNATIVES', 9);
 
 function qtype_multianswer_extract_question($text) {
     // Variable $text is an array [text][format][itemid].
+    // If the main question contains a file then its [itemid]
+    // will not be empty.
+    // The other subquestions question , answers feedback and
+    // multiple choice vertical and horizontal answers should be declared
+    // array and should have [itemid] set to [text][itemid].
     $question = new stdClass();
     $question->qtype = 'multianswer';
     $question->questiontext = $text;
+    $question->questiontext['text'] = str_replace(array('<pre>', '</pre>'), array('', ''), $question->questiontext['text']);
     $question->generalfeedback['text'] = '';
     $question->generalfeedback['format'] = FORMAT_HTML;
     $question->generalfeedback['itemid'] = '';
@@ -314,6 +357,9 @@ function qtype_multianswer_extract_question($text) {
         $wrapped->generalfeedback['text'] = '';
         $wrapped->generalfeedback['format'] = FORMAT_HTML;
         $wrapped->generalfeedback['itemid'] = '';
+        $wrapped->questiontext['text'] = $answerregs[0];
+        $wrapped->questiontext['format'] = $question->questiontext['format'];
+        $wrapped->questiontext['itemid'] = $question->questiontext['itemid'];
         if (isset($answerregs[ANSWER_REGEX_NORM])&& $answerregs[ANSWER_REGEX_NORM]!== '') {
             $wrapped->defaultmark = $answerregs[ANSWER_REGEX_NORM];
         } else {
@@ -388,9 +434,6 @@ function qtype_multianswer_extract_question($text) {
         $wrapped->answer   = array();
         $wrapped->fraction = array();
         $wrapped->feedback = array();
-        $wrapped->questiontext['text'] = $answerregs[0];
-        $wrapped->questiontext['format'] = FORMAT_HTML;
-        $wrapped->questiontext['itemid'] = '';
         $answerindex = 0;
 
         $remainingalts = $answerregs[ANSWER_REGEX_ALTERNATIVES];
@@ -408,7 +451,7 @@ function qtype_multianswer_extract_question($text) {
                 $feedback = str_replace('\}', '}', $feedback);
                 $wrapped->feedback["$answerindex"]['text'] = str_replace('\#', '#', $feedback);
                 $wrapped->feedback["$answerindex"]['format'] = FORMAT_HTML;
-                $wrapped->feedback["$answerindex"]['itemid'] = '';
+                $wrapped->feedback["$answerindex"]['itemid'] = $question->questiontext['itemid'];
             } else {
                 $wrapped->feedback["$answerindex"]['text'] = '';
                 $wrapped->feedback["$answerindex"]['format'] = FORMAT_HTML;
@@ -436,6 +479,11 @@ function qtype_multianswer_extract_question($text) {
                             'text' => $wrapped->answer["$answerindex"],
                             'format' => FORMAT_HTML,
                             'itemid' => '');
+                    if ($wrapped->answer["$answerindex"]['text'] != '' &&
+                            ($wrapped->layout == qtype_multichoice_base::LAYOUT_HORIZONTAL ||
+                            $wrapped->layout == qtype_multichoice_base::LAYOUT_VERTICAL )) {
+                        $wrapped->answer["$answerindex"]['itemid'] = $question->questiontext['itemid'];
+                    }
                 }
             }
             $tmp = explode($altregs[0], $remainingalts, 2);
index d67d0fc..403c985 100644 (file)
@@ -388,7 +388,7 @@ class qtype_multianswer_multichoice_vertical_renderer extends qtype_multianswer_
                         question_state::$gradedright) {
                     $feedback[] = get_string('correctansweris', 'qtype_multichoice',
                             $subq->format_text($ans->answer, $ans->answerformat,
-                                    $qa, 'question', 'answer', $ansid));
+                                    $qa, 'question', 'answer', $ans->id));
                     break;
                 }
             }
index c3ac2ca..2888a30 100644 (file)
@@ -338,7 +338,7 @@ class qtype_multichoice_multi_question extends qtype_multichoice_base {
     public function is_same_response(array $prevresponse, array $newresponse) {
         foreach ($this->order as $key => $notused) {
             $fieldname = $this->field($key);
-            if (!question_utils::arrays_same_at_key($prevresponse, $newresponse, $fieldname)) {
+            if (!question_utils::arrays_same_at_key_integer($prevresponse, $newresponse, $fieldname)) {
                 return false;
             }
         }
diff --git a/question/type/multichoice/tests/question_multi_test.php b/question/type/multichoice/tests/question_multi_test.php
new file mode 100644 (file)
index 0000000..11fe16f
--- /dev/null
@@ -0,0 +1,152 @@
+<?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 the multiple choice, multi-response question definition classes.
+ *
+ * @package   qtype_multichoice
+ * @copyright 2009 The Open University
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
+
+
+/**
+ * Unit tests for the multiple choice, multi-response question definition class.
+ *
+ * @copyright 2009 The Open University
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class qtype_multichoice_multi_question_test extends advanced_testcase {
+
+    public function test_get_expected_data() {
+        $question = test_question_maker::make_a_multichoice_multi_question();
+        $question->start_attempt(new question_attempt_step(), 1);
+
+        $this->assertEquals(array('choice0' => PARAM_BOOL, 'choice1' => PARAM_BOOL,
+                'choice2' => PARAM_BOOL, 'choice3' => PARAM_BOOL), $question->get_expected_data());
+    }
+
+    public function test_is_complete_response() {
+        $question = test_question_maker::make_a_multichoice_multi_question();
+        $question->start_attempt(new question_attempt_step(), 1);
+
+        $this->assertFalse($question->is_complete_response(array()));
+        $this->assertFalse($question->is_complete_response(
+                array('choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0')));
+        $this->assertTrue($question->is_complete_response(array('choice1' => '1')));
+        $this->assertTrue($question->is_complete_response(
+                array('choice0' => '1', 'choice1' => '1', 'choice2' => '1', 'choice3' => '1')));
+    }
+
+    public function test_is_gradable_response() {
+        $question = test_question_maker::make_a_multichoice_multi_question();
+        $question->start_attempt(new question_attempt_step(), 1);
+
+        $this->assertFalse($question->is_gradable_response(array()));
+        $this->assertFalse($question->is_gradable_response(
+                array('choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0')));
+        $this->assertTrue($question->is_gradable_response(array('choice1' => '1')));
+        $this->assertTrue($question->is_gradable_response(
+                array('choice0' => '1', 'choice1' => '1', 'choice2' => '1', 'choice3' => '1')));
+    }
+
+    public function test_is_same_response() {
+        $question = test_question_maker::make_a_multichoice_multi_question();
+        $question->start_attempt(new question_attempt_step(), 1);
+
+        $this->assertTrue($question->is_same_response(
+                array(),
+                array('choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0')));
+
+        $this->assertTrue($question->is_same_response(
+                array('choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0'),
+                array('choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0')));
+
+        $this->assertFalse($question->is_same_response(
+                array('choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0'),
+                array('choice0' => '1', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0')));
+
+        $this->assertTrue($question->is_same_response(
+                array('choice0' => '1', 'choice1' => '0', 'choice2' => '1', 'choice3' => '0'),
+                array('choice0' => '1', 'choice1' => '0', 'choice2' => '1', 'choice3' => '0')));
+    }
+
+    public function test_grading() {
+        $question = test_question_maker::make_a_multichoice_multi_question();
+        $question->shuffleanswers = false;
+        $question->start_attempt(new question_attempt_step(), 1);
+
+        $this->assertEquals(array(1, question_state::$gradedright),
+                $question->grade_response(array('choice0' => '1', 'choice2' => '1')));
+        $this->assertEquals(array(0.5, question_state::$gradedpartial),
+                $question->grade_response(array('choice0' => '1')));
+        $this->assertEquals(array(0, question_state::$gradedwrong),
+                $question->grade_response(
+                        array('choice0' => '1', 'choice1' => '1', 'choice2' => '1')));
+        $this->assertEquals(array(0, question_state::$gradedwrong),
+                $question->grade_response(array('choice1' => '1')));
+    }
+
+    public function test_get_correct_response() {
+        $question = test_question_maker::make_a_multichoice_multi_question();
+        $question->shuffleanswers = false;
+        $question->start_attempt(new question_attempt_step(), 1);
+
+        $this->assertEquals(array('choice0' => '1', 'choice2' => '1'),
+                $question->get_correct_response());
+    }
+
+    public function test_get_question_summary() {
+        $mc = test_question_maker::make_a_multichoice_single_question();
+        $mc->start_attempt(new question_attempt_step(), 1);
+
+        $qsummary = $mc->get_question_summary();
+
+        $this->assertRegExp('/' . preg_quote($mc->questiontext, '/') . '/', $qsummary);
+        foreach ($mc->answers as $answer) {
+            $this->assertRegExp('/' . preg_quote($answer->answer, '/') . '/', $qsummary);
+        }
+    }
+
+    public function test_summarise_response() {
+        $mc = test_question_maker::make_a_multichoice_multi_question();
+        $mc->shuffleanswers = false;
+        $mc->start_attempt(new question_attempt_step(), 1);
+
+        $summary = $mc->summarise_response(array('choice1' => 1, 'choice2' => 1),
+                test_question_maker::get_a_qa($mc));
+
+        $this->assertEquals('B; C', $summary);
+    }
+
+    public function test_classify_response() {
+        $mc = test_question_maker::make_a_multichoice_multi_question();
+        $mc->shuffleanswers = false;
+        $mc->start_attempt(new question_attempt_step(), 1);
+
+        $this->assertEquals(array(
+                    13 => new question_classified_response(13, 'A', 0.5),
+                    14 => new question_classified_response(14, 'B', -1.0),
+                ), $mc->classify_response(array('choice0' => 1, 'choice1' => 1)));
+
+        $this->assertEquals(array(), $mc->classify_response(array()));
+    }
+}
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Unit tests for the multiple choice question definition classes.
+ * Unit tests for the multiple choice, single response question definition classes.
  *
- * @package    qtype
- * @subpackage multichoice
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @package   qtype_multichoice
+ * @copyright 2009 The Open University
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-
 defined('MOODLE_INTERNAL') || die();
 
 global $CFG;
@@ -31,10 +29,10 @@ require_once($CFG->dirroot . '/question/engine/tests/helpers.php');
 
 
 /**
- * Unit tests for the multiple choice, multiple response question definition class.
+ * Unit tests for the multiple choice, single response question definition class.
  *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @copyright 2009 The Open University
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class qtype_multichoice_single_question_test extends advanced_testcase {
 
@@ -59,6 +57,31 @@ class qtype_multichoice_single_question_test extends advanced_testcase {
         $this->assertTrue($question->is_gradable_response(array('answer' => '2')));
     }
 
+    public function test_is_same_response() {
+        $question = test_question_maker::make_a_multichoice_single_question();
+        $question->start_attempt(new question_attempt_step(), 1);
+
+        $this->assertTrue($question->is_same_response(
+                array(),
+                array()));
+
+        $this->assertFalse($question->is_same_response(
+                array(),
+                array('answer' => '0')));
+
+        $this->assertTrue($question->is_same_response(
+                array('answer' => '0'),
+                array('answer' => '0')));
+
+        $this->assertFalse($question->is_same_response(
+                array('answer' => '0'),
+                array('answer' => '1')));
+
+        $this->assertTrue($question->is_same_response(
+                array('answer' => '2'),
+                array('answer' => '2')));
+    }
+
     public function test_grading() {
         $question = test_question_maker::make_a_multichoice_single_question();
         $question->shuffleanswers = false;
@@ -151,106 +174,3 @@ class qtype_multichoice_single_question_test extends advanced_testcase {
         $this->assertEquals('Frog<br />†', $mc->make_html_inline('<p>Frog</p><p>†</p>'));
     }
 }
-
-
-/**
- * Unit tests for the multiple choice, single response question definition class.
- *
- * @copyright  2009 The Open University
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class qtype_multichoice_multi_question_test extends advanced_testcase {
-
-    public function test_get_expected_data() {
-        $question = test_question_maker::make_a_multichoice_multi_question();
-        $question->start_attempt(new question_attempt_step(), 1);
-
-        $this->assertEquals(array('choice0' => PARAM_BOOL, 'choice1' => PARAM_BOOL,
-                'choice2' => PARAM_BOOL, 'choice3' => PARAM_BOOL), $question->get_expected_data());
-    }
-
-    public function test_is_complete_response() {
-        $question = test_question_maker::make_a_multichoice_multi_question();
-        $question->start_attempt(new question_attempt_step(), 1);
-
-        $this->assertFalse($question->is_complete_response(array()));
-        $this->assertFalse($question->is_complete_response(
-                array('choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0')));
-        $this->assertTrue($question->is_complete_response(array('choice1' => '1')));
-        $this->assertTrue($question->is_complete_response(
-                array('choice0' => '1', 'choice1' => '1', 'choice2' => '1', 'choice3' => '1')));
-    }
-
-    public function test_is_gradable_response() {
-        $question = test_question_maker::make_a_multichoice_multi_question();
-        $question->start_attempt(new question_attempt_step(), 1);
-
-        $this->assertFalse($question->is_gradable_response(array()));
-        $this->assertFalse($question->is_gradable_response(
-                array('choice0' => '0', 'choice1' => '0', 'choice2' => '0', 'choice3' => '0')));
-        $this->assertTrue($question->is_gradable_response(array('choice1' => '1')));
-        $this->assertTrue($question->is_gradable_response(
-                array('choice0' => '1', 'choice1' => '1', 'choice2' => '1', 'choice3' => '1')));
-    }
-
-    public function test_grading() {
-        $question = test_question_maker::make_a_multichoice_multi_question();
-        $question->shuffleanswers = false;
-        $question->start_attempt(new question_attempt_step(), 1);
-
-        $this->assertEquals(array(1, question_state::$gradedright),
-                $question->grade_response(array('choice0' => '1', 'choice2' => '1')));
-        $this->assertEquals(array(0.5, question_state::$gradedpartial),
-                $question->grade_response(array('choice0' => '1')));
-        $this->assertEquals(array(0, question_state::$gradedwrong),
-                $question->grade_response(
-                        array('choice0' => '1', 'choice1' => '1', 'choice2' => '1')));
-        $this->assertEquals(array(0, question_state::$gradedwrong),
-                $question->grade_response(array('choice1' => '1')));
-    }
-
-    public function test_get_correct_response() {
-        $question = test_question_maker::make_a_multichoice_multi_question();
-        $question->shuffleanswers = false;
-        $question->start_attempt(new question_attempt_step(), 1);
-
-        $this->assertEquals(array('choice0' => '1', 'choice2' => '1'),
-                $question->get_correct_response());
-    }
-
-    public function test_get_question_summary() {
-        $mc = test_question_maker::make_a_multichoice_single_question();
-        $mc->start_attempt(new question_attempt_step(), 1);
-
-        $qsummary = $mc->get_question_summary();
-
-        $this->assertRegExp('/' . preg_quote($mc->questiontext, '/') . '/', $qsummary);
-        foreach ($mc->answers as $answer) {
-            $this->assertRegExp('/' . preg_quote($answer->answer, '/') . '/', $qsummary);
-        }
-    }
-
-    public function test_summarise_response() {
-        $mc = test_question_maker::make_a_multichoice_multi_question();
-        $mc->shuffleanswers = false;
-        $mc->start_attempt(new question_attempt_step(), 1);
-
-        $summary = $mc->summarise_response(array('choice1' => 1, 'choice2' => 1),
-                test_question_maker::get_a_qa($mc));
-
-        $this->assertEquals('B; C', $summary);
-    }
-
-    public function test_classify_response() {
-        $mc = test_question_maker::make_a_multichoice_multi_question();
-        $mc->shuffleanswers = false;
-        $mc->start_attempt(new question_attempt_step(), 1);
-
-        $this->assertEquals(array(
-                    13 => new question_classified_response(13, 'A', 0.5),
-                    14 => new question_classified_response(14, 'B', -1.0),
-                ), $mc->classify_response(array('choice0' => 1, 'choice1' => 1)));
-
-        $this->assertEquals(array(), $mc->classify_response(array()));
-    }
-}
index 2d290aa..995de5c 100644 (file)
@@ -206,7 +206,8 @@ class qtype_numerical extends question_type {
             }
             $options->question = $question->id;
             $options->answer   = $answer->id;
-            if (trim($question->tolerance[$key]) == '') {
+            // When the answer is * the tolerance can be absent i.e. in multianswer.
+            if (!isset($question->tolerance[$key]) || trim($question->tolerance[$key]) == '') {
                 $options->tolerance = '';
             } else {
                 $options->tolerance = $this->apply_unit($question->tolerance[$key],
index 6d61971..35075ba 100644 (file)
@@ -473,25 +473,8 @@ class question_type {
         $oldhints = $DB->get_records('question_hints',
                 array('questionid' => $formdata->id), 'id ASC');
 
-        if (!empty($formdata->hint)) {
-            $numhints = max(array_keys($formdata->hint)) + 1;
-        } else {
-            $numhints = 0;
-        }
 
-        if ($withparts) {
-            if (!empty($formdata->hintclearwrong)) {
-                $numclears = max(array_keys($formdata->hintclearwrong)) + 1;
-            } else {
-                $numclears = 0;
-            }
-            if (!empty($formdata->hintshownumcorrect)) {
-                $numshows = max(array_keys($formdata->hintshownumcorrect)) + 1;
-            } else {
-                $numshows = 0;
-            }
-            $numhints = max($numhints, $numclears, $numshows);
-        }
+        $numhints = $this->count_hints_on_form($formdata, $withparts);
 
         for ($i = 0; $i < $numhints; $i += 1) {
             if (html_is_blank($formdata->hint[$i]['text'])) {
@@ -503,8 +486,7 @@ class question_type {
                 $shownumcorrect = !empty($formdata->hintshownumcorrect[$i]);
             }
 
-            if (empty($formdata->hint[$i]['text']) && empty($clearwrong) &&
-                    empty($shownumcorrect)) {
+            if ($this->is_hint_empty_in_form_data($formdata, $i, $withparts)) {
                 continue;
             }
 
@@ -524,6 +506,7 @@ class question_type {
                 $hint->clearwrong = $clearwrong;
                 $hint->shownumcorrect = $shownumcorrect;
             }
+            $hint->options = $this->save_hint_options($formdata, $i, $withparts);
             $DB->update_record('question_hints', $hint);
         }
 
@@ -535,6 +518,65 @@ class question_type {
         }
     }
 
+    /**
+     * Count number of hints on the form.
+     * Overload if you use custom hint controls.
+     * @param object $formdata the data from the form.
+     * @param bool $withparts whether to take into account clearwrong and shownumcorrect options.
+     * @return int count of hints on the form.
+     */
+    protected function count_hints_on_form($formdata, $withparts) {
+        if (!empty($formdata->hint)) {
+            $numhints = max(array_keys($formdata->hint)) + 1;
+        } else {
+            $numhints = 0;
+        }
+
+        if ($withparts) {
+            if (!empty($formdata->hintclearwrong)) {
+                $numclears = max(array_keys($formdata->hintclearwrong)) + 1;
+            } else {
+                $numclears = 0;
+            }
+            if (!empty($formdata->hintshownumcorrect)) {
+                $numshows = max(array_keys($formdata->hintshownumcorrect)) + 1;
+            } else {
+                $numshows = 0;
+            }
+            $numhints = max($numhints, $numclears, $numshows);
+        }
+        return $numhints;
+    }
+
+    /**
+     * Determine if the hint with specified number is not empty and should be saved.
+     * Overload if you use custom hint controls.
+     * @param object $formdata the data from the form.
+     * @param int $number number of hint under question.
+     * @param bool $withparts whether to take into account clearwrong and shownumcorrect options.
+     * @return bool is this particular hint data empty.
+     */
+    protected function is_hint_empty_in_form_data($formdata, $number, $withparts) {
+        if ($withparts) {
+            return empty($formdata->hint[$number]['text']) && empty($formdata->hintclearwrong[$number]) &&
+                    empty($formdata->hintshownumcorrect[$number]);
+        } else {
+            return  empty($formdata->hint[$number]['text']);
+        }
+    }
+
+    /**
+     * Save additional question type data into the hint optional field.
+     * Overload if you use custom hint information.
+     * @param object $formdata the data from the form.
+     * @param int $number number of hint to get options from.
+     * @param bool $withparts whether question have parts.
+     * @return string value to save into the options field of question_hints table.
+     */
+    protected function save_hint_options($formdata, $number, $withparts) {
+        return null;    // By default, options field is unused.
+    }
+
     /**
      * Can be used to {@link save_question_options()} to transfer the combined
      * feedback fields from $formdata to $options.
index 842f847..58a49cb 100644 (file)
@@ -130,6 +130,7 @@ if ($type === "usercourse.png") {
 
    $graph = new graph(750, 400);
 
+   $a = new stdClass();
    $a->coursename = format_string($course->shortname, true, array('context' => $coursecontext));
    $a->username = fullname($user, true);
    $graph->parameter['title'] = get_string("hitsoncourse", "", $a);
@@ -191,6 +192,7 @@ if ($type === "usercourse.png") {
 
    $graph = new graph(750, 400);
 
+   $a = new stdClass();
    $a->coursename = format_string($course->shortname, true, array('context' => $coursecontext));
    $a->username = fullname($user, true);
    $graph->parameter['title'] = get_string("hitsoncoursetoday", "", $a);
index c8ec1e4..3931e71 100644 (file)
@@ -44,7 +44,7 @@ function report_progress_extend_navigation_course($navigation, $course, $context
     }
 
     $completion = new completion_info($course);
-    $showonnavigation = ($showonnavigation && $completion->is_enabled() && count($completion->get_activities())>0);
+    $showonnavigation = ($showonnavigation && $completion->is_enabled() && $completion->has_activities());
     if ($showonnavigation) {
         $url = new moodle_url('/report/progress/index.php', array('course'=>$course->id));
         $navigation->add(get_string('pluginname','report_progress'), $url, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/report', ''));
index aba395f..8ddf895 100644 (file)
@@ -32,7 +32,7 @@
 $THEME->doctype = 'html5';
 $THEME->yuicssmodules = array();
 $THEME->name = 'bootstrapbase';
-$THEME->parents = array('');
+$THEME->parents = array();
 $THEME->sheets = array('moodle');
 $THEME->supportscssoptimisation = false;
 
@@ -52,115 +52,112 @@ $THEME->rendererfactory = 'theme_overridden_renderer_factory';
 $THEME->layouts = array(
     // Most backwards compatible layout without the blocks - this is the layout used by default.
     'base' => array(
-        'file' => 'general.php',
+        'file' => 'columns1.php',
         'regions' => array(),
     ),
     // Standard layout with blocks, this is recommended for most pages with general information.
     'standard' => array(
-        'file' => 'general.php',
+        'file' => 'columns3.php',
         'regions' => array('side-pre', 'side-post'),
         'defaultregion' => 'side-pre',
     ),
     // Main course page.
     'course' => array(
-        'file' => 'general.php',
+        'file' => 'columns3.php',
         'regions' => array('side-pre', 'side-post'),
         'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     'coursecategory' => array(
-        'file' => 'general.php',
+        'file' => 'columns3.php',
         'regions' => array('side-pre', 'side-post'),
         'defaultregion' => 'side-pre',
     ),
     // part of course, typical for modules - default page layout if $cm specified in require_login()
     'incourse' => array(
-        'file' => 'general.php',
+        'file' => 'columns3.php',
         'regions' => array('side-pre', 'side-post'),
         'defaultregion' => 'side-pre',
     ),
     // The site home page.
     'frontpage' => array(
-        'file' => 'general.php',
+        'file' => 'columns3.php',
         'regions' => array('side-pre', 'side-post'),
         'defaultregion' => 'side-pre',
         'options' => array('nonavbar'=>true),
     ),
     // Server administration scripts.
     'admin' => array(
-        'file' => 'general.php',
+        'file' => 'columns2.php',
         'regions' => array('side-pre'),
         'defaultregion' => 'side-pre',
     ),
     // My dashboard page.
     'mydashboard' => array(
-        'file' => 'general.php',
+        'file' => 'columns3.php',
         'regions' => array('side-pre', 'side-post'),
         'defaultregion' => 'side-pre',
         'options' => array('langmenu'=>true),
     ),
     // My public page.
     'mypublic' => array(
-        'file' => 'general.php',
+        'file' => 'columns3.php',
         'regions' => array('side-pre', 'side-post'),
         'defaultregion' => 'side-pre',
     ),
     'login' => array(
-        'file' => 'general.php',
+        'file' => 'columns1.php',
         'regions' => array(),
         'options' => array('langmenu'=>true),
     ),
 
     // Pages that appear in pop-up windows - no navigation, no blocks, no header.
     'popup' => array(
-        'file' => 'general.php',
+        'file' => 'columns1.php',
         'regions' => array(),
-        'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocustommenu'=>true, 'nologininfo'=>true, 'nocourseheaderfooter'=>true),
+        'options' => array('nofooter'=>true, 'nonavbar'=>true),
     ),
     // No blocks and minimal footer - used for legacy frame layouts only!
     'frametop' => array(
-        'file' => 'general.php',
+        'file' => 'columns1.php',
         'regions' => array(),
         'options' => array('nofooter'=>true, 'nocoursefooter'=>true),
     ),
     // Embeded pages, like iframe/object embeded in moodleform - it needs as much space as possible
     'embedded' => array(
         'file' => 'embedded.php',
-        'regions' => array(),
-        'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocustommenu'=>true, 'nocourseheaderfooter'=>true),
+        'regions' => array()
     ),
     // Used during upgrade and install, and for the 'This site is undergoing maintenance' message.
     // This must not have any blocks, and it is good idea if it does not have links to
     // other places - for example there should not be a home link in the footer...
     'maintenance' => array(
-        'file' => 'general.php',
+        'file' => 'columns1.php',
         'regions' => array(),
-        'options' => array('noblocks'=>true, 'nofooter'=>true, 'nonavbar'=>true, 'nocustommenu'=>true, 'nocourseheaderfooter'=>true),
+        'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocoursefooter'=>true, 'nocourseheader'=>true),
     ),
     // Should display the content and basic headers only.
     'print' => array(
-        'file' => 'general.php',
+        'file' => 'columns1.php',
         'regions' => array(),
-        'options' => array('noblocks'=>true, 'nofooter'=>true, 'nonavbar'=>false, 'nocustommenu'=>true, 'nocourseheaderfooter'=>true),
+        'options' => array('nofooter'=>true, 'nonavbar'=>false),
     ),
     // The pagelayout used when a redirection is occuring.
     'redirect' => array(
         'file' => 'embedded.php',
         'regions' => array(),
-        'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocustommenu'=>true, 'nocourseheaderfooter'=>true),
     ),
     // The pagelayout used for reports.
     'report' => array(
-        'file' => 'general.php',
+        'file' => 'columns2.php',
         'regions' => array('side-pre'),
         'defaultregion' => 'side-pre',
     ),
     // The pagelayout used for safebrowser and securewindow.
     'secure' => array(
-        'file' => 'general.php',
+        'file' => 'secure.php',
         'regions' => array('side-pre', 'side-post'),
-        'defaultregion' => 'side-pre',
-        'options' => array('nofooter'=>true, 'nonavbar'=>true, 'nocustommenu'=>true, 'nologinlinks'=>true, 'nocourseheaderfooter'=>true),
+        'defaultregion' => 'side-pre'
     ),
 );
 
@@ -170,12 +167,13 @@ $THEME->javascripts_footer = array(
     'moodlebootstrap',
 );
 
-$useragent = '';
-if (!empty($_SERVER['HTTP_USER_AGENT'])) {
-    $useragent = $_SERVER['HTTP_USER_AGENT'];
-}
-if (strpos($useragent, 'MSIE 8') || strpos($useragent, 'MSIE 7')) {
+if (check_browser_version('MSIE') && !check_browser_version('MSIE', '9.0')) {
     $THEME->javascripts[] = 'html5shiv';
 }
 
 $THEME->hidefromselector = true;
+
+$THEME->blockrtlmanipulations = array(
+    'side-pre' => 'side-post',
+    'side-post' => 'side-pre'
+);
diff --git a/theme/bootstrapbase/layout/columns1.php b/theme/bootstrapbase/layout/columns1.php
new file mode 100644 (file)
index 0000000..2d3f417
--- /dev/null
@@ -0,0 +1,89 @@
+<?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/>.
+
+echo $OUTPUT->doctype() ?>
+<html <?php echo $OUTPUT->htmlattributes(); ?>>
+<head>
+    <title><?php echo $OUTPUT->page_title(); ?></title>
+    <link rel="shortcut icon" href="<?php echo $OUTPUT->favicon(); ?>" />
+    <?php echo $OUTPUT->standard_head_html() ?>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
+
+<body <?php echo $OUTPUT->body_attributes(); ?>>
+
+<?php echo $OUTPUT->standard_top_of_body_html() ?>
+
+<header role="banner" class="navbar navbar-fixed-top">
+    <nav role="navigation" class="navbar-inner">
+        <div class="container-fluid">
+            <a class="brand" href="<?php echo $CFG->wwwroot;?>"><?php echo $SITE->shortname; ?></a>
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </a>
+            <div class="nav-collapse collapse">
+                <?php echo $OUTPUT->custom_menu(); ?>
+                <ul class="nav pull-right">
+                    <li><?php echo $OUTPUT->page_heading_menu(); ?></li>
+                    <li class="navbar-text"><?php echo $OUTPUT->login_info() ?></li>
+                </ul>
+            </div>
+        </div>
+    </nav>
+</header>
+
+<div id="page" class="container-fluid">
+
+    <header id="page-header" class="clearfix">
+        <div id="page-navbar">
+            <nav class="breadcrumb-button"><?php echo $OUTPUT->page_heading_button(); ?></nav>
+            <?php echo $OUTPUT->navbar(); ?>
+        </div>
+        <?php echo $OUTPUT->page_heading(); ?>
+        <div id="course-header">
+            <?php echo $OUTPUT->course_header(); ?>
+        </div>
+    </header>
+
+    <div id="page-content">
+        <div id="region-bs-main-and-pre">
+            <section id="region-main">
+                <?php
+                echo $OUTPUT->course_content_header();
+                echo $OUTPUT->main_content();
+                echo $OUTPUT->course_content_footer();
+                ?>
+            </section>
+        </div>
+    </div>
+
+    <footer id="page-footer">
+        <div id="course-footer"><?php echo $OUTPUT->course_footer(); ?></div>
+        <p class="helplink"><?php echo $OUTPUT->page_doc_link(); ?></p>
+        <?php
+        echo $OUTPUT->login_info();
+        echo $OUTPUT->home_link();
+        echo $OUTPUT->standard_footer_html();
+        ?>
+    </footer>
+
+    <?php echo $OUTPUT->standard_end_of_body_html() ?>
+
+</div>
+</body>
+</html>
diff --git a/theme/bootstrapbase/layout/columns2.php b/theme/bootstrapbase/layout/columns2.php
new file mode 100644 (file)
index 0000000..eba9f85
--- /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/>.
+
+echo $OUTPUT->doctype() ?>
+<html <?php echo $OUTPUT->htmlattributes(); ?>>
+<head>
+    <title><?php echo $OUTPUT->page_title(); ?></title>
+    <link rel="shortcut icon" href="<?php echo $OUTPUT->favicon(); ?>" />
+    <?php echo $OUTPUT->standard_head_html() ?>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
+
+<body <?php echo $OUTPUT->body_attributes('two-column'); ?>>
+
+<?php echo $OUTPUT->standard_top_of_body_html() ?>
+
+<header role="banner" class="navbar navbar-fixed-top">
+    <nav role="navigation" class="navbar-inner">
+        <div class="container-fluid">
+            <a class="brand" href="<?php echo $CFG->wwwroot;?>"><?php echo $SITE->shortname; ?></a>
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </a>
+            <div class="nav-collapse collapse">
+                <?php echo $OUTPUT->custom_menu(); ?>
+                <ul class="nav pull-right">
+                    <li><?php echo $OUTPUT->page_heading_menu(); ?></li>
+                    <li class="navbar-text"><?php echo $OUTPUT->login_info() ?></li>
+                </ul>
+            </div>
+        </div>
+    </nav>
+</header>
+
+<div id="page" class="container-fluid">
+
+    <header id="page-header" class="clearfix">
+        <div id="page-navbar">
+            <nav class="breadcrumb-button"><?php echo $OUTPUT->page_heading_button(); ?></nav>
+            <?php echo $OUTPUT->navbar(); ?>
+        </div>
+        <?php echo $OUTPUT->page_heading(); ?>
+        <div id="course-header">
+            <?php echo $OUTPUT->course_header(); ?>
+        </div>
+    </header>
+
+    <div id="page-content" class="row-fluid">
+        <div id="region-bs-main-and-pre" class="span9">
+            <div class="row-fluid">
+                <section id="region-main" class="span9 pull-right">
+                    <?php
+                    echo $OUTPUT->course_content_header();
+                    echo $OUTPUT->main_content();
+                    echo $OUTPUT->course_content_footer();
+                    ?>
+                </section>
+                <?php
+                if (!right_to_left()) {
+                    echo $OUTPUT->blocks('side-pre', 'span3 desktop-first-column');
+                } ?>
+            </div>
+        </div>
+        <?php
+        if (right_to_left()) {
+            echo $OUTPUT->blocks('side-post', 'span3');
+        }
+        ?>
+    </div>
+
+    <footer id="page-footer">
+        <div id="course-footer"><?php echo $OUTPUT->course_footer(); ?></div>
+        <p class="helplink"><?php echo $OUTPUT->page_doc_link(); ?></p>
+        <?php
+        echo $OUTPUT->login_info();
+        echo $OUTPUT->home_link();
+        echo $OUTPUT->standard_footer_html();
+        ?>
+    </footer>
+
+    <?php echo $OUTPUT->standard_end_of_body_html() ?>
+
+</div>
+</body>
+</html>
diff --git a/theme/bootstrapbase/layout/columns3.php b/theme/bootstrapbase/layout/columns3.php
new file mode 100644 (file)
index 0000000..3df8db2
--- /dev/null
@@ -0,0 +1,93 @@
+<?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/>.
+
+echo $OUTPUT->doctype() ?>
+<html <?php echo $OUTPUT->htmlattributes(); ?>>
+<head>
+    <title><?php echo $OUTPUT->page_title(); ?></title>
+    <link rel="shortcut icon" href="<?php echo $OUTPUT->favicon(); ?>" />
+    <?php echo $OUTPUT->standard_head_html() ?>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
+
+<body <?php echo $OUTPUT->body_attributes(); ?>>
+
+<?php echo $OUTPUT->standard_top_of_body_html() ?>
+
+<header role="banner" class="navbar navbar-fixed-top">
+    <nav role="navigation" class="navbar-inner">
+        <div class="container-fluid">
+            <a class="brand" href="<?php echo $CFG->wwwroot;?>"><?php echo $SITE->shortname; ?></a>
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </a>
+            <div class="nav-collapse collapse">
+                <?php echo $OUTPUT->custom_menu(); ?>
+                <ul class="nav pull-right">
+                    <li><?php echo $OUTPUT->page_heading_menu(); ?></li>
+                    <li class="navbar-text"><?php echo $OUTPUT->login_info() ?></li>
+                </ul>
+            </div>
+        </div>
+    </nav>
+</header>
+
+<div id="page" class="container-fluid">
+
+    <header id="page-header" class="clearfix">
+        <div id="page-navbar">
+            <nav class="breadcrumb-button"><?php echo $OUTPUT->page_heading_button(); ?></nav>
+            <?php echo $OUTPUT->navbar(); ?>
+        </div>
+        <?php echo $OUTPUT->page_heading(); ?>
+        <div id="course-header">
+            <?php echo $OUTPUT->course_header(); ?>
+        </div>
+    </header>
+
+    <div id="page-content" class="row-fluid">
+        <div id="region-bs-main-and-pre" class="span9">
+            <div class="row-fluid">
+                <section id="region-main" class="span8 pull-right">
+                    <?php
+                    echo $OUTPUT->course_content_header();
+                    echo $OUTPUT->main_content();
+                    echo $OUTPUT->course_content_footer();
+                    ?>
+                </section>
+                <?php echo $OUTPUT->blocks('side-pre', 'span4 desktop-first-column'); ?>
+            </div>
+        </div>
+        <?php echo $OUTPUT->blocks('side-post', 'span3'); ?>
+    </div>
+
+    <footer id="page-footer">
+        <div id="course-footer"><?php echo $OUTPUT->course_footer(); ?></div>
+        <p class="helplink"><?php echo $OUTPUT->page_doc_link(); ?></p>
+        <?php
+        echo $OUTPUT->login_info();
+        echo $OUTPUT->home_link();
+        echo $OUTPUT->standard_footer_html();
+        ?>
+    </footer>
+
+    <?php echo $OUTPUT->standard_end_of_body_html() ?>
+
+</div>
+</body>
+</html>
index a802fbb..821ae91 100644 (file)
@@ -1,23 +1,35 @@
-<?php echo $OUTPUT->doctype() ?>
-<html <?php echo $OUTPUT->htmlattributes() ?>>
+<?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/>.
+
+echo $OUTPUT->doctype() ?>
+<html <?php echo $OUTPUT->htmlattributes(); ?>>
 <head>
-    <title><?php echo $PAGE->title ?></title>
-    <link rel="shortcut icon" href="<?php echo $OUTPUT->pix_url('favicon', 'theme')?>" />
+    <title><?php echo $OUTPUT->page_title(); ?></title>
+    <link rel="shortcut icon" href="<?php echo $OUTPUT->favicon(); ?>" />
     <?php echo $OUTPUT->standard_head_html() ?>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 </head>
-<body id="<?php p($PAGE->bodyid) ?>" class="<?php p($PAGE->bodyclasses) ?>">
-<?php echo $OUTPUT->standard_top_of_body_html() ?>
 
+<body <?php echo $OUTPUT->body_attributes(); ?>>
+<?php echo $OUTPUT->standard_top_of_body_html() ?>
 <div id="page">
-
-<!-- END OF HEADER -->
-
-    <div id="content" class="clearfix">
-        <?php echo $OUTPUT->main_content() ?>
+    <div id="page-content" class="clearfix">
+        <?php echo $OUTPUT->main_content(); ?>
     </div>
-
-<!-- START OF FOOTER -->
 </div>
 <?php echo $OUTPUT->standard_end_of_body_html() ?>
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/theme/bootstrapbase/layout/general.php b/theme/bootstrapbase/layout/general.php
deleted file mode 100644 (file)
index fe59117..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-<?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/>.
-
-$hasheading = ($PAGE->heading);
-$hasnavbar = (empty($PAGE->layout_options['nonavbar']) && $PAGE->has_navbar());
-$hasfooter = (empty($PAGE->layout_options['nofooter']));
-$hasheader = (empty($PAGE->layout_options['noheader']));
-
-$hassidepre = (empty($PAGE->layout_options['noblocks']) && $PAGE->blocks->region_has_content('side-pre', $OUTPUT));
-$hassidepost = (empty($PAGE->layout_options['noblocks']) && $PAGE->blocks->region_has_content('side-post', $OUTPUT));
-
-$showsidepre = ($hassidepre && !$PAGE->blocks->region_completely_docked('side-pre', $OUTPUT));
-$showsidepost = ($hassidepost && !$PAGE->blocks->region_completely_docked('side-post', $OUTPUT));
-
-// If there can be a sidepost region on this page and we are editing, always
-// show it so blocks can be dragged into it.
-if ($PAGE->user_is_editing()) {
-    if ($PAGE->blocks->is_known_region('side-pre')) {
-        $showsidepre = true;
-    }
-    if ($PAGE->blocks->is_known_region('side-post')) {
-        $showsidepost = true;
-    }
-}
-
-$custommenu = $OUTPUT->custom_menu();
-$hascustommenu = (empty($PAGE->layout_options['nocustommenu']) && !empty($custommenu));
-
-$courseheader = $coursecontentheader = $coursecontentfooter = $coursefooter = '';
-
-if (empty($PAGE->layout_options['nocourseheaderfooter'])) {
-    $courseheader = $OUTPUT->course_header();
-    $coursecontentheader = $OUTPUT->course_content_header();
-    if (empty($PAGE->layout_options['nocoursefooter'])) {
-        $coursecontentfooter = $OUTPUT->course_content_footer();
-        $coursefooter = $OUTPUT->course_footer();
-    }
-}
-
-$layout = 'pre-and-post';
-if ($showsidepre && !$showsidepost) {
-    if (!right_to_left()) {
-        $layout = 'side-pre-only';
-    } else {
-        $layout = 'side-post-only';
-    }
-} else if ($showsidepost && !$showsidepre) {
-    if (!right_to_left()) {
-        $layout = 'side-post-only';
-    } else {
-        $layout = 'side-pre-only';
-    }
-} else if (!$showsidepost && !$showsidepre) {
-    $layout = 'content-only';
-}
-$bodyclasses[] = $layout;
-
-echo $OUTPUT->doctype() ?>
-<html <?php echo $OUTPUT->htmlattributes() ?>>
-<head>
-    <title><?php echo $PAGE->title ?></title>
-    <link rel="shortcut icon" href="<?php echo $OUTPUT->pix_url('favicon', 'theme')?>" />
-    <?php echo $OUTPUT->standard_head_html() ?>
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-</head>
-
-<body id="<?php p($PAGE->bodyid) ?>" class="<?php p($PAGE->bodyclasses.' '.join($bodyclasses)) ?>">
-
-<?php echo $OUTPUT->standard_top_of_body_html() ?>
-
-<header role="banner" class="navbar navbar-fixed-top">
-    <nav role="navigation" class="navbar-inner">
-        <div class="container-fluid">
-            <a class="brand" href="<?php echo $CFG->wwwroot;?>"><?php echo $SITE->shortname; ?></a>
-            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
-                <span class="icon-bar"></span>
-                <span class="icon-bar"></span>
-                <span class="icon-bar"></span>
-            </a>
-            <div class="nav-collapse collapse">
-            <?php if ($hascustommenu) {
-                echo $custommenu;
-            } ?>
-            <ul class="nav pull-right">
-            <li><?php echo $PAGE->headingmenu ?></li>
-            <li class="navbar-text"><?php echo $OUTPUT->login_info() ?></li>
-            </ul>
-            </div>
-        </div>
-    </nav>
-</header>
-
-<div id="page" class="container-fluid">
-
-<?php if ($hasheader) { ?>
-<header id="page-header" class="clearfix">
-    <?php if ($hasnavbar) { ?>
-        <nav class="breadcrumb-button"><?php echo $PAGE->button; ?></nav>
-        <?php echo $OUTPUT->navbar(); ?>
-    <?php } ?>
-    <h1><?php echo $PAGE->heading ?></h1>
-
-    <?php if (!empty($courseheader)) { ?>
-        <div id="course-header"><?php echo $courseheader; ?></div>
-    <?php } ?>
-</header>
-<?php } ?>
-
-<div id="page-content" class="row-fluid">
-
-<?php if ($layout === 'pre-and-post') { ?>
-    <div id="region-bs-main-and-pre" class="span9">
-    <div class="row-fluid">
-    <section id="region-main" class="span8 pull-right">
-<?php } else if ($layout === 'side-post-only') { ?>
-    <section id="region-main" class="span9">
-<?php } else if ($layout === 'side-pre-only') { ?>
-    <section id="region-main" class="span9 pull-right">
-<?php } else if ($layout === 'content-only') { ?>
-    <section id="region-main" class="span12">
-<?php } ?>
-
-
-    <?php echo $coursecontentheader; ?>
-    <?php echo $OUTPUT->main_content() ?>
-    <?php echo $coursecontentfooter; ?>
-    </section>
-
-
-<?php if ($layout !== 'content-only') {
-          if ($layout === 'pre-and-post') { ?>
-            <aside class="span4 desktop-first-column">
-    <?php } else if ($layout === 'side-pre-only') { ?>
-            <aside class="span3 desktop-first-column">
-    <?php } ?>
-          <div id="region-pre" class="block-region">
-          <div class="region-content">
-          <?php
-                if (!right_to_left()) {
-                    echo $OUTPUT->blocks_for_region('side-pre');
-                } else if ($hassidepost) {
-                    echo $OUTPUT->blocks_for_region('side-post');
-                } ?>
-          </div>
-          </div>
-          </aside>
-    <?php if ($layout === 'pre-and-post') {
-          ?></div></div><?php // Close row-fluid and span9.
-   }
-
-    if ($layout === 'side-post-only' OR $layout === 'pre-and-post') { ?>
-        <aside class="span3">
-        <div id="region-post" class="block-region">
-        <div class="region-content">
-        <?php if (!right_to_left()) {
-                  echo $OUTPUT->blocks_for_region('side-post');
-              } else {
-                  echo $OUTPUT->blocks_for_region('side-pre');
-              } ?>
-        </div>
-        </div>
-        </aside>
-    <?php } ?>
-<?php } ?>
-</div>
-
-<footer id="page-footer">
-    <p class="helplink"><?php echo page_doc_link(get_string('moodledocslink')) ?></p>
-    <?php echo $OUTPUT->standard_footer_html(); ?>
-</footer>
-
-<?php echo $OUTPUT->standard_end_of_body_html() ?>
-
-</div>
-</body>
-</html>
diff --git a/theme/bootstrapbase/layout/secure.php b/theme/bootstrapbase/layout/secure.php
new file mode 100644 (file)
index 0000000..eb3746b
--- /dev/null
@@ -0,0 +1,70 @@
+<?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/>.
+
+echo $OUTPUT->doctype() ?>
+<html <?php echo $OUTPUT->htmlattributes(); ?>>
+<head>
+    <title><?php echo $OUTPUT->page_title(); ?></title>
+    <link rel="shortcut icon" href="<?php echo $OUTPUT->favicon(); ?>" />
+    <?php echo $OUTPUT->standard_head_html() ?>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+</head>
+
+<body <?php echo $OUTPUT->body_attributes(); ?>>
+
+<?php echo $OUTPUT->standard_top_of_body_html() ?>
+
+<header role="banner" class="navbar navbar-fixed-top">
+    <nav role="navigation" class="navbar-inner">
+        <div class="container-fluid">
+            <a class="brand" href="<?php echo $CFG->wwwroot;?>"><?php echo $SITE->shortname; ?></a>
+            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+                <span class="icon-bar"></span>
+            </a>
+            <div class="nav-collapse collapse">
+                <ul class="nav pull-right">
+                    <li><?php echo $OUTPUT->page_heading_menu(); ?></li>
+                </ul>
+            </div>
+        </div>
+    </nav>
+</header>
+
+<div id="page" class="container-fluid">
+
+    <header id="page-header" class="clearfix">
+        <?php echo $OUTPUT->page_heading(); ?>
+    </header>
+
+    <div id="page-content" class="row-fluid">
+        <div id="region-bs-main-and-pre" class="span9">
+            <div class="row-fluid">
+                <section id="region-main" class="span8 pull-right">
+                    <?php echo $OUTPUT->main_content(); ?>
+                </section>
+                <?php echo $OUTPUT->blocks('side-pre', 'span4 desktop-first-column'); ?>
+            </div>
+        </div>
+        <?php echo $OUTPUT->blocks('side-post', 'span3'); ?>
+    </div>
+
+    <?php echo $OUTPUT->standard_end_of_body_html() ?>
+
+</div>
+</body>
+</html>
\ No newline at end of file
index 4ed8537..0384629 100644 (file)
@@ -1,3 +1,6 @@
+// Import the bootstrap variables.
+@import "bootstrap/variables.less";
+
 // Old Moodle stuff from base theme.
 // Massive, needs broken up.
 @import "moodle/core";
@@ -21,8 +24,9 @@
 // Increase form label width.
 @horizontalComponentOffset: 200px;
 // On Wider screens.
-@horizontalComponentOffset768: 220px;
-@horizontalComponentOffset980: 265px;
+@horizontalComponentOffset980: 220px;
+@horizontalComponentOffset1200: 265px;
+
 
 // Roll back nameclashes.
 @import "moodle/undo";
index d33480d..7b34db3 100644 (file)
@@ -1,4 +1,45 @@
 /* core.less */
+
+/** Page layout CSS starts **/
+.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;
+}
+
+.dir-ltr.two-column #region-bs-main-and-pre.span9,
+.dir-rtl.two-column #region-main.span9,
+.empty-region-side-post #region-bs-main-and-pre.span9 {
+    width:100%;
+}
+
+.empty-region-side-pre #region-main {
+    float:none;
+    width:100%;
+}
+
+.fluid-span (@columns) {
+    width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1));
+    *width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%);
+}
+
+.empty-region-side-post.used-region-side-pre #region-main.span8 {
+    /** increase the span size by 1 **/
+    .fluid-span(9);
+}
+.empty-region-side-post.used-region-side-pre #block-region-side-pre.span4 {
+    /** decrease the span size by 1 **/
+    .fluid-span(3);
+}
+/** Page layout CSS ends **/
+
 .dir-ltr,
 .mdl-left,
 .dir-rtl .mdl-right {
@@ -1845,3 +1886,9 @@ div.badge .expireimage {
 .addcourse {
     float: right;
 }
+.invisiblefieldset {
+    display: inline;
+    margin: 0;
+    padding: 0;
+    border-width: 0;
+}
index d142f3b..5904827 100644 (file)
@@ -813,6 +813,7 @@ a.ygtvspacer:hover {
 .filemanager-toolbar{
     padding: 5px 8px;
     min-height: 22px;
+    overflow: hidden;
 }
 .fp-pathbar {
     border-top: 1px solid #BBBBBB;
index d5bc457..0b1c034 100644 (file)
@@ -82,13 +82,6 @@ select {
     float: right;
 }
 
-.navbar .logininfo a {
-    color: @navbarLinkColor;
-}
-.navbar .logininfo a:hover {
-    background-color: @navbarLinkBackgroundHover; // "transparent" is default to differentiate :hover/:focus from .active
-    color: @navbarLinkColorHover;
-}
 .navbar-inverse .logininfo a {
     color: @navbarInverseLinkColor;
 }
@@ -99,7 +92,7 @@ select {
 
 .navbar-fixed-top,
 .navbar-fixed-bottom {
-        z-index: 4030;
+    z-index: 4030;
 }
 
 .dir-rtl .breadcrumb-button,
@@ -108,7 +101,7 @@ select {
 }
 
 .ie .row-fluid .desktop-first-column {
-      margin-left: 0;
+    margin-left: 0;
 }
 .langmenu form {
     margin: 0;
index ba341ee..939a174 100644 (file)
 }
 .que .formulation,
 .que .outcome,
-.que .comment,
-.que .history {
+.que .comment {
     .alert
 }
 .que .formulation {
 .formulation select {
     width: auto;
 }
-
 .path-mod-quiz input[size] {
     width: auto;
 }
     .alert-success;
 }
 .que .history {
-    color: @textColor;
-    background: @grayLighter;
+    .well
 }
 .que .ablock {
     margin: 0.7em 0 0.3em 0;
index 9971e2f..336aff1 100644 (file)
@@ -14,6 +14,9 @@
             float: right;
         }
     }
+}
+
+@media (min-width: 980px) and (max-width: 1199px) {
     // Wider form labels.
     .form-item .form-label,
     .mform .fitem div.fitemtitle,
         width: 48.717948717948715%;
        *width: 48.664757228587014%;
    }
+    // Wider form labels.
+    .form-item .form-label,
+    .mform .fitem div.fitemtitle,
+    .userprofile dl.list dt,
+    .form-horizontal .control-label {
+        width: @horizontalComponentOffset1200 - 20px;
+    }
+    .form-item .form-setting,
+    .form-item .form-description,
+    .mform .fitem .felement,
+    #page-mod-forum-search .c1,
+    .mform .fdescription.required,
+    .userprofile dl.list dd,
+    .form-horizontal .controls {
+        margin-left: @horizontalComponentOffset1200;
+    }
+    .path-admin .buttons,
+    .form-buttons {
+        padding-left: @horizontalComponentOffset1200;
+    }
+
 }
 
 @media (min-width: 980px) {
         padding-left: 0;
         padding-right: 0;
     }
-    // Wider form labels.
-    .form-item .form-label,
-    .mform .fitem div.fitemtitle,
-    .userprofile dl.list dt,
-    .form-horizontal .control-label {
-        width: @horizontalComponentOffset768 - 20px;
-    }
-    .form-item .form-setting,
-    .form-item .form-description,
-    .mform .fitem .felement,
-    #page-mod-forum-search .c1,
-    .mform .fdescription.required,
-    .userprofile dl.list dd,
-    .form-horizontal .controls {
-        margin-left: @horizontalComponentOffset768;
-    }
-    .path-admin .buttons,
-    .form-buttons {
-        padding-left: @horizontalComponentOffset768;
-    }
 }
 
 @media (max-width: 979px) {
index 0b0bdcc..192af4c 100644 (file)
@@ -138,8 +138,8 @@ class theme_bootstrapbase_core_renderer extends core_renderer {
             } else {
                 $url = '#cm_submenu_'.$submenucount;
             }
-            $content .= html_writer::start_tag('a', array('href'=>$url, 'class'=>'dropdown-toggle', 'data-toggle'=>'dropdown'));
-            $content .= $menunode->get_title();
+            $content .= html_writer::start_tag('a', array('href'=>$url, 'class'=>'dropdown-toggle', 'data-toggle'=>'dropdown', 'title'=>$menunode->get_title()));
+            $content .= $menunode->get_text();
             if ($level == 1) {
                 $content .= '<b class="caret"></b>';
             }
index fb9fb58..cfdd7c5 100644 (file)
@@ -1,4 +1,4 @@
-.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}.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}.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}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}.main img{vertical-align:middle}.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 #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-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 .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:left}.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}.moodle-dialogue-base .moodle-dialogue{z-index:600;padding:0;margin:0;background:0;border: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-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}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}#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}.addcourse{float:right}.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 .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 .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}.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}.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;vertical-align:text-bottom}.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:22px;margin-left:40%}.section li.activity{padding:.2em;clear:both}.section .activity .activityinstance .groupinglabel{padding-left:.45em}.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{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:3em}.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}.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 .controls{visibility:hidden}.course_category_tree .controls div{display:inline;cursor:pointer}.jsenabled .course_category_tree .controls{visibility:visible}.course_category_tree .controls{float:right;margin-bottom:5px;text-align:right}.course_category_tree .controls div{padding-right:2em;font-size:75%}.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{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;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}.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}.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}#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{position:absolute;top:26px;bottom:1px;display:inline-block;*display:inline;width:180px;overflow:auto;border-right:1px solid #bbb;*zoom:1}.dir-rtl .file-picker .fp-repo-area{border-right:0;border-left:1px solid #bbb}.file-picker .fp-repo-items{display:inline-block;*display:inline;margin-left:181px;vertical-align:top;*zoom:1}.file-picker .fp-navbar{min-height:22px;padding:5px 8px;background:#f2f2f2;border-bottom:1px solid #bbb}.file-picker .fp-content{width:678px;height:477px;margin-bottom:-14px;overflow:auto;clear:both;background:#fff}.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;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}.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 .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}.file-picker.fp-select{width:420px}.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}.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;z-index:1000;width:100%;height:100%}.fp-iconview .fp-reficons2{position:absolute;top:0;left:0;z-index:1001;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;z-index:2000;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;z-index:3000;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;z-index:3000;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;z-index:3000;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}.allcoursegrades{width:100%;padding:4px 0 5px 0;text-align:right}.path-grade-edit .buttons{text-align:center}.path-grade-edit-tree .idnumber{margin-left:15px}.path-grade-edit-tree .movetarget{position:relative;width:80px;height:16px}.path-grade-edit-tree ul#grade_tree{width:auto}.path-grade-edit-tree ul#grade_tree li{list-style:none}.path-grade-edit-tree ul#grade_tree li.category{margin-bottom:6px}.path-grade-edit-tree .iconsmall{margin-left:4px}#grade-report-toggles{text-align:center}#grade-aggregation-help dt{margin-top:15px}#grade-aggregation-help dd.example{margin-top:7px}#grade-aggregation-help code{display:block;margin-top:7px}.gradeexportlink{padding:2em;text-align:center}.gradetreebox{margin-top:10px;overflow-x:auto;overflow-y:hidden}.gradetreebox table{width:100%;font-size:.8em}.gradetreebox td.colspan,.gradetreebox tr.category .cell{background-color:#DDD}.gradetreebox th.actions{width:105px;white-space:nowrap}.gradetreebox td.name{white-space:nowrap}.gradetreebox td.name h4{display:inline}.gradetreebox td.range{white-space:nowrap}.gradetreebox span.actionlink{color:blue}.gradetreebox span.actionlink:hover{text-decoration:underline;cursor:pointer}.gradetreebox img.iconsmall{margin-left:4px}.gradetreebox img.icon{margin-right:5px}.gradetreebox #gradetreesubmit{margin-bottom:1em;text-align:center}.gradetreebox .hidden{display:none}#page-grade-grading-manage #activemethodselector{margin-bottom:1em;text-align:center}#page-grade-grading-manage #activemethodselector select{margin:0 1em}#page-grade-grading-manage .actions{text-align:center}#page-grade-grading-manage .action{display:inline-block;width:150px;padding:.5em;margin:.5em;text-align:center;background-color:#eee;border:2px solid #ccc;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage .action:hover{text-decoration:none;background-color:#f6f6f6}#page-grade-grading-manage #actionresultmessagebox{position:relative;width:60%;padding:.5em;margin:1em auto;text-align:center;background-color:#d2ebff;border:2px solid #CCC;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage #actionresultmessagebox span{position:absolute;top:-1.2em;right:0;font-size:80%;color:#666}#page-grade-grading-manage .definition-name .status{padding:.25em;font-size:60%;font-weight:normal;text-transform:uppercase;border:1px solid #EEE;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage .definition-name .status.ready{background-color:#e7f1c3;border-color:#aea}#page-grade-grading-manage .definition-name .status.draft{background-color:#f3f2aa;border-color:#ee2}#page-grade-grading-manage .definition-preview{width:50%;padding:1em;margin:1em auto;border:1px solid #EEE}#page-grade-grading-pick .template-name{padding:3px;clear:both;background-color:#f6f6f6}#page-grade-grading-pick .template-name .type{padding:.25em;font-size:60%;font-weight:normal;text-transform:uppercase;border:1px solid #eee;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-pick .template-name .type.shared{background-color:#e7f1c3;border-color:#aea}#page-grade-grading-pick .template-name .type.ownform{background-color:#d2ebff;border-color:#ace}#page-grade-grading-pick .template-description{padding:0 2em 0 0;margin-right:51%;margin-bottom:1em}#page-grade-grading-pick .template-preview{float:right;width:50%;padding:1em;margin-bottom:1em;border:1px solid #EEE}#page-grade-grading-pick .template-actions{padding:0 2em 0 0;margin-right:51%;margin-bottom:1em}#page-grade-grading-pick .template-actions .action{display:inline-block;padding:.25em;margin:.25em;border:2px solid transparent}#page-grade-grading-pick .template-actions .action.pick{background-color:#EEE;border:2px solid #CCC;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#page-grade-grading-pick .template-actions .action:hover{text-decoration:none;background-color:#f6f6f6;border:2px solid #CCC;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#page-grade-grading-pick .template-actions .action .action-text{display:inline}#page-grade-grading-pick .template-actions .action .action-icon{margin:0 3px}#page-grade-grading-pick .template-preview-confirm{width:50%;padding:1em;margin:1em auto;border:1px solid #EEE}#page-grade-grading-pick .singlebutton{clear:both}table#user-grades tr td.overridden{background-color:#f3e4c0}table#user-grades tr.odd td.overridden{background-color:#efd9a4}table#user-grades tr td.ajaxoverridden{background-color:#ffe3a0}table#user-grades tr.odd td.ajaxoverridden{background-color:#ffda83}table#user-grades tr.even td.excluded{background-color:#eabfff}table#user-grades tr.odd td.excluded{background-color:#e5afff}table#user-grades tr.groupavg td.cell{font-weight:700;color:#006400;background-color:#efffef}table#user-grades td.cat,table#user-grades td.course{font-weight:700}.path-grade-report-grader #overDiv table{margin:0}.path-grade-report-grader #overDiv table td.feedback{border:0}.path-grade-report-grader #overDiv .feedback{font-size:10.5px;font-weight:400;background-color:#ABF}.path-grade-report-grader #overDiv .caption{font-size:10.5px;font-weight:700;color:#CCF;background-color:#56C}.path-grade-report-grader #overDiv .intersection{font-size:10.5px;font-weight:400;color:#000;background-color:#ABF}.path-grade-report-grader #overDiv .intersectioncaption{font-weight:700;color:#CCF;background-color:#56C}.path-grade-report-grader div.gradeparent,table#user-grades td.ajax{text-align:left}.path-grade-report-grader.dir-rtl div.gradeparent,.dir-rtl table#user-grades td.ajax{text-align:right}table#user-grades td,table#user-grades th{text-align:right}table#user-grades .courseitem{text-align:right;white-space:nowrap}table#user-grades th.category,table#user-grades th#studentheader,table#user-grades th.user{text-align:left}div.gradertoggle{display:inline;margin-left:20px}table#user-grades .userpic{margin-right:10px}table#user-grades .quickfeedback{margin-left:10px;border:1px dashed #000}.dir-rtl table#user-grades .quickfeedback{margin-right:10px;margin-left:0}.path-grade-report-grader #siteconfiglink{text-align:right}table#user-grades .hidden,table#user-grades .hidden a{color:#999}table#user-grades .datesubmitted{font-size:10.5px}.path-grade-report-grader span.inclusion-links{margin:0 5px 0 10px}.path-grade-report-grader th.user img.userpicture{margin-right:.5em}.path-grade-report-grader a.quickedit{display:block;float:right;margin:.1em 0 0;clear:none;font-size:9px;line-height:1em;background-color:transparent}.path-grade-report-grader a.quickedit2{display:block;float:right;margin:1.3em 0 0;clear:none;background-color:transparent}.path-grade-report-grader table#quick_edit{margin:0 auto;border:1px solid #cecece}.path-grade-report-grader table#quick_edit td{padding:5px;margin:0;text-align:left;vertical-align:middle;border:1px solid #cecece}.path-grade-report-grader table#quick_edit td img{padding:0;vertical-align:middle;border:3px double #cecece}.path-grade-report-grader table#quick_edit td.fullname{padding-left:5px;border-left:0}.path-grade-report-grader table#quick_edit td.picture{border-right:0}.path-grade-report-grader table#quick_edit td.finalgrade input{width:5em}.path-grade-report-grader h1{clear:both;text-align:center}.path-grade-report-grader input.center{margin:10px auto 0}.path-grade-report-grader .lefttbody{width:auto;vertical-align:middle}.path-grade-report-grader .left_scroller{float:left;clear:none}.path-grade-report-grader .left_scroller #fixed_column .heading th.header,.path-grade-report-grader .left_scroller #fixed_column td,.path-grade-report-grader .left_scroller #fixed_column th{height:4em}.path-grade-report-grader .left_scroller #fixed_column td.controls{height:2em}.path-grade-report-grader.dir-rtl .left_scroller{float:right}.path-grade-report-grader .right_scroller{width:auto;overflow-x:scroll;clear:none}.path-grade-report-grader .right_scroller tr.heading_name_row th,.path-grade-report-grader .right_scroller table#user-grades td.grade{height:4em}.path-grade-report-grader .right_scroller .path-grade-report-grader .left_scroller .topleft,.path-grade-report-grader .right_scroller tr.avg td,.path-grade-report-grader .right_scroller tr.groupavg,.path-grade-report-grader .right_scroller tr.controls_row,.path-grade-report-grader .right_scroller div.right_scroller tr{height:2em}table#fixed_column,table#user-grades,table#fixed_column th,table#fixed_column td,table#user-grades td,table#user-grades th,table#user-grades input{padding:0 2px;margin:0;font-size:10px;vertical-align:middle}.path-grade-report-grader form td.excluded{color:#b94a48}.path-grade-report-grader .excludedfloater{float:left;font-size:9px;font-weight:700;color:#b94a48}.path-grade-report-grader span.gradepass{color:#298721}.path-grade-report-grader span.gradefail{color:#890d0d}.path-grade-report-grader .gradeweight{font-weight:700;color:#461d7c}.path-grade-report-grader td select{padding:0;font-size:100%}.path-grade-report-grader .right_scroller td select{font-size:11.9px}.path-grade-report-grader .grade_icons img.ajax{float:right}.path-grade-report-grader .gradestable th.user,.path-grade-report-grader .gradestable th.range,.path-grade-report-grader .flexible th,.path-grade-report-grader .flexible td,.path-grade-report-grader .flexible th a,.path-grade-report-grader .flexible td a,.path-grade-report-grader .gradestable th.range,.path-grade-report-grader th,.path-grade-report-grader td{white-space:nowrap}table#user-grades td.vmarked{background-color:#fc3}table#user-grades td.hmarked{background-color:#ff9}table#user-grades td.hmarked.vmarked{background-color:#fc9}.path-grade-report-grader .gradeparent{overflow:auto}table#fixed_column tr.controls td,table#user-grades tr.controls td,.path-grade-report-grader table tr.avg,.path-grade-report-grader table tr.avg:hover{background-color:#d9edf7}.path-grade-report-grader table th.user,.path-grade-report-grader table td.userfield{text-align:left}.path-grade-report-grader .usersuspended a:link,.path-grade-report-grader .usersuspended a:visited{color:#999}.path-grade-report-grader table th.usersuspended img.usersuspendedicon{margin-left:.45em;vertical-align:text-bottom}.path-grade-report-grader .yui3-overlay{left:0;padding:2px 5px;font-size:.7em;background-color:#ffee69;border-color:#d4c237 #a6982b #a6982b;border-style:solid;border-width:1px}.path-grade-report-grader .yui3-overlay .fullname{font-weight:bold;color:#5f3e00}.path-grade-report-grader .yui3-overlay .itemname{font-weight:bold;color:#194f3e}.path-grade-report-grader .yui3-overlay .feedback{color:#5f595e}.path-grade-report-grader #tooltipPanel{text-align:left}.path-grade-report-grader .yui3-overlay a.container-close{margin-top:-3px}.path-grade-report-grader #hiddentooltiproot,.tooltipDiv{display:none}.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 .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:35em}#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;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}.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,.que .history{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{color:#333;background:#eee}.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 .main .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{border:1px solid}.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.main{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}.dir-ltr.two-column #region-bs-main-and-pre.span9,.dir-rtl.two-column #region-main.span9,.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%}.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}.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}.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}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}.main img{vertical-align:middle}.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 #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-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}