require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/pluginlib.php');
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
admin_externalpage_setup('pluginsoverview');
+require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
$fetchremote = optional_param('fetchremote', false, PARAM_BOOL);
$mform->addElement('searchableselector', 'fids', get_string('name'),
$functions, array('multiple'));
+ $mform->addRule('fids', get_string('required'), 'required', null, 'client');
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
}
public function process_grouping_group($data) {
- global $DB;
-
- $data = (object)$data;
-
- $data->groupingid = $this->get_new_parentid('grouping'); // Use new parentid
- $data->groupid = $this->get_mappingid('group', $data->groupid); // Get from mappings
+ global $CFG;
- $params = array();
- $params['groupingid'] = $data->groupingid;
- $params['groupid'] = $data->groupid;
+ require_once($CFG->dirroot.'/group/lib.php');
- if (!$DB->record_exists('groupings_groups', $params)) {
- $DB->insert_record('groupings_groups', $data); // No need to set this mapping (no child info nor files)
- }
+ $data = (object)$data;
+ groups_assign_grouping($this->get_new_parentid('grouping'), $this->get_mappingid('group', $data->groupid), $data->timeadded);
}
protected function after_execute() {
*
* If restoring users from same site backup:
* 1A - Normal check: If match by id and username and mnethost => ok, return target user
- * 1B - Handle users deleted in DB and "alive" in backup file:
+ * 1B - If restoring an 'anonymous' user (created via the 'Anonymize user information' option) try to find a
+ * match by username only => ok, return target user MDL-31484
+ * 1C - Handle users deleted in DB and "alive" in backup file:
* If match by id and mnethost and user is deleted in DB and
* (match by username LIKE 'backup_email.%' or by non empty email = md5(username)) => ok, return target user
- * 1C - Handle users deleted in backup file and "alive" in DB:
+ * 1D - Handle users deleted in backup file and "alive" in DB:
* If match by id and mnethost and user is deleted in backup file
* and match by email = email_without_time(backup_email) => ok, return target user
- * 1D - Conflict: If match by username and mnethost and doesn't match by id => conflict, return false
- * 1E - None of the above, return true => User needs to be created
+ * 1E - Conflict: If match by username and mnethost and doesn't match by id => conflict, return false
+ * 1F - None of the above, return true => User needs to be created
*
* if restoring from another site backup (cannot match by id here, replace it by email/firstaccess combination):
* 2A - Normal check: If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
return $rec; // Matching user found, return it
}
- // 1B - Handle users deleted in DB and "alive" in backup file
+ // 1B - If restoring an 'anonymous' user (created via the 'Anonymize user information' option) try to find a
+ // match by username only => ok, return target user MDL-31484
+ // This avoids username / id mis-match problems when restoring subsequent anonymized backups.
+ if (backup_anonymizer_helper::is_anonymous_user($user)) {
+ if ($rec = $DB->get_record('user', array('username' => $user->username))) {
+ return $rec; // Matching anonymous user found - return it
+ }
+ }
+
+ // 1C - Handle users deleted in DB and "alive" in backup file
// Note: for DB deleted users email is stored in username field, hence we
// are looking there for emails. See delete_user()
// Note: for DB deleted users md5(username) is stored *sometimes* in the email field,
return $rec; // Matching user, deleted in DB found, return it
}
- // 1C - Handle users deleted in backup file and "alive" in DB
+ // 1D - Handle users deleted in backup file and "alive" in DB
// If match by id and mnethost and user is deleted in backup file
// and match by email = email_without_time(backup_email) => ok, return target user
if ($user->deleted) {
}
}
- // 1D - If match by username and mnethost and doesn't match by id => conflict, return false
+ // 1E - If match by username and mnethost and doesn't match by id => conflict, return false
if ($rec = $DB->get_record('user', array('username'=>$user->username, 'mnethostid'=>$user->mnethostid))) {
if ($user->id != $rec->id) {
return false; // Conflict, username already exists and belongs to another id
*/
class backup_anonymizer_helper {
+ /**
+ * Determine if the given user is an 'anonymous' user, based on their username, firstname, lastname
+ * and email address.
+ * @param stdClass $user the user record to test
+ * @return bool true if this is an 'anonymous' user
+ */
+ public static function is_anonymous_user($user) {
+ if (preg_match('/^anon\d*$/', $user->username)) {
+ $match = preg_match('/^anonfirstname\d*$/', $user->firstname);
+ $match = $match && preg_match('/^anonlastname\d*$/', $user->lastname);
+ $match = $match && preg_match('/^anon\d*@doesntexist\.com$/', $user->email);
+ if ($match) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static function process_user_auth($value) {
return 'manual'; // Set them to manual always
}
require_once($CFG->dirroot . '/backup/util/interfaces/processable.class.php');
require_once($CFG->dirroot . '/backup/backup.class.php');
require_once($CFG->dirroot . '/backup/util/structure/restore_path_element.class.php');
+require_once($CFG->dirroot . '/backup/util/helper/backup_anonymizer_helper.class.php');
require_once($CFG->dirroot . '/backup/util/helper/backup_file_manager.class.php');
require_once($CFG->dirroot . '/backup/util/helper/restore_prechecks_helper.class.php');
require_once($CFG->dirroot . '/backup/util/helper/restore_moodlexml_parser_processor.class.php');
scope: scope
},
headers: {
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
- 'User-Agent': 'MoodleComment/3.0'
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
data: build_querystring(params)
};
scope: this
},
headers: {
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
- 'User-Agent': 'MoodleComment/3.0'
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
data: build_querystring(data)
};
resel.icon.src = result.icon;
resel.a.href = result.link;
resel.namespan.innerHTML = result.name;
+ if (!parseInt(result.visible, 10)) {
+ resel.a.className = 'dimmed';
+ }
if (result.groupingname) {
resel.groupingspan.innerHTML = '(' + result.groupingname + ')';
resel.icon.src = result.icon;
resel.a.href = result.link;
resel.namespan.innerHTML = result.name;
+ if (!parseInt(result.visible, 10)) {
+ resel.a.className = 'dimmed';
+ }
if (result.groupingname) {
resel.groupingspan.innerHTML = '(' + result.groupingname + ')';
throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
}
+ // Note the section visibility
+ $visible = get_fast_modinfo($this->course)->get_section_info($this->section)->visible;
+
$DB->set_field('course_modules', 'instance', $instanceid, array('id' => $this->cm->id));
$sectionid = add_mod_to_section($this->cm);
$DB->set_field('course_modules', 'section', $sectionid, array('id' => $this->cm->id));
- set_coursemodule_visible($this->cm->id, true);
+ set_coursemodule_visible($this->cm->id, $visible);
+ if (!$visible) {
+ $DB->set_field('course_modules', 'visibleold', 1, array('id' => $this->cm->id));
+ }
// Rebuild the course cache and retrieve the final info about this module.
rebuild_course_cache($this->course->id, true);
delete_course_module($this->cm->id);
throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
}
- $mod = $info->cms[$this->cm->id];
+ $mod = $info->get_cm($this->cm->id);
$mod->groupmodelink = $this->cm->groupmodelink;
$mod->groupmode = $this->cm->groupmode;
$resp->elementid = 'module-'.$mod->id;
$resp->commands = make_editing_buttons($mod, true, true, 0, $mod->sectionnum);
$resp->onclick = $mod->get_on_click();
+ $resp->visible = $mod->visible;
// if using groupings, then display grouping name
if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', $this->context)) {
array(0=>get_string('completiondisabled','completion'), 1=>get_string('completionenabled','completion')));
$mform->setDefault('enablecompletion', $courseconfig->enablecompletion);
- $mform->addElement('checkbox', 'completionstartonenrol', get_string('completionstartonenrol', 'completion'));
+ $mform->addElement('advcheckbox', 'completionstartonenrol', get_string('completionstartonenrol', 'completion'));
$mform->setDefault('completionstartonenrol', $courseconfig->completionstartonenrol);
$mform->disabledIf('completionstartonenrol', 'enablecompletion', 'eq', 0);
} else {
}
$mform = new editsection_form($PAGE->url, array('course' => $course, 'editoroptions' => $editoroptions,
- 'cs' => $section, 'showavailability' => $section->showavailability));
+ 'cs' => $section));
$mform->set_data($section); // set current value
$returnurl = course_get_url($course, $sectionreturn);
$mform->addHelpButton('groupingid', 'groupingsection', 'group');
}
- // Date and time conditions
+ // Available from/to defaults to midnight because then the display
+ // will be nicer where it tells users when they can access it (it
+ // shows only the date and not time).
+ $date = usergetdate(time());
+ $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']);
+
+ // Date and time conditions.
$mform->addElement('date_time_selector', 'availablefrom',
- get_string('availablefrom', 'condition'), array('optional' => true));
+ get_string('availablefrom', 'condition'),
+ array('optional' => true, 'defaulttime' => $midnight));
$mform->addElement('date_time_selector', 'availableuntil',
- get_string('availableuntil', 'condition'), array('optional' => true));
+ get_string('availableuntil', 'condition'),
+ array('optional' => true, 'defaulttime' => $midnight));
// Conditions based on grades
$gradeoptions = array();
CONDITION_STUDENTVIEW_HIDE => get_string('showavailabilitysection_hide', 'condition'));
$mform->addElement('select', 'showavailability',
get_string('showavailabilitysection', 'condition'), $showhide);
-
- $mform->setDefault('showavailability', $this->_customdata['showavailability']);
}
$this->add_action_buttons();
// Conditions: Don't let them set dates which make no sense
if (array_key_exists('availablefrom', $data) &&
$data['availablefrom'] && $data['availableuntil'] &&
- $data['availablefrom'] > $data['availableuntil']) {
+ $data['availablefrom'] >= $data['availableuntil']) {
$errors['availablefrom'] = get_string('badavailabledates', 'condition');
}
+ // Conditions: Verify that the grade conditions are numbers, and make sense.
+ if (array_key_exists('conditiongradegroup', $data)) {
+ foreach ($data['conditiongradegroup'] as $i => $gradedata) {
+ if ($gradedata['conditiongrademin'] !== '' &&
+ !is_numeric(unformat_float($gradedata['conditiongrademin']))) {
+ $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
+ continue;
+ }
+ if ($gradedata['conditiongrademax'] !== '' &&
+ !is_numeric(unformat_float($gradedata['conditiongrademax']))) {
+ $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
+ continue;
+ }
+ if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' &&
+ unformat_float($gradedata['conditiongrademax']) <= unformat_float($gradedata['conditiongrademin'])) {
+ $errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition');
+ continue;
+ }
+ if ($gradedata['conditiongrademin'] === '' && $gradedata['conditiongrademax'] === '' &&
+ $gradedata['conditiongradeitemid']) {
+ $errors["conditiongradegroup[{$i}]"] = get_string('gradeitembutnolimits', 'condition');
+ continue;
+ }
+ if (($gradedata['conditiongrademin'] !== '' || $gradedata['conditiongrademax'] !== '') &&
+ !$gradedata['conditiongradeitemid']) {
+ $errors["conditiongradegroup[{$i}]"] = get_string('gradelimitsbutnoitem', 'condition');
+ continue;
+ }
+ }
+ }
+
return $errors;
}
}
}
$o.= html_writer::end_tag('div');
- $o .= $this->section_availability_message($section);
+ $o .= $this->section_availability_message($section,
+ has_capability('moodle/course:viewhiddensections', $context));
return $o;
}
$o.= html_writer::end_tag('div');
$o.= $this->section_activity_summary($section, $course, $mods);
- $o.= $this->section_availability_message($section);
+ $context = context_course::instance($course->id);
+ $o .= $this->section_availability_message($section,
+ has_capability('moodle/course:viewhiddensections', $context));
$o .= html_writer::end_tag('div');
$o .= html_writer::end_tag('li');
}
/**
- * If section is not visible to current user, display the message about that
- * ('Not available until...', that sort of thing). Otherwise, returns blank.
+ * If section is not visible, display the message about that ('Not available
+ * until...', that sort of thing). Otherwise, returns blank.
+ *
+ * For users with the ability to view hidden sections, it shows the
+ * information even though you can view the section and also may include
+ * slightly fuller information (so that teachers can tell when sections
+ * are going to be unavailable etc). This logic is the same as for
+ * activities.
*
* @param stdClass $section The course_section entry from DB
+ * @param bool $canviewhidden True if user can view hidden sections
* @return string HTML to output
*/
- protected function section_availability_message($section) {
+ protected function section_availability_message($section, $canviewhidden) {
+ global $CFG;
$o = '';
- if (!$section->uservisible || $section->availableinfo) {
+ if (!$section->uservisible) {
$o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
- if (!empty($section->availableinfo)) {
- $o .= $section->availableinfo;
- } else {
- $o .= get_string('notavailable');
- }
+ // Note: We only get to this function if availableinfo is non-empty,
+ // so there is definitely something to print.
+ $o .= $section->availableinfo;
$o .= html_writer::end_tag('div');
+ } else if ($canviewhidden && !empty($CFG->enableavailability) && $section->visible) {
+ $ci = new condition_info_section($section);
+ $fullinfo = $ci->get_full_information();
+ if ($fullinfo) {
+ $o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
+ $o .= get_string(
+ ($section->showavailability ? 'userrestriction_visible' : 'userrestriction_hidden'),
+ 'condition', $fullinfo);
+ $o .= html_writer::end_tag('div');
+ }
}
return $o;
}
$thissection->showavailability = 0;
}
// Show the section if the user is permitted to access it, OR if it's not available
- // but showavailability is turned on
+ // but showavailability is turned on (and there is some available info text).
$showsection = $thissection->uservisible ||
- ($thissection->visible && !$thissection->available && $thissection->showavailability);
+ ($thissection->visible && !$thissection->available && $thissection->showavailability
+ && !empty($thissection->availableinfo));
if (!$showsection) {
// Hidden section message is overridden by 'unavailable' control
// (showavailability option).
continue;
}
echo $this->stealth_section_header($section);
- print_section($course, $thissection, $mods, $modnamesused, true, "100%", false, $displaysection);
+ print_section($course, $thissection, $mods, $modnamesused, true, "100%", false, 0);
echo $this->stealth_section_footer();
}
$strfulllistofcourses = get_string('fulllistofcourses');
-/// Unless it's an editing admin, just print the regular listing of courses/categories
+// Unless it's an editing admin, just print the regular listing of courses/categories.
if (!$adminediting) {
-
-/// Print form for creating new categories
+ $showaddcoursebutton = true;
+ // Print form for creating new categories.
$countcategories = $DB->count_records('course_categories');
-
if ($countcategories > 1 || ($countcategories == 1 && $DB->count_records('course') > 200)) {
$strcourses = get_string('courses');
$strcategories = get_string('categories');
echo $OUTPUT->header();
echo $OUTPUT->skip_link_target();
echo $OUTPUT->box_start('courseboxes');
- print_courses(0);
+ $showaddcoursebutton = print_courses(0);
echo $OUTPUT->box_end();
}
echo $OUTPUT->container_start('buttons');
- if (has_capability('moodle/course:create', $systemcontext)) {
- /// Print link to create a new course
- /// Get the 1st available category
+ if (has_capability('moodle/course:create', $systemcontext) && $showaddcoursebutton) {
+ // Print link to create a new course, for the 1st available category.
$options = array('category' => $CFG->defaultrequestcategory);
echo $OUTPUT->single_button(new moodle_url('edit.php', $options), get_string('addnewcourse'), 'get');
}
}
/**
- * Category is 0 (for all courses) or an object
+ * Print courses in category. If category is 0 then all courses are printed.
+ * @param int|stdClass $category category object or id.
+ * @return bool true if courses found and printed, else false.
*/
function print_courses($category) {
global $CFG, $OUTPUT;
echo html_writer::start_tag('div', array('class'=>'addcoursebutton'));
echo $OUTPUT->single_button(new moodle_url('/course/edit.php', $options), get_string("addnewcourse"));
echo html_writer::end_tag('div');
+ return false;
}
}
+ return true;
}
/**
if ($icons = enrol_get_course_info_icons($course)) {
echo html_writer::start_tag('div', array('class'=>'enrolmenticons'));
foreach ($icons as $icon) {
+ $icon->attributes["alt"] .= ": ". format_string($coursename, true, array('context'=>$context));
echo $OUTPUT->render($icon);
}
echo html_writer::end_tag('div'); // End of enrolmenticons div
if (!$cm = $DB->get_record('course_modules', array('id'=>$id))) {
return false;
}
+
+ // Create events and propagate visibility to associated grade items if the value has changed.
+ // Only do this if it's changed to avoid accidently overwriting manual showing/hiding of student grades.
+ if ($cm->visible == $visible) {
+ return true;
+ }
+
if (!$modulename = $DB->get_field('modules', 'name', array('id'=>$cm->module))) {
return false;
}
}
}
- // hide the associated grade items so the teacher doesn't also have to go to the gradebook and hide them there
+ // Hide the associated grade items so the teacher doesn't also have to go to the gradebook and hide them there.
$grade_items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$modulename, 'iteminstance'=>$cm->instance, 'courseid'=>$cm->course));
if ($grade_items) {
foreach ($grade_items as $grade_item) {
/// Update module itself if necessary
- if ($mod->section != $section->id) {
- $mod->section = $section->id;
- $DB->update_record("course_modules", $mod);
- // if moving to a hidden section then hide module
- if (!$section->visible) {
- set_coursemodule_visible($mod->id, 0);
- }
+ // If moving to a hidden section then hide module.
+ if (!$section->visible && $mod->visible) {
+ // Set this in the object because it is sent as a response to ajax calls.
+ set_coursemodule_visible($mod->id, 0, true);
+ $mod->visible = 0;
+ }
+ if ($section->visible && !$mod->visible) {
+ set_coursemodule_visible($mod->id, 1, true);
+ // Set this in the object because it is sent as a response to ajax calls.
+ $mod->visible = $mod->visibleold;
}
/// Add the module into the new section
// make sure visibility is set correctly (in particular in calendar)
// note: allow them to set it even without moodle/course:activityvisibility
set_coursemodule_visible($fromform->coursemodule, $fromform->visible);
+ $DB->set_field('course_modules', 'visibleold', 1, array('id' => $fromform->coursemodule));
if (isset($fromform->cmidnumber)) { //label
// set cm idnumber - uniqueness is already verified by form validation
continue;
}
if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' &&
- unformat_float($gradedata['conditiongrademax']) < unformat_float($gradedata['conditiongrademin'])) {
+ unformat_float($gradedata['conditiongrademax']) <= unformat_float($gradedata['conditiongrademin'])) {
$errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition');
continue;
}
}
moveto_module($cm, $section, $beforemod);
+ echo json_encode(array('visible' => $cm->visible));
break;
case 'gettitle':
require_capability('moodle/course:manageactivities', $modcontext);
$createdcats = core_course_external::create_categories($categories);
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $createdcats = external_api::clean_returnvalue(core_course_external::create_categories_returns(), $createdcats);
+
// Initially confirm that base data was inserted correctly.
$this->assertEquals($category1->name, $createdcats[0]['name']);
$this->assertEquals($category2->name, $createdcats[1]['name']);
$createdsubcats = core_course_external::create_categories($subcategories);
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $createdsubcats = external_api::clean_returnvalue(core_course_external::create_categories_returns(), $createdsubcats);
+
// Confirm that sub categories were inserted correctly.
$this->assertEquals($category3->name, $createdsubcats[0]['name']);
array('key' => 'id', 'value' => $category1->id),
array('key' => 'visible', 'value' => 1)), 1);
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories);
+
// Check we retrieve the good total number of categories.
$this->assertEquals(2, count($categories));
array('key' => 'id', 'value' => $category1->id),
array('key' => 'idnumber', 'value' => $category1->idnumber),
array('key' => 'visible', 'value' => 1)), 0);
+
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories);
+
$this->assertEquals(1, count($categories));
// Retrieve categories from parent.
// Retrieve all categories.
$categories = core_course_external::get_categories();
+
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $categories = external_api::clean_returnvalue(core_course_external::get_categories_returns(), $categories);
+
$this->assertEquals($DB->count_records('course_categories'), count($categories));
// Call without required capability (it will fail cause of the search on idnumber).
$createdcourses = core_course_external::create_courses($courses);
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $createdcourses = external_api::clean_returnvalue(core_course_external::create_courses_returns(), $createdcourses);
+
// Check that right number of courses were created.
$this->assertEquals(2, count($createdcourses));
$courses = core_course_external::get_courses(array('ids' =>
array($course1->id, $course2->id)));
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $courses = external_api::clean_returnvalue(core_course_external::get_courses_returns(), $courses);
+
// Check we retrieve the good total number of categories.
$this->assertEquals(2, count($courses));
// Get all courses in the DB
$courses = core_course_external::get_courses(array());
+
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $courses = external_api::clean_returnvalue(core_course_external::get_courses_returns(), $courses);
+
$this->assertEquals($DB->count_records('course'), count($courses));
}
$courses = core_course_external::get_course_contents($course->id, array());
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $courses = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $courses);
+
// Check that the course has the 3 created modules
$this->assertEquals(3, count($courses[0]['modules']));
}
$duplicate = core_course_external::duplicate_course($course->id, $newcourse['fullname'],
$newcourse['shortname'], $newcourse['categoryid'], $newcourse['visible'], $newcourse['options']);
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $duplicate = external_api::clean_returnvalue(core_course_external::duplicate_course_returns(), $duplicate);
+
// Check that the course has been duplicated.
$this->assertEquals($newcourse['shortname'], $duplicate['shortname']);
}
spinner.show();
},
success: function(tid, response) {
+ var responsetext = Y.JSON.parse(response.responseText);
+ var params = {element: dragnode, visible: responsetext.visible};
+ M.course.coursebase.invoke_function('set_visibility_resource_ui', params);
this.unlock_drag_handle(drag, CSS.EDITINGMOVE);
window.setTimeout(function(e) {
spinner.hide();
{
NAME : MODCHOOSERNAME,
ATTRS : {
+ maxheight : {
+ value : 800
+ }
}
});
M.course = M.course || {};
},
_setup_for_resource : function(toolboxtarget) {
toolboxtarget = Y.one(toolboxtarget);
- // "Disable" show/hide icons (change cursor to not look clickable) if section is hidden
- var showhide = toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.HIDE);
- showhide.concat(toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.SHOW));
- showhide.each(function(node) {
- var section = node.ancestor(CSS.SECTIONLI);
- if (section && section.hasClass(CSS.SECTIONHIDDENCLASS)) {
- node.setStyle('cursor', 'auto');
- }
- });
// Set groupmode attribute for use by this.toggle_groupmode()
var groups;
}
}, this);
listenevents.push(thisevent);
+ },
+ /**
+ * Set the visibility of the current resource (identified by the element)
+ * to match the hidden parameter (this is not a toggle).
+ * Only changes the visibility in the browser (no ajax update).
+ * @param args An object with 'element' being the A node containing the resource
+ * and 'visible' being the state that the visiblity should be set to.
+ * @return void
+ */
+ set_visibility_resource_ui: function(args) {
+ var element = args.element;
+ var shouldbevisible = args.visible;
+ var buttonnode = element.one(CSS.SHOW);
+ var visible = (buttonnode === null);
+ if (visible) {
+ buttonnode = element.one(CSS.HIDE);
+ }
+ if (visible != shouldbevisible) {
+ this.toggle_hide_resource_ui(buttonnode);
+ }
}
}, {
NAME : 'course-resource-toolbox',
if (Y.Array.indexOf(response.resourcestotoggle, activityid) != -1) {
this.toggle_hide_resource_ui(button);
}
-
- if (value == 0) {
- button.setStyle('cursor', 'auto');
- } else {
- button.setStyle('cursor', 'pointer');
- }
}, this);
},
toggle_highlight : function(e) {
break;
}
}
- $users[$userrole->id]['roles'] = array();
+ if (!isset($users[$userrole->id]['roles'])) {
+ $users[$userrole->id]['roles'] = array();
+ }
$users[$userrole->id]['roles'][$userrole->roleid] = array(
'text' => $roletext,
'unchangeable' => !$changeable
private function fm_js_template_mkdir() {
$rv = '
<div class="filemanager fp-mkdir-dlg">
- <div class="fp-mkdir-dlg-text">'.get_string('newfoldername','repository').'<br/><input type="text" /></div>
+ <div class="fp-mkdir-dlg-text">
+ <label>' . get_string('newfoldername', 'repository') . '</label><br/>
+ <input type="text" />
+ </div>
<button class="{!}fp-dlg-butcreate">'.get_string('makeafolder').'</button>
<button class="{!}fp-dlg-butcancel">'.get_string('cancel').'</button>
</div>';
// Were any changes made?
$changedgrades = false;
- foreach ($data as $varname => $postedvalue) {
+ foreach ($data as $varname => $students) {
$needsupdate = false;
continue;
}
- $gradeinfo = explode("_", $varname);
- $userid = clean_param($gradeinfo[1], PARAM_INT);
- $itemid = clean_param($gradeinfo[2], PARAM_INT);
+ foreach ($students as $userid => $items) {
+ $userid = clean_param($userid, PARAM_INT);
+ foreach ($items as $itemid => $postedvalue) {
+ $itemid = clean_param($itemid, PARAM_INT);
+
+ // Was change requested?
+ $oldvalue = $this->grades[$userid][$itemid];
+ if ($datatype === 'grade') {
+ // If there was no grade and there still isn't
+ if (is_null($oldvalue->finalgrade) && $postedvalue == -1) {
+ // -1 means no grade
+ continue;
+ }
- // Was change requested?
- $oldvalue = $this->grades[$userid][$itemid];
- if ($datatype === 'grade') {
- // If there was no grade and there still isn't
- if (is_null($oldvalue->finalgrade) && $postedvalue == -1) {
- // -1 means no grade
- continue;
- }
+ // If the grade item uses a custom scale
+ if (!empty($oldvalue->grade_item->scaleid)) {
- // If the grade item uses a custom scale
- if (!empty($oldvalue->grade_item->scaleid)) {
+ if ((int)$oldvalue->finalgrade === (int)$postedvalue) {
+ continue;
+ }
+ } else {
+ // The grade item uses a numeric scale
- if ((int)$oldvalue->finalgrade === (int)$postedvalue) {
- continue;
- }
- } else {
- // The grade item uses a numeric scale
+ // Format the finalgrade from the DB so that it matches the grade from the client
+ if ($postedvalue === format_float($oldvalue->finalgrade, $oldvalue->grade_item->get_decimals())) {
+ continue;
+ }
+ }
- // Format the finalgrade from the DB so that it matches the grade from the client
- if ($postedvalue === format_float($oldvalue->finalgrade, $oldvalue->grade_item->get_decimals())) {
- continue;
+ $changedgrades = true;
+
+ } else if ($datatype === 'feedback') {
+ if (($oldvalue->feedback === $postedvalue) or ($oldvalue->feedback === NULL and empty($postedvalue))) {
+ continue;
+ }
}
- }
- $changedgrades = true;
+ if (!$gradeitem = grade_item::fetch(array('id'=>$itemid, 'courseid'=>$this->courseid))) {
+ print_error('invalidgradeitemid');
+ }
- } else if ($datatype === 'feedback') {
- if (($oldvalue->feedback === $postedvalue) or ($oldvalue->feedback === NULL and empty($postedvalue))) {
- continue;
- }
- }
+ // Pre-process grade
+ if ($datatype == 'grade') {
+ $feedback = false;
+ $feedbackformat = false;
+ if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
+ if ($postedvalue == -1) { // -1 means no grade
+ $finalgrade = null;
+ } else {
+ $finalgrade = $postedvalue;
+ }
+ } else {
+ $finalgrade = unformat_float($postedvalue);
+ }
- if (!$gradeitem = grade_item::fetch(array('id'=>$itemid, 'courseid'=>$this->courseid))) { // we must verify course id here!
- print_error('invalidgradeitemid');
- }
+ $errorstr = '';
+ // Warn if the grade is out of bounds.
+ if (is_null($finalgrade)) {
+ // ok
+ } else {
+ $bounded = $gradeitem->bounded_grade($finalgrade);
+ if ($bounded > $finalgrade) {
+ $errorstr = 'lessthanmin';
+ } else if ($bounded < $finalgrade) {
+ $errorstr = 'morethanmax';
+ }
+ }
+ if ($errorstr) {
+ $user = $DB->get_record('user', array('id' => $userid), 'id, firstname, lastname');
+ $gradestr = new stdClass();
+ $gradestr->username = fullname($user);
+ $gradestr->itemname = $gradeitem->get_name();
+ $warnings[] = get_string($errorstr, 'grades', $gradestr);
+ }
- // Pre-process grade
- if ($datatype == 'grade') {
- $feedback = false;
- $feedbackformat = false;
- if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
- if ($postedvalue == -1) { // -1 means no grade
- $finalgrade = null;
- } else {
- $finalgrade = $postedvalue;
+ } else if ($datatype == 'feedback') {
+ $finalgrade = false;
+ $trimmed = trim($postedvalue);
+ if (empty($trimmed)) {
+ $feedback = NULL;
+ } else {
+ $feedback = $postedvalue;
+ }
}
- } else {
- $finalgrade = unformat_float($postedvalue);
- }
- $errorstr = '';
- // Warn if the grade is out of bounds.
- if (is_null($finalgrade)) {
- // ok
- } else {
- $bounded = $gradeitem->bounded_grade($finalgrade);
- if ($bounded > $finalgrade) {
- $errorstr = 'lessthanmin';
- } else if ($bounded < $finalgrade) {
- $errorstr = 'morethanmax';
+ // group access control
+ if ($separategroups) {
+ // note: we can not use $this->currentgroup because it would fail badly
+ // when having two browser windows each with different group
+ $sharinggroup = false;
+ foreach($mygroups as $groupid) {
+ if (groups_is_member($groupid, $userid)) {
+ $sharinggroup = true;
+ break;
+ }
+ }
+ if (!$sharinggroup) {
+ // either group membership changed or somebody is hacking grades of other group
+ $warnings[] = get_string('errorsavegrade', 'grades');
+ continue;
+ }
}
- }
- if ($errorstr) {
- $user = $DB->get_record('user', array('id' => $userid), 'id, firstname, lastname');
- $gradestr = new stdClass();
- $gradestr->username = fullname($user);
- $gradestr->itemname = $gradeitem->get_name();
- $warnings[] = get_string($errorstr, 'grades', $gradestr);
- }
- } else if ($datatype == 'feedback') {
- $finalgrade = false;
- $trimmed = trim($postedvalue);
- if (empty($trimmed)) {
- $feedback = NULL;
- } else {
- $feedback = $postedvalue;
- }
- }
+ $gradeitem->update_final_grade($userid, $finalgrade, 'gradebook', $feedback, FORMAT_MOODLE);
- // group access control
- if ($separategroups) {
- // note: we can not use $this->currentgroup because it would fail badly
- // when having two browser windows each with different group
- $sharinggroup = false;
- foreach($mygroups as $groupid) {
- if (groups_is_member($groupid, $userid)) {
- $sharinggroup = true;
- break;
+ // We can update feedback without reloading the grade item as it doesn't affect grade calculations
+ if ($datatype === 'feedback') {
+ $this->grades[$userid][$itemid]->feedback = $feedback;
}
}
- if (!$sharinggroup) {
- // either group membership changed or somebody is hacking grades of other group
- $warnings[] = get_string('errorsavegrade', 'grades');
- continue;
- }
- }
-
- $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
- if ($datatype === 'feedback') {
- $this->grades[$userid][$itemid]->feedback = $feedback;
}
}
}
$attributes = array('tabindex' => $tabindices[$item->id]['grade'], 'id'=>'grade_'.$userid.'_'.$item->id);
$itemcell->text .= html_writer::label(get_string('typescale', 'grades'), $attributes['id'], false, array('class' => 'accesshide'));
- $itemcell->text .= html_writer::select($scaleopt, 'grade_'.$userid.'_'.$item->id, $gradeval, array(-1=>$nogradestr), $attributes);
+ $itemcell->text .= html_writer::select($scaleopt, 'grade['.$userid.']['.$item->id.']', $gradeval, array(-1=>$nogradestr), $attributes);
} elseif(!empty($scale)) {
$scales = explode(",", $scale->scale);
if ($this->get_pref('quickgrading') and $grade->is_editable()) {
$value = format_float($gradeval, $decimalpoints);
$itemcell->text .= '<input size="6" tabindex="' . $tabindices[$item->id]['grade']
- . '" type="text" class="text" title="'. $strgrade .'" name="grade_'
- .$userid.'_' .$item->id.'" id="grade_'.$userid.'_'.$item->id.'" value="'.$value.'" />';
+ . '" type="text" class="text" title="'. $strgrade .'" name="grade['
+ .$userid.'][' .$item->id.']" id="grade_'.$userid.'_'.$item->id.'" value="'.$value.'" />';
} else {
$itemcell->text .= html_writer::tag('span', format_float($gradeval, $decimalpoints), array('class'=>"gradevalue$hidden$gradepass"));
}
if ($this->get_pref('showquickfeedback') and $grade->is_editable()) {
$itemcell->text .= '<input class="quickfeedback" tabindex="' . $tabindices[$item->id]['feedback'].'" id="feedback_'.$userid.'_'.$item->id
- . '" size="6" title="' . $strfeedback . '" type="text" name="feedback_'.$userid.'_'.$item->id.'" value="' . s($grade->feedback) . '" />';
+ . '" size="6" title="' . $strfeedback . '" type="text" name="feedback['.$userid.']['.$item->id.']" value="' . s($grade->feedback) . '" />';
}
} else { // Not editing
// Will this number of students result in more fields that we are allowed?
$maxinputvars = ini_get('max_input_vars');
if ($maxinputvars !== false) {
- $fieldspergradeitem = 0; // The number of fields output per grade item for each student
+ // We can't do anything about there being more grade items than max_input_vars,
+ // but we can decrease number of students per page if there are >= max_input_vars
+ $fieldsperstudent = 0; // The number of fields output per student
- if ($this->get_pref('quickgrading')) {
- // One grade field
- $fieldspergradeitem ++;
- }
- if ($this->get_pref('showquickfeedback')) {
- // One feedback field
- $fieldspergradeitem ++;
+ if ($this->get_pref('quickgrading') || $this->get_pref('showquickfeedback')) {
+ // Each array (grade, feedback) will gain one element
+ $fieldsperstudent ++;
}
- $fieldsperstudent = $fieldspergradeitem * count($this->gtree->get_items());
$fieldsrequired = $studentsperpage * $fieldsperstudent;
- if ($fieldsrequired > $maxinputvars) {
- $studentsperpage = floor($maxinputvars / $fieldsperstudent);
+ if ($fieldsrequired >= $maxinputvars) {
+ $studentsperpage = $maxinputvars - 1; // Subtract one to be on the safe side
if ($studentsperpage<1) {
- // Make sure students per page doesn't fall below 1
- // PHP max_input_vars could potentially be reached with 1 student
- // if there are >500 grade items and quickgrading and showquickfeedback are on
+ // Make sure students per page doesn't fall below 1, though if your
+ // max_input_vars is only 1 you've got bigger problems!
$studentsperpage = 1;
}
vertical-align:middle;
}
-.path-grade-report-grader .yui-overlay {
+.path-grade-report-grader .yui3-overlay {
background-color: #FFEE69;
border-color: #D4C237 #A6982B #A6982B;
border-style: solid;
font-size: 0.7em;
}
-.path-grade-report-grader .yui-overlay .fullname {
+.path-grade-report-grader .yui3-overlay .fullname {
color: #5F3E00;
font-weight: bold;
}
-.path-grade-report-grader .yui-overlay .itemname {
+.path-grade-report-grader .yui3-overlay .itemname {
color: #194F3E;
font-weight: bold;
}
-.path-grade-report-grader .yui-overlay .feedback {
+.path-grade-report-grader .yui3-overlay .feedback {
color: #5F595E;
}
/* table#user-grades td */
text-align: left;
}
-.path-grade-report-grader .yui-overlay a.container-close {
+.path-grade-report-grader .yui3-overlay a.container-close {
margin-top: -3px;
}
*
* @param int groupingid
* @param int groupid
+ * @param int $timeadded The time the group was added to the grouping.
* @return bool true or exception
*/
-function groups_assign_grouping($groupingid, $groupid) {
+function groups_assign_grouping($groupingid, $groupid, $timeadded = null) {
global $DB;
if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
$assign = new stdClass();
$assign->groupingid = $groupingid;
$assign->groupid = $groupid;
- $assign->timeadded = time();
+ if ($timeadded != null) {
+ $assign->timeadded = (integer)$timeadded;
+ } else {
+ $assign->timeadded = time();
+ }
$DB->insert_record('groupings_groups', $assign);
return true;
$roles[$roledata->id] = $roledata;
}
// Record that user has role
- $users[$rec->userid]->roles[] = $roles[$rec->roleid];
+ $users[$rec->userid]->roles[$rec->roleid] = $roles[$rec->roleid];
}
}
$rs->close();
} else if($rolecount > 1) {
$roleid = '*';
} else {
- $roleid = $userdata->roles[0]->id;
+ $userrole = reset($userdata->roles);
+ $roleid = $userrole->id;
}
$roles[$roleid]->users[$userid] = $userdata;
}
$string['pathswrongadmindir'] = '管理目錄不存在';
$string['phpextension'] = '{$a} PHP擴展';
$string['phpversion'] = 'PHP版本';
-$string['phpversionhelp'] = '<p>Moodle 需要至少4.1.0.的PHP版本 </p>
+$string['phpversionhelp'] = '<p>Moodle 需要的PHP版本至少要4.3.0或是5.1.0 (5.0.x有一些已知的問題) </p>
<p>您目前執行的是{$a} 版</p>
-<p>您必須更新您的 PHP 或在有更新版本的主機進行安裝!</p>';
+<p>您必須更新您的 PHP 或在有更新版本的主機進行安裝!!(若是5.0.x,你可以下降到4.4.x 版本)</p>';
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
$string['welcomep20'] = '這個頁面是提醒您已經成功安裝與啟動 <strong>{$a->packname} {$a->packversion}</strong> ,恭喜!';
$string['welcomep30'] = '<strong>{$a->installername}</strong>包含了可以建立<strong>Moodle</strong>執行環境的應用程序:';
$string['addtodock'] = 'Move this to the dock';
$string['anypagematchingtheabove'] = 'Any page matching the above';
$string['appearsinsubcontexts'] = 'Appears in sub-contexts';
+$string['assignrolesinblock'] = 'Assign roles in {$a} block';
$string['blocksettings'] = 'Block settings';
$string['bracketfirst'] = '{$a} (first)';
$string['bracketlast'] = '{$a} (last)';
+$string['configureblock'] = 'Configure {$a} block';
$string['contexts'] = 'Page contexts';
$string['contexts_help'] = 'Contexts are more specific types of pages where this block can be displayed within the original block location. You will have different options here depending on the original block location and your current location. For example, you can restrict a block to only appearing on forum pages in a course by adding the block to the course (making it appear on all sub-pages), then going into a forum and editing the block settings again to restrict display to just forum pages.';
$string['createdat'] = 'Original block location';
$string['defaultweight'] = 'Default weight';
$string['defaultweight_help'] = 'The default weight allows you to choose roughly where you want the block to appear in the chosen region, either at the top or the bottom. The final location is calculated from all the blocks in that region (for example, only one block can actually be at the top). This value can be overridden on specific pages if required.';
$string['deletecheck'] = 'Delete {$a} block?';
+$string['deleteblock'] = 'Delete {$a} block';
$string['deleteblockcheck'] = 'Are you sure that you want to delete this block titled {$a}?';
+$string['hideblock'] = 'Hide {$a} block';
$string['hidedockpanel'] = 'Hide the dock panel';
$string['hidepanel'] = 'Hide panel';
+$string['moveblock'] = 'Move {$a} block';
$string['moveblockhere'] = 'Move block here';
$string['movingthisblockcancel'] = 'Moving this block ({$a})';
$string['onthispage'] = 'On this page';
$string['pagetypes'] = 'Page types';
$string['pagetypewarning'] = 'The previously specified page type is no longer selectable. Please choose the most appropriate page type below.';
$string['region'] = 'Region';
+$string['showblock'] = 'Show {$a} block';
$string['showoncontextandsubs'] = 'Display on \'{$a}\' and any pages within it';
$string['showoncontextonly'] = 'Display on \'{$a}\' only';
$string['showonentiresite'] = 'Display throughout the entire site';
$string['invalidcategoryidtomove'] = 'Invalid category id to move!';
$string['invalidconfirm'] = 'Confirmation string was incorrect';
$string['invalidcontextinhasanyquestions'] = 'Invalid context passed to question_context_has_any_questions.';
+$string['invalidgrade'] = 'Grades ({$a}) do not match grade options - question skipped.';
$string['invalidpenalty'] = 'Invalid penalty';
$string['invalidwizardpage'] = 'Incorrect or no wizard page specified!';
$string['lastmodifiedby'] = 'Last modified by';
$string['linkedfiledoesntexist'] = 'Linked file {$a} doesn\'t exist';
$string['makechildof'] = 'Make child of \'{$a}\'';
$string['maketoplevelitem'] = 'Move to top level';
-$string['matcherror'] = 'Grades do not match grade options - question skipped';
$string['matchgrades'] = 'Match grades';
$string['matchgradeserror'] = 'Error if grade not listed';
$string['matchgradesnearest'] = 'Nearest grade if not listed';
if ($this->page->user_can_edit_blocks()) {
// Move icon.
$controls[] = array('url' => $actionurl . '&bui_moveid=' . $block->instance->id,
- 'icon' => 't/move', 'caption' => get_string('move'), 'class' => 'editing_move');
+ 'icon' => 't/move', 'caption' => get_string('moveblock', 'block', $block->title),
+ 'class' => 'editing_move');
}
if ($this->page->user_can_edit_blocks() || $block->user_can_edit()) {
// Edit config icon - always show - needed for positioning UI.
$controls[] = array('url' => $actionurl . '&bui_editid=' . $block->instance->id,
- 'icon' => 't/edit', 'caption' => get_string('configuration'), 'class' => 'editing_edit');
+ 'icon' => 't/edit', 'caption' => get_string('configureblock', 'block', $block->title),
+ 'class' => 'editing_edit');
}
if ($this->page->user_can_edit_blocks() && $block->user_can_edit() && $block->user_can_addto($this->page)) {
|| $block->instance->parentcontextid != SITEID) {
// Delete icon.
$controls[] = array('url' => $actionurl . '&bui_deleteid=' . $block->instance->id,
- 'icon' => 't/delete', 'caption' => get_string('delete'), 'class' => 'editing_delete');
+ 'icon' => 't/delete', 'caption' => get_string('deleteblock', 'block', $block->title),
+ 'class' => 'editing_delete');
}
}
// Show/hide icon.
if ($block->instance->visible) {
$controls[] = array('url' => $actionurl . '&bui_hideid=' . $block->instance->id,
- 'icon' => 't/hide', 'caption' => get_string('hide'), 'class' => 'editing_hide');
+ 'icon' => 't/hide', 'caption' => get_string('hideblock', 'block', $block->title),
+ 'class' => 'editing_hide');
} else {
$controls[] = array('url' => $actionurl . '&bui_showid=' . $block->instance->id,
- 'icon' => 't/show', 'caption' => get_string('show'), 'class' => 'editing_show');
+ 'icon' => 't/show', 'caption' => get_string('showblock', 'block', $block->title),
+ 'class' => 'editing_show');
}
}
$controls[] = array('url' => $CFG->wwwroot . '/' . $CFG->admin .
'/roles/assign.php?contextid=' . $block->context->id . '&returnurl=' . urlencode($return),
- 'icon' => 'i/roles', 'caption' => get_string('assignroles', 'role'), 'class' => 'editing_roles');
+ 'icon' => 'i/roles', 'caption' => get_string('assignrolesinblock', 'block', $block->title),
+ 'class' => 'editing_roles');
}
return $controls;
} else if ($data = $mform->get_data()) {
$bi = new stdClass;
$bi->id = $block->instance->id;
+
+ // This may get overwritten by the special case handling below.
$bi->pagetypepattern = $data->bui_pagetypepattern;
+ $bi->showinsubcontexts = (bool) $data->bui_contexts;
if (empty($data->bui_subpagepattern) || $data->bui_subpagepattern == '%@NULL@%') {
$bi->subpagepattern = null;
} else {
* @return bool
*/
public function is_tracked_user($userid) {
- return is_enrolled(context_course::instance($this->course->id), $userid, '', true);
+ return is_enrolled(context_course::instance($this->course->id), $userid, 'moodle/course:isincompletionreports', true);
}
/**
global $DB;
list($enrolledsql, $enrolledparams) = get_enrolled_sql(
- context_course::instance($this->course->id), '', $groupid, true);
+ context_course::instance($this->course->id), 'moodle/course:isincompletionreports', $groupid, true);
$sql = 'SELECT COUNT(eu.id) FROM (' . $enrolledsql . ') eu JOIN {user} u ON u.id = eu.id';
if ($where) {
$sql .= " WHERE $where";
'isf' => array ('type'=>'application/inspiration', 'icon'=>'isf'),
'ist' => array ('type'=>'application/inspiration.template', 'icon'=>'isf'),
'java' => array ('type'=>'text/plain', 'icon'=>'sourcecode'),
+ 'jar' => array ('type'=>'application/java-archive', 'icon' => 'archive'),
'jcb' => array ('type'=>'text/xml', 'icon'=>'markup'),
'jcl' => array ('type'=>'text/xml', 'icon'=>'markup'),
'jcw' => array ('type'=>'text/xml', 'icon'=>'markup'),
if (!overwrite) {
this.currentfilecount++;
}
- if (this.options.maxfiles > 0 && this.currentfilecount > this.options.maxfiles) {
+ // The value for "unlimited files" is -1, so 0 should mean 0.
+ if (this.options.maxfiles >= 0 && this.currentfilecount > this.options.maxfiles) {
// Too many files - abort entire upload.
this.uploadqueue = [];
this.renamequeue = [];
scope: scope
},
headers: {
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
- 'User-Agent': 'MoodleFileManager/3.0'
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
data: build_querystring(params)
};
on('keydown', function(e){
if (e.keyCode == 13) {Y.bind(perform_action, this)(e);}
}, this);
+ node.one('label').set('for', 'fm-newname-' + this.client_id);
node.all('.fp-dlg-butcancel').on('click', function(e){e.preventDefault();this.mkdir_dialog.hide();}, this);
node.all('.fp-dlg-curpath').set('id', 'fm-curpath-'+this.client_id);
}
$defaults['defaultlicense'] = $CFG->sitedefaultlicense;
}
foreach ($defaults as $key=>$value) {
- if (empty($options->$key)) {
+ // Using !isset() prevents us from overwriting falsey values with defaults (as empty() did).
+ if (!isset($options->$key)) {
$options->$key = $value;
}
}
}
}
+/**
+ * Set focus on login error message
+ */
+M.util.focus_login_error = function(Y) {
+ var errorlog = Y.one('#loginerrormessage');
+
+ if (errorlog) {
+ errorlog.focus();
+ }
+}
/**
* Adds lightbox hidden element that covers the whole node.
*
$lastpage = 1;
}
- if ($this->page > 15) {
- $startpage = $this->page - 10;
+ if ($this->page > round(($this->maxdisplay/3)*2)) {
+ $currpage = $this->page - round($this->maxdisplay/3);
$this->firstlink = html_writer::link(new moodle_url($this->baseurl, array($this->pagevar=>0)), '1', array('class'=>'first'));
} else {
- $startpage = 0;
+ $currpage = 0;
}
- $currpage = $startpage;
$displaycount = $displaypage = 0;
while ($displaycount < $this->maxdisplay and $currpage < $lastpage) {
if (!isset($CFG->phpunit_dataroot)) {
phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGERROR, 'Missing $CFG->phpunit_dataroot in config.php, can not run tests!');
}
+// Ensure we access to phpunit_dataroot realpath always.
+$CFG->phpunit_dataroot = realpath($CFG->phpunit_dataroot);
+
if (isset($CFG->dataroot) and $CFG->phpunit_dataroot === $CFG->dataroot) {
phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGERROR, '$CFG->dataroot and $CFG->phpunit_dataroot must not be identical, can not run tests!');
}
$plagiarismplugin->cron();
}
}
-/**
+/**
* helper function - also loads lib file of plagiarism plugin
* @return array of available plugins
*/
}
function test_out_as_local_url() {
+ global $CFG;
+ // Test http url.
$url1 = new moodle_url('/lib/tests/weblib_test.php');
$this->assertEquals('/lib/tests/weblib_test.php', $url1->out_as_local_url());
+
+ // Test https url.
+ $httpswwwroot = str_replace("http://", "https://", $CFG->wwwroot);
+ $url2 = new moodle_url($httpswwwroot.'/login/profile.php');
+ $this->assertEquals('/login/profile.php', $url2->out_as_local_url());
+
+ // Test http url matching wwwroot.
+ $url3 = new moodle_url($CFG->wwwroot);
+ $this->assertEquals('', $url3->out_as_local_url());
+
+ // Test http url matching wwwroot ending with slash (/).
+ $url3 = new moodle_url($CFG->wwwroot.'/');
+ $this->assertEquals('/', $url3->out_as_local_url());
}
/**
$url2->out_as_local_url();
}
+ /**
+ * You should get error with modified url
+ *
+ * @expectedException coding_exception
+ * @return void
+ */
+ public function test_modified_url_out_as_local_url_error() {
+ global $CFG;
+
+ $modifiedurl = $CFG->wwwroot.'1';
+ $url3 = new moodle_url($modifiedurl.'/login/profile.php');
+ $url3->out_as_local_url();
+ }
+
+ /**
+ * Try get local url from external https url and you should get error
+ *
+ * @expectedException coding_exception
+ * @return void
+ */
+ public function test_https_out_as_local_url_error() {
+ $url4 = new moodle_url('https://www.google.com/lib/tests/weblib_test.php');
+ $url4->out_as_local_url();
+ }
+
public function test_clean_text() {
$text = "lala <applet>xx</applet>";
$this->assertEquals($text, clean_text($text, FORMAT_PLAIN));
global $CFG;
$url = $this->out($escaped, $overrideparams);
-
- if (strpos($url, $CFG->wwwroot) !== 0) {
+ $httpswwwroot = str_replace("http://", "https://", $CFG->wwwroot);
+
+ // $url should be equal to wwwroot or httpswwwroot. If not then throw exception.
+ if (($url === $CFG->wwwroot) || (strpos($url, $CFG->wwwroot.'/') === 0)) {
+ $localurl = substr($url, strlen($CFG->wwwroot));
+ return !empty($localurl) ? $localurl : '';
+ } else if (($url === $httpswwwroot) || (strpos($url, $httpswwwroot.'/') === 0)) {
+ $localurl = substr($url, strlen($httpswwwroot));
+ return !empty($localurl) ? $localurl : '';
+ } else {
throw new coding_exception('out_as_local_url called on a non-local URL');
}
-
- return str_replace($CFG->wwwroot, '', $url);
}
/**
},
prepare_chooser : function () {
- if (this.overlay) {
+ if (this.panel) {
return;
}
}
// Assign this select items 'nothing' value and lastindex (current value)
- var thisselect = Y.one('select#' + this.get('selectid'));
- thisselect.setData('nothing', this.get('nothing'));
- thisselect.setData('startindex', thisselect.get('selectedIndex'));
+ if (this.get('selectid')) {
+ var thisselect = Y.one('select#' + this.get('selectid'));
+ if (thisselect) {
+ if (this.get('nothing')) {
+ thisselect.setData('nothing', this.get('nothing'));
+ }
+ thisselect.setData('startindex', thisselect.get('selectedIndex'));
+ } else {
+ Y.log("Warning: A single_select element was renderered, but the output is not displayed on the page.");
+ }
+ }
},
/**
echo $OUTPUT->box_end();
} else {
include("index_form.html");
- if (!empty($CFG->loginpageautofocus)) {
+ if ($errormsg) {
+ $PAGE->requires->js_init_call('M.util.focus_login_error', null, true);
+ } else if (!empty($CFG->loginpageautofocus)) {
//focus username or password
$PAGE->requires->js_init_call('M.util.focus_login_form', null, true);
}
</div>
<?php
if (!empty($errormsg)) {
- echo '<div class="loginerrors">';
+ echo html_writer::start_tag('div', array('class' => 'loginerrors'));
+ echo html_writer::link('#', $errormsg, array('id' => 'loginerrormessage', 'class' => 'accesshide'));
echo $OUTPUT->error_text($errormsg);
- echo '</div>';
+ echo html_writer::end_tag('div');
}
?>
<form action="<?php echo $CFG->httpswwwroot; ?>/login/index.php" method="post" id="login" <?php echo $autocomplete; ?> >
}
}
- $mform->addElement('editor', 'assignfeedbackcomments_editor', '', null, null);
+ $mform->addElement('editor', 'assignfeedbackcomments_editor', html_writer::tag('span', $this->get_name(),
+ array('class' => 'accesshide')), null, null);
+
return true;
}
'assignfeedback_file',
ASSIGNFEEDBACK_FILE_FILEAREA,
$gradeid);
-
- $mform->addElement('filemanager', $elementname . '_filemanager', '', null, $fileoptions);
+ $mform->addElement('filemanager', $elementname . '_filemanager', html_writer::tag('span', $this->get_name(),
+ array('class' => 'accesshide')), null, $fileoptions);
return true;
}
// get all user submissions, indexed by assignment id
$mysubmissions = $DB->get_records_sql("SELECT a.id AS assignment, a.nosubmissions AS nosubmissions, g.timemodified AS timemarked, g.grader AS grader, g.grade AS grade, s.status AS status
FROM {assign} a LEFT JOIN {assign_grades} g ON g.assignment = a.id AND g.userid = ? LEFT JOIN {assign_submission} s ON s.assignment = a.id AND s.userid = ?
- AND a.id $sqlassignmentids", array_merge(array($USER->id, $USER->id), $assignmentidparams));
+ WHERE a.id $sqlassignmentids", array($USER->id, $USER->id));
foreach ($assignments as $assignment) {
// Do not show assignments that are not open
* @return bool was it a success? (false will trigger a rollback)
*/
public function upgrade_settings(context $oldcontext, stdClass $oldassignment, & $log) {
- // first upgrade settings (nothing to do)
+ if ($oldassignment->assignmenttype == 'upload') {
+ // Disable if allow notes was not enabled.
+ if (!$oldassignment->var2) {
+ $this->disable();
+ }
+ }
return true;
}
$fileoptions = $this->get_file_options();
$submissionid = $submission ? $submission->id : 0;
-
$data = file_prepare_standard_filemanager($data, 'files', $fileoptions, $this->assignment->get_context(), 'assignsubmission_file', ASSIGNSUBMISSION_FILE_FILEAREA, $submissionid);
- $mform->addElement('filemanager', 'files_filemanager', '', null, $fileoptions);
+ $mform->addElement('filemanager', 'files_filemanager', html_writer::tag('span', $this->get_name(),
+ array('class' => 'accesshide')), null, $fileoptions);
+
return true;
}
* @return bool Was it a success? (false will trigger rollback)
*/
public function upgrade_settings(context $oldcontext,stdClass $oldassignment, & $log) {
+ global $DB;
+
if ($oldassignment->assignmenttype == 'uploadsingle') {
$this->set_config('maxfilesubmissions', 1);
$this->set_config('maxsubmissionsizebytes', $oldassignment->maxbytes);
return true;
- }else {
-
+ } else if ($oldassignment->assignmenttype == 'upload') {
$this->set_config('maxfilesubmissions', $oldassignment->var1);
$this->set_config('maxsubmissionsizebytes', $oldassignment->maxbytes);
+
+ // Advanced file upload uses a different setting to do the same thing.
+ $DB->set_field('assign',
+ 'submissiondrafts',
+ $oldassignment->var4,
+ array('id'=>$this->assignment->get_instance()->id));
+
+ // Convert advanced file upload "hide description before due date" setting.
+ $alwaysshow = 0;
+ if (!$oldassignment->var3) {
+ $alwaysshow = 1;
+ }
+ $DB->set_field('assign',
+ 'alwaysshowdescription',
+ $alwaysshow,
+ array('id'=>$this->assignment->get_instance()->id));
return true;
}
}
-
$data = file_prepare_standard_editor($data, 'onlinetext', $editoroptions, $this->assignment->get_context(), 'assignsubmission_onlinetext', ASSIGNSUBMISSION_ONLINETEXT_FILEAREA, $submissionid);
- $mform->addElement('editor', 'onlinetext_editor', '', null, $editoroptions);
+ $mform->addElement('editor', 'onlinetext_editor', html_writer::tag('span', $this->get_name(),
+ array('class' => 'accesshide')), null, $editoroptions);
+
return true;
}
$gradingdefinitions = $DB->get_records('grading_definitions', array('areaid'=>$gradingarea->id));
}
+ // Upgrade availability data.
+ $DB->set_field('course_modules_availability',
+ 'coursemoduleid',
+ $newcoursemodule->id,
+ array('coursemoduleid'=>$oldcoursemodule->id));
+ $DB->set_field('course_modules_availability',
+ 'sourcecmid',
+ $newcoursemodule->id,
+ array('sourcecmid'=>$oldcoursemodule->id));
+ $DB->set_field('course_sections_availability',
+ 'sourcecmid',
+ $newcoursemodule->id,
+ array('sourcecmid'=>$oldcoursemodule->id));
+
// upgrade completion data
$DB->set_field('course_modules_completion', 'coursemoduleid', $newcoursemodule->id, array('coursemoduleid'=>$oldcoursemodule->id));
$allcriteria = $DB->get_records('course_completion_criteria', array('moduleinstance'=>$oldcoursemodule->id));
}
if ($type == 0) {
$chapterfile = reset($chapterfiles);
- if ($file = $fs->get_file_by_hash("$context->id/mod_book/importhtmltemp/0/$chapterfile->pathname")) {
+ if ($file = $fs->get_file_by_hash(sha1("$context->id/mod_book/importhtmltemp/0/$chapterfile->pathname"))) {
$htmlcontent = toolbook_importhtml_fix_encoding($file->get_content());
$htmlchapters = toolbook_importhtml_parse_headings(toolbook_importhtml_parse_body($htmlcontent));
// TODO: process h1 as main chapter and h2 as subchapters
$rules[] = new restore_log_rule('forum', 'delete discussion', 'view.php?id={course_module}', '{forum}');
$rules[] = new restore_log_rule('forum', 'add post', 'discuss.php?d={forum_discussion}&parent={forum_post}', '{forum_post}');
$rules[] = new restore_log_rule('forum', 'update post', 'discuss.php?d={forum_discussion}#p{forum_post}&parent={forum_post}', '{forum_post}');
+ $rules[] = new restore_log_rule('forum', 'update post', 'discuss.php?d={forum_discussion}&parent={forum_post}', '{forum_post}');
$rules[] = new restore_log_rule('forum', 'prune post', 'discuss.php?d={forum_discussion}', '{forum_post}');
$rules[] = new restore_log_rule('forum', 'delete post', 'discuss.php?d={forum_discussion}', '[post]');
$eventdata->fullmessagehtml = $posthtml;
$eventdata->notification = 1;
+ // If forum_replytouser is not set then send mail using the noreplyaddress.
+ if (empty($CFG->forum_replytouser)) {
+ // Clone userfrom as it is referenced by $users.
+ $cloneduserfrom = clone($userfrom);
+ $cloneduserfrom->email = $CFG->noreplyaddress;
+ $eventdata->userfrom = $cloneduserfrom;
+ }
+
$smallmessagestrings = new stdClass();
$smallmessagestrings->user = fullname($userfrom);
$smallmessagestrings->forumname = "$shortname: ".format_string($forum->name,true).": ".$discussion->name;
}
$attachment = $attachname='';
- $usetrueaddress = true;
// Directly email forum digests rather than sending them via messaging, use the
// site shortname as 'from name', the noreply address will be used by email_to_user.
- $mailresult = email_to_user($userto, $site->shortname, $postsubject, $posttext, $posthtml, $attachment, $attachname, $usetrueaddress, $CFG->forum_replytouser);
+ $mailresult = email_to_user($userto, $site->shortname, $postsubject, $posttext, $posthtml, $attachment, $attachname);
if (!$mailresult) {
mtrace("ERROR!");
}
if (count($this->answers)>0) {
$count = 0;
+ $qtype = $properties->qtype;
foreach ($this->answers as $answer) {
- $properties->{'answer_editor['.$count.']'} = array('text'=>$answer->answer, 'format'=>$answer->answerformat);
- $properties->{'response_editor['.$count.']'} = array('text'=>$answer->response, 'format'=>$answer->responseformat);
+ $properties->{'answer_editor['.$count.']'} = array('text' => $answer->answer, 'format' => $answer->answerformat);
+ if ($qtype != LESSON_PAGE_MATCHING) {
+ $properties->{'response_editor['.$count.']'} = array('text' => $answer->response, 'format' => $answer->responseformat);
+ } else {
+ $properties->{'response_editor['.$count.']'} = $answer->response;
+ }
$properties->{'jumpto['.$count.']'} = $answer->jumpto;
$properties->{'score['.$count.']'} = $answer->score;
$count++;
} else {
$essayinfo = new stdClass();
$essayinfo->answer = get_string("didnotanswerquestion", "lesson");
+ $essayinfo->answerformat = null;
}
if (isset($pagestats[$this->properties->id])) {
foreach ($answers as $answer) {
// get all the response
if ($answer->response != NULL) {
- $responses[] = trim($answer->response);
+ $responses[$answer->id] = trim($answer->response);
}
}
$responseoptions = array(''=>get_string('choosedots'));
if (!empty($responses)) {
- shuffle($responses);
- $responses = array_unique($responses);
- foreach ($responses as $response) {
- $responseoptions[htmlspecialchars(trim($response))] = $response;
+ $shuffleresponses = $responses;
+ shuffle($shuffleresponses);
+ foreach ($shuffleresponses as $response) {
+ $key = array_search($response, $responses);
+ $responseoptions[$key] = $response;
}
}
if (isset($USER->modattempts[$this->lesson->id]) && !empty($attempt->useranswer)) {
$answer->answer = $properties->answer_editor[$i]['text'];
$answer->answerformat = $properties->answer_editor[$i]['format'];
}
- if (!empty($properties->response_editor[$i]) && is_array($properties->response_editor[$i])) {
- $answer->response = $properties->response_editor[$i]['text'];
- $answer->responseformat = $properties->response_editor[$i]['format'];
+ if (!empty($properties->response_editor[$i])) {
+ $answer->response = $properties->response_editor[$i];
+ $answer->responseformat = 0;
}
if (isset($properties->jumpto[$i])) {
$wrong = array_shift($answers);
foreach ($answers as $key=>$answer) {
- if ($answer->answer === '' or $answer->response === '') {
- // incomplete option!
- unset($answers[$key]);
+ if ($answer->answer !== '' or $answer->response !== '') {
+ $answers[$answer->id] = $answer;
}
+ unset($answers[$key]);
}
// get he users exact responses for record keeping
$hits = 0;
$userresponse = array();
- foreach ($response as $key => $value) {
- foreach($answers as $answer) {
- if ($value === $answer->response) {
- $userresponse[] = $answer->id;
- }
- if ((int)$answer->id === (int)$key) {
- $result->studentanswer .= '<br />'.format_text($answer->answer, $answer->answerformat, $formattextdefoptions).' = '.$value;
- }
- if ((int)$answer->id === (int)$key and $value === $answer->response) {
+ foreach ($response as $id => $value) {
+ $userresponse[] = $value;
+ // Make sure the user's answer is exist in question's answer
+ if (array_key_exists($id, $answers)) {
+ $answer = $answers[$id];
+ $result->studentanswer .= '<br />'.format_text($answer->answer, $answer->answerformat, $formattextdefoptions).' = '.$answers[$value]->response;
+ if ($id == $value) {
$hits++;
}
}
}
+
$result->userresponse = implode(",", $userresponse);
if ($hits == count($answers)) {
$this->answers[$i]->answer = $properties->answer_editor[$i]['text'];
$this->answers[$i]->answerformat = $properties->answer_editor[$i]['format'];
}
- if (!empty($properties->response_editor[$i]) && is_array($properties->response_editor[$i])) {
- $this->answers[$i]->response = $properties->response_editor[$i]['text'];
- $this->answers[$i]->responseformat = $properties->response_editor[$i]['format'];
+ if (!empty($properties->response_editor[$i])) {
+ $this->answers[$i]->response = $properties->response_editor[$i];
+ $this->answers[$i]->responseformat = 0;
}
if (isset($properties->jumpto[$i])) {
for ($i = 2; $i < $this->_customdata['lesson']->maxanswers+2; $i++) {
$this->_form->addElement('header', 'matchingpair'.($i-1), get_string('matchingpair', 'lesson', $i-1));
$this->add_answer($i, NULL, ($i < 4));
- $this->add_response($i, get_string('matchesanswer','lesson'), ($i < 4));
+ $required = ($i < 4);
+ $label = get_string('matchesanswer','lesson');
+ $count = $i;
+ $this->_form->addElement('text', 'response_editor['.$count.']', $label, array('size'=>'50'));
+ $this->_form->setDefault('response_editor['.$count.']', '');
+ if ($required) {
+ $this->_form->addRule('response_editor['.$count.']', get_string('required'), 'required', null, 'client');
+ }
}
}
}
-
class lesson_display_answer_form_matching extends moodleform {
public function definition() {
$data->timestart = $this->apply_date_offset($data->timestart);
$data->timefinish = $this->apply_date_offset($data->timefinish);
$data->timemodified = $this->apply_date_offset($data->timemodified);
- $data->timecheckstate = $this->apply_date_offset($data->timecheckstate);
+ if (!empty($data->timecheckstate)) {
+ $data->timecheckstate = $this->apply_date_offset($data->timecheckstate);
+ } else {
+ $data->timecheckstate = 0;
+ }
// Deals with up-grading pre-2.3 back-ups to 2.3+.
if (!isset($data->state)) {
// SQL to compute timeclose and timelimit for each attempt:
- $quizausersql = quiz_get_attempt_usertime_sql();
+ $quizausersql = quiz_get_attempt_usertime_sql(
+ "iquiza.state IN ('inprogress', 'overdue') AND iquiza.timecheckstate <= :iprocessto");
// This query should have all the quiz_attempts columns.
return $DB->get_recordset_sql("
AND quiza.timecheckstate <= :processto
ORDER BY quiz.course, quiza.quiz",
- array('processto' => $processto));
+ array('processto' => $processto, 'iprocessto' => $processto));
}
}
}
$params = array();
- $coursecond = '';
- $usercond = '';
- $quizcond = '';
- $groupcond = '';
+ $wheres = array("quiza.state IN ('inprogress', 'overdue')");
+ $iwheres = array("iquiza.state IN ('inprogress', 'overdue')");
if (isset($conditions['courseid'])) {
list ($incond, $inparams) = $DB->get_in_or_equal($conditions['courseid'], SQL_PARAMS_NAMED, 'cid');
$params = array_merge($params, $inparams);
- $coursecond = "AND quiza.quiz IN (SELECT q.id FROM {quiz} q WHERE q.course $incond)";
+ $wheres[] = "quiza.quiz IN (SELECT q.id FROM {quiz} q WHERE q.course $incond)";
+ list ($incond, $inparams) = $DB->get_in_or_equal($conditions['courseid'], SQL_PARAMS_NAMED, 'icid');
+ $params = array_merge($params, $inparams);
+ $iwheres[] = "iquiza.quiz IN (SELECT q.id FROM {quiz} q WHERE q.course $incond)";
}
+
if (isset($conditions['userid'])) {
list ($incond, $inparams) = $DB->get_in_or_equal($conditions['userid'], SQL_PARAMS_NAMED, 'uid');
$params = array_merge($params, $inparams);
- $usercond = "AND quiza.userid $incond";
+ $wheres[] = "quiza.userid $incond";
+ list ($incond, $inparams) = $DB->get_in_or_equal($conditions['userid'], SQL_PARAMS_NAMED, 'iuid');
+ $params = array_merge($params, $inparams);
+ $iwheres[] = "iquiza.userid $incond";
}
+
if (isset($conditions['quizid'])) {
list ($incond, $inparams) = $DB->get_in_or_equal($conditions['quizid'], SQL_PARAMS_NAMED, 'qid');
$params = array_merge($params, $inparams);
- $quizcond = "AND quiza.quiz $incond";
+ $wheres[] = "quiza.quiz $incond";
+ list ($incond, $inparams) = $DB->get_in_or_equal($conditions['quizid'], SQL_PARAMS_NAMED, 'iqid');
+ $params = array_merge($params, $inparams);
+ $iwheres[] = "iquiza.quiz $incond";
}
+
if (isset($conditions['groupid'])) {
list ($incond, $inparams) = $DB->get_in_or_equal($conditions['groupid'], SQL_PARAMS_NAMED, 'gid');
$params = array_merge($params, $inparams);
- $groupcond = "AND quiza.quiz IN (SELECT qo.quiz FROM {quiz_overrides} qo WHERE qo.groupid $incond)";
+ $wheres[] = "quiza.quiz IN (SELECT qo.quiz FROM {quiz_overrides} qo WHERE qo.groupid $incond)";
+ list ($incond, $inparams) = $DB->get_in_or_equal($conditions['groupid'], SQL_PARAMS_NAMED, 'igid');
+ $params = array_merge($params, $inparams);
+ $iwheres[] = "iquiza.quiz IN (SELECT qo.quiz FROM {quiz_overrides} qo WHERE qo.groupid $incond)";
}
// SQL to compute timeclose and timelimit for each attempt:
- $quizausersql = quiz_get_attempt_usertime_sql();
+ $quizausersql = quiz_get_attempt_usertime_sql(
+ implode("\n AND ", $iwheres));
// SQL to compute the new timecheckstate
$timecheckstatesql = "
CASE WHEN quiza.state = 'overdue' THEN quiz.graceperiod ELSE 0 END";
// SQL to select which attempts to process
- $attemptselect = " quiza.state IN ('inprogress', 'overdue')
- $coursecond
- $usercond
- $quizcond
- $groupcond";
+ $attemptselect = implode("\n AND ", $wheres);
/*
* Each database handles updates with inner joins differently:
/**
* Returns SQL to compute timeclose and timelimit for every attempt, taking into account user and group overrides.
*
- * @return string SQL select with columns attempt.id, usertimeclose, usertimelimit
+ * @param string $redundantwhereclauses extra where clauses to add to the subquery
+ * for performance. These can use the table alias iquiza for the quiz attempts table.
+ * @return string SQL select with columns attempt.id, usertimeclose, usertimelimit.
*/
-function quiz_get_attempt_usertime_sql() {
+function quiz_get_attempt_usertime_sql($redundantwhereclauses = '') {
+ if ($redundantwhereclauses) {
+ $redundantwhereclauses = 'WHERE ' . $redundantwhereclauses;
+ }
// The multiple qgo JOINS are necessary because we want timeclose/timelimit = 0 (unlimited) to supercede
// any other group override
$quizausersql = "
LEFT JOIN {quiz_overrides} qgo2 ON qgo2.quiz = iquiza.quiz AND qgo2.groupid = gm.groupid AND qgo2.timeclose > 0
LEFT JOIN {quiz_overrides} qgo3 ON qgo3.quiz = iquiza.quiz AND qgo3.groupid = gm.groupid AND qgo3.timelimit = 0
LEFT JOIN {quiz_overrides} qgo4 ON qgo4.quiz = iquiza.quiz AND qgo4.groupid = gm.groupid AND qgo4.timelimit > 0
+ $redundantwhereclauses
GROUP BY iquiza.id, iquiz.id, iquiz.timeclose, iquiz.timelimit";
return $quizausersql;
}
}
function scorm_view_display ($user, $scorm, $action, $cm) {
- global $CFG, $DB, $PAGE, $OUTPUT;
+ global $CFG, $DB, $PAGE, $OUTPUT, $COURSE;
if ($scorm->scormtype != SCORM_TYPE_LOCAL && $scorm->updatefreq == SCORM_UPDATE_EVERYTIME) {
scorm_parse($scorm, false);
<label for="a"><?php print_string('newattempt', 'scorm') ?></label>
<?php
}
- if (!empty($scorm->popup)) {
+ if ($COURSE->format != 'scorm' && !empty($scorm->popup)) {
echo '<input type="hidden" name="display" value="popup" />'."\n";
}
?>
$string['savingerror'] = 'Saving error';
$string['searchcontent'] = 'Search in page content';
$string['searchresult'] = 'Search results:';
+$string['searchterms'] = 'Search terms';
$string['searchwikis'] = 'Search wikis';
$string['special'] = 'Special';
$string['tableofcontents'] = 'Table of contents';
$output = '<div class="wikisearch">';
$output .= '<form method="post" action="' . $CFG->wwwroot . '/mod/wiki/search.php" style="display:inline">';
$output .= '<fieldset class="invisiblefieldset">';
- $output .= '<label class="accesshide" for="searchwiki">' . get_string("searchwikis", "wiki") . '</label>';
+ $output .= '<legend class="accesshide">'. get_string('searchwikis', 'wiki') .'</legend>';
+ $output .= '<label class="accesshide" for="searchwiki">' . get_string("searchterms", "wiki") . '</label>';
$output .= '<input id="searchwiki" name="searchstring" type="text" size="18" value="' . s($search, true) . '" alt="search" />';
$output .= '<input name="courseid" type="hidden" value="' . $cm->course . '" />';
$output .= '<input name="cmid" type="hidden" value="' . $cm->id . '" />';
foreach ($questions as $question) {
if (!empty($question->fraction) and (is_array($question->fraction))) {
$fractions = $question->fraction;
- $answersvalid = true; // in case they are!
+ $invalidfractions = array();
foreach ($fractions as $key => $fraction) {
$newfraction = match_grade_options($gradeoptionsfull, $fraction,
$this->matchgrades);
if ($newfraction === false) {
- $answersvalid = false;
+ $invalidfractions[] = $fraction;
} else {
$fractions[$key] = $newfraction;
}
}
- if (!$answersvalid) {
- echo $OUTPUT->notification(get_string('invalidgrade', 'question'));
+ if ($invalidfractions) {
+ echo $OUTPUT->notification(get_string('invalidgrade', 'question',
+ implode(', ', $invalidfractions)));
++$gradeerrors;
continue;
} else {
return $xml;
}
+ public function import_text_with_files($data, $path, $defaultvalue = '', $defaultformat = 'html') {
+ $field = array();
+ $field['text'] = $this->getpath($data,
+ array_merge($path, array('#', 'text', 0, '#')), $defaultvalue, true);
+ $field['format'] = $this->trans_format($this->getpath($data,
+ array_merge($path, array('@', 'format')), $defaultformat));
+ $itemid = $this->import_files_as_draft($this->getpath($data,
+ array_merge($path, array('#', 'file')), array(), false));
+ if (!empty($itemid)) {
+ $field['itemid'] = $itemid;
+ }
+ return $field;
+ }
+
+ public function import_files_as_draft($xml) {
+ global $USER;
+ if (empty($xml)) {
+ return null;
+ }
+ $fs = get_file_storage();
+ $itemid = file_get_unused_draft_itemid();
+ foreach ($xml as $file) {
+ $filerecord = array(
+ 'contextid' => context_user::instance($USER->id)->id,
+ 'component' => 'user',
+ 'filearea' => 'draft',
+ 'itemid' => $itemid,
+ 'filepath' => '/',
+ 'filename' => $file['@']['name'],
+ );
+ $fs->create_file_from_string($filerecord, base64_decode($file['#']));
+ }
+ return $itemid;
+ }
/**
* import parts of question common to all types
* @return object question object
*/
public function import_headers($question) {
- global $CFG;
+ global $CFG, $USER;
// get some error strings
$error_noname = get_string('xmlimportnoname', 'qformat_xml');
$qo->name = $this->clean_question_name($this->getpath($question,
array('#', 'name', 0, '#', 'text', 0, '#'), '', true,
get_string('xmlimportnoname', 'qformat_xml')));
- $qo->questiontext = $this->getpath($question,
- array('#', 'questiontext', 0, '#', 'text', 0, '#'), '', true);
- $qo->questiontextformat = $this->trans_format($this->getpath(
- $question, array('#', 'questiontext', 0, '@', 'format'), 'html'));
-
- $qo->questiontextfiles = $this->import_files($this->getpath($question,
- array('#', 'questiontext', 0, '#', 'file'), array(), false));
-
+ $questiontext = $this->import_text_with_files($question,
+ array('#', 'questiontext', 0));
+ $qo->questiontext = $questiontext['text'];
+ $qo->questiontextformat = $questiontext['format'];
+ if (!empty($questiontext['itemid'])) {
+ $qo->questiontextitemid = $questiontext['itemid'];
+ }
// Backwards compatibility, deal with the old image tag.
$filedata = $this->getpath($question, array('#', 'image_base64', '0', '#'), null, false);
$filename = $this->getpath($question, array('#', 'image', '0', '#'), null, false);
if ($filedata && $filename) {
- $data = new stdClass();
- $data->content = $filedata;
- $data->encoding = 'base64';
- // Question file areas don't support subdirs, so convert path to filename if necessary.
- $data->name = clean_param(str_replace('/', '_', $filename), PARAM_FILE);
- $qo->questiontextfiles[] = $data;
- $qo->questiontext .= ' <img src="@@PLUGINFILE@@/' . $data->name . '" />';
+ $fs = get_file_storage();
+ if (empty($qo->questiontextitemid)) {
+ $qo->questiontextitemid = file_get_unused_draft_itemid();
+ }
+ $filename = clean_param(str_replace('/', '_', $filename), PARAM_FILE);
+ $filerecord = array(
+ 'contextid' => context_user::instance($USER->id)->id,
+ 'component' => 'user',
+ 'filearea' => 'draft',
+ 'itemid' => $qo->questiontextitemid,
+ 'filepath' => '/',
+ 'filename' => $filename,
+ );
+ $fs->create_file_from_string($filerecord, base64_decode($filedata));
+ $qo->questiontext .= ' <img src="@@PLUGINFILE@@/' . $filename . '" />';
}
// restore files in generalfeedback
- $qo->generalfeedback = $this->getpath($question,
- array('#', 'generalfeedback', 0, '#', 'text', 0, '#'), $qo->generalfeedback, true);
- $qo->generalfeedbackfiles = array();
- $qo->generalfeedbackformat = $this->trans_format($this->getpath($question,
- array('#', 'generalfeedback', 0, '@', 'format'), $this->get_format($qo->questiontextformat)));
- $qo->generalfeedbackfiles = $this->import_files($this->getpath($question,
- array('#', 'generalfeedback', 0, '#', 'file'), array(), false));
+ $generalfeedback = $this->import_text_with_files($question,
+ array('#', 'generalfeedback', 0), $qo->generalfeedback, $this->get_format($qo->questiontextformat));
+ $qo->generalfeedback = $generalfeedback['text'];
+ $qo->generalfeedbackformat = $generalfeedback['format'];
+ if (!empty($generalfeedback['itemid'])) {
+ $qo->generalfeedbackitemid = $generalfeedback['itemid'];
+ }
$qo->defaultmark = $this->getpath($question,
array('#', 'defaultgrade', 0, '#'), $qo->defaultmark);
public function import_answer($answer, $withanswerfiles = false, $defaultformat = 'html') {
$ans = new stdClass();
- $ans->answer = array();
- $ans->answer['text'] = $this->getpath($answer, array('#', 'text', 0, '#'), '', true);
- $ans->answer['format'] = $this->trans_format($this->getpath($answer,
- array('@', 'format'), $defaultformat));
if ($withanswerfiles) {
- $ans->answer['files'] = $this->import_files($this->getpath($answer,
- array('#', 'file'), array()));
+ $ans->answer = $this->import_text_with_files($answer, array(), '', $defaultformat);
} else {
+ $ans->answer = array();
+ $ans->answer['text'] = $this->getpath($answer, array('#', 'text', 0, '#'), '', true);
$ans->answer['format'] = FORMAT_PLAIN;
}
- $ans->feedback = array();
- $ans->feedback['text'] = $this->getpath($answer,
- array('#', 'feedback', 0, '#', 'text', 0, '#'), '', true);
- $ans->feedback['format'] = $this->trans_format($this->getpath($answer,
- array('#', 'feedback', 0, '@', 'format'), $defaultformat));
- $ans->feedback['files'] = $this->import_files($this->getpath($answer,
- array('#', 'feedback', 0, '#', 'file'), array()));
+ $ans->feedback = $this->import_text_with_files($answer, array('#', 'feedback', 0), '', $defaultformat);
$ans->fraction = $this->getpath($answer, array('@', 'fraction'), 0) / 100;
public function import_combined_feedback($qo, $questionxml, $withshownumpartscorrect = false) {
$fields = array('correctfeedback', 'partiallycorrectfeedback', 'incorrectfeedback');
foreach ($fields as $field) {
- $text = array();
- $text['text'] = $this->getpath($questionxml,
- array('#', $field, 0, '#', 'text', 0, '#'), '', true);
- $text['format'] = $this->trans_format($this->getpath($questionxml,
- array('#', $field, 0, '@', 'format'), $this->get_format($qo->questiontextformat)));
- $text['files'] = $this->import_files($this->getpath($questionxml,
- array('#', $field, 0, '#', 'file'), array(), false));
-
- $qo->$field = $text;
+ $qo->$field = $this->import_text_with_files($questionxml,
+ array('#', $field, 0), '', $this->get_format($qo->questiontextformat));
}
if ($withshownumpartscorrect) {
* @return object hint for storing in the database.
*/
public function import_hint($hintxml, $defaultformat) {
+ $hint = new stdClass();
if (array_key_exists('hintcontent', $hintxml['#'])) {
// Backwards compatibility:
- $hint = new stdClass();
- $hint->hint = array('format' => FORMAT_HTML, 'files' => array());
- $hint->hint['text'] = $this->getpath($hintxml,
- array('#', 'hintcontent', 0, '#', 'text', 0, '#'), '', true);
- $hint->hint['format'] = $this->trans_format($defaultformat);
- $hint->hint['files'] = array();
+ $hint->hint = $this->import_text_with_files($hintxml,
+ array('#', 'hintcontent', 0), '', $defaultformat);
+
$hint->shownumcorrect = $this->getpath($hintxml,
array('#', 'statenumberofcorrectresponses', 0, '#'), 0);
$hint->clearwrong = $this->getpath($hintxml,
return $hint;
}
-
- $hint = new stdClass();
- $hint->hint['text'] = $this->getpath($hintxml,
- array('#', 'text', 0, '#'), '', true);
- $hint->hint['format'] = $this->trans_format($this->getpath($hintxml,
- array('@', 'format'), $defaultformat));
- $hint->hint['files'] = $this->import_files($this->getpath($hintxml,
- array('#', 'file'), array(), false));
+ $hint->hint = $this->import_text_with_files($hintxml, array(), '', $defaultformat);
$hint->shownumcorrect = array_key_exists('shownumcorrect', $hintxml['#']);
$hint->clearwrong = array_key_exists('clearwrong', $hintxml['#']);
$hint->options = $this->getpath($hintxml, array('#', 'options', 0, '#'), '', true);
$qo->name = $this->clean_question_name($this->import_text($question['#']['name'][0]['#']['text']));
$qo->questiontextformat = $questiontext['format'];
$qo->questiontext = $qo->questiontext['text'];
- $qo->questiontextfiles = $this->import_files($this->getpath($question,
+ $itemid = $this->import_files($this->getpath($question,
array('#', 'questiontext', 0, '#', 'file'), array(), false));
-
+ if (!empty($itemid)) {
+ $qo->questiontextitemid = $itemid;
+ }
// Backwards compatibility, deal with the old image tag.
$filedata = $this->getpath($question, array('#', 'image_base64', '0', '#'), null, false);
$filename = $this->getpath($question, array('#', 'image', '0', '#'), null, false);
}
// restore files in generalfeedback
- $qo->generalfeedback = $this->getpath($question,
- array('#', 'generalfeedback', 0, '#', 'text', 0, '#'), $qo->generalfeedback, true);
- $qo->generalfeedbackformat = $this->trans_format($this->getpath($question,
- array('#', 'generalfeedback', 0, '@', 'format'), $this->get_format($qo->questiontextformat)));
- $qo->generalfeedbackfiles = $this->import_files($this->getpath($question,
- array('#', 'generalfeedback', 0, '#', 'file'), array(), false));
+ $generalfeedback = $this->import_text_with_files($question,
+ array('#', 'generalfeedback', 0), $qo->generalfeedback, $this->get_format($qo->questiontextformat));
+ $qo->generalfeedback = $generalfeedback['text'];
+ $qo->generalfeedbackformat = $generalfeedback['format'];
+ if (!empty($generalfeedback['itemid'])) {
+ $qo->generalfeedbackitemid = $generalfeedback['itemid'];
+ }
$qo->penalty = $this->getpath($question,
array('#', 'penalty', 0, '#'), $this->defaultquestion()->penalty);
foreach ($question['#']['answer'] as $answer) {
$answertext = $this->getpath($answer,
array('#', 'text', 0, '#'), '', true);
- $feedback = $this->getpath($answer,
- array('#', 'feedback', 0, '#', 'text', 0, '#'), '', true);
- $feedbackformat = $this->getpath($answer,
- array('#', 'feedback', 0, '@', 'format'), $this->get_format($qo->questiontextformat));
- $feedbackfiles = $this->getpath($answer,
- array('#', 'feedback', 0, '#', 'file'), array());
- $files = array();
- foreach ($feedbackfiles as $file) {
- $data = new stdClass();
- $data->content = $file['#'];
- $data->encoding = $file['@']['encoding'];
- $data->name = $file['@']['name'];
- $files[] = $data;
- }
+ $feedback = $this->import_text_with_files($answer,
+ array('#', 'feedback', 0), '', $this->get_format($qo->questiontextformat));
+
if ($answertext != 'true' && $answertext != 'false') {
// Old style file, assume order is true/false.
$warning = true;
if ($answertext == 'true') {
$qo->answer = ($answer['@']['fraction'] == 100);
$qo->correctanswer = $qo->answer;
- $qo->feedbacktrue = array();
- $qo->feedbacktrue['text'] = $feedback;
- $qo->feedbacktrue['format'] = $this->trans_format($feedbackformat);
- $qo->feedbacktrue['files'] = $files;
+ $qo->feedbacktrue = $feedback;
} else {
$qo->answer = ($answer['@']['fraction'] != 100);
$qo->correctanswer = $qo->answer;
- $qo->feedbackfalse = array();
- $qo->feedbackfalse['text'] = $feedback;
- $qo->feedbackfalse['format'] = $this->trans_format($feedbackformat);
- $qo->feedbackfalse['files'] = $files;
+ $qo->feedbackfalse = $feedback;
}
$first = false;
}
$qo->instructions['format'] = FORMAT_HTML;
$instructions = $this->getpath($question, array('#', 'instructions'), array());
if (!empty($instructions)) {
- $qo->instructions = array();
- $qo->instructions['text'] = $this->getpath($instructions,
- array('0', '#', 'text', '0', '#'), '', true);
- $qo->instructions['format'] = $this->trans_format($this->getpath($instructions,
- array('0', '@', 'format'), $this->get_format($qo->questiontextformat)));
- $qo->instructions['files'] = $this->import_files($this->getpath(
- $instructions, array('0', '#', 'file'), array()));
+ $qo->instructions = $this->import_text_with_files($instructions,
+ array('0'), '', $this->get_format($qo->questiontextformat));
}
if (is_null($qo->showunits)) {
$qo->subquestions = array();
$qo->subanswers = array();
foreach ($question['#']['subquestion'] as $subqxml) {
- $subquestion = array();
- $subquestion['text'] = $this->getpath($subqxml, array('#', 'text', 0, '#'), '', true);
- $subquestion['format'] = $this->trans_format($this->getpath($subqxml,
- array('@', 'format'), $this->get_format($qo->questiontextformat)));
- $subquestion['files'] = $this->import_files($this->getpath($subqxml,
- array('#', 'file'), array()));
-
- $qo->subquestions[] = $subquestion;
+ $qo->subquestions[] = $this->import_text_with_files($subqxml,
+ array(), '', $this->get_format($qo->questiontextformat));
+
$answers = $this->getpath($subqxml, array('#', 'answer'), array());
$qo->subanswers[] = $this->getpath($subqxml,
array('#', 'answer', 0, '#', 'text', 0, '#'), '', true);
array('#', 'responsefieldlines', 0, '#'), 15);
$qo->attachments = $this->getpath($question,
array('#', 'attachments', 0, '#'), 0);
- $qo->graderinfo['text'] = $this->getpath($question,
- array('#', 'graderinfo', 0, '#', 'text', 0, '#'), '', true);
- $qo->graderinfo['format'] = $this->trans_format($this->getpath($question,
- array('#', 'graderinfo', 0, '@', 'format'), $this->get_format($qo->questiontextformat)));
- $qo->graderinfo['files'] = $this->import_files($this->getpath($question,
- array('#', 'graderinfo', '0', '#', 'file'), array()));
+ $qo->graderinfo = $this->import_text_with_files($question,
+ array('#', 'graderinfo', 0), '', $this->get_format($qo->questiontextformat));
return $qo;
}
$qo->instructions = $this->getpath($question,
array('#', 'instructions', 0, '#', 'text', 0, '#'), '', true);
if (!empty($instructions)) {
- $qo->instructions = array();
- $qo->instructions['text'] = $this->getpath($instructions,
- array('0', '#', 'text', '0', '#'), '', true);
- $qo->instructions['format'] = $this->trans_format($this->getpath($instructions,
- array('0', '@', 'format'), $this->get_format($qo->questiontextformat)));
- $qo->instructions['files'] = $this->import_files($this->getpath($instructions,
- array('0', '#', 'file'), array()));
+ $qo->instructions = $this->import_text_with_files($instructions,
+ array('0'), '', $this->get_format($qo->questiontextformat));
}
// get answers array
}
$instructions = $this->getpath($question, array('#', 'instructions'), array());
if (!empty($instructions)) {
- $qo->instructions = array();
- $qo->instructions['text'] = $this->getpath($instructions,
- array('0', '#', 'text', '0', '#'), '', true);
- $qo->instructions['format'] = $this->trans_format($this->getpath($instructions,
- array('0', '@', 'format'), $this->get_format($qo->questiontextformat)));
- $qo->instructions['files'] = $this->import_files($this->getpath($instructions,
- array('0', '#', 'file'), array()));
+ $qo->instructions = $this->import_text_with_files($instructions,
+ array('0'), '', $this->get_format($qo->questiontextformat));
}
if (is_null($qo->unitpenalty)) {
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<quiz>
+<!-- question: 0 -->
+ <question type="category">
+ <category>
+ <text>$course$/Default for testhead/Multichoice</text>
+
+ </category>
+ </question>
+
+<!-- question: 2295 -->
+ <question type="multichoice">
+ <name>
+ <text>Greeting</text>
+ </name>
+ <questiontext format="html">
+ <text><![CDATA[<p><a href="@@PLUGINFILE@@/bonjour.mp3">Listen to this greeting:</a><br /><br />What language is being spoken?</p>]]></text>
+<file name="bonjour.mp3" encoding="base64">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Fl7pz/jb6rABwGCAGDAGhSDiEYjCYFBTQjFYJHgumNR////////////+v69////////////7sToIDJhMBjQYMHDsFBgwCBDdpEfY20TiErmN0iYRIBteqiV1NLe81CJTXUoNyiIw8VAeLDFhQMML41sHTEYbBrIMVlcw8LjTAuaCxIzGXVfEoFMhG54CAIqFNyV/Xd56yYPTCzG6qYU61nheF5IKUtZ02WWOUqtKpuii81BRfNnAXD7ZoKY7khaoKOBNTRmrv05UBikgYAyIeNbxfsGhNUZAOB4XP4XDSeoX0MDAorApAOiIjOiWkfdiEMhcKNKEYuMJACDkt4qCQOBgwCAMZeCACCCOtosA4LgQlAAkDa6E0RCcvABA//LCwD145VuTxnQBnOAA8LFlX6lU8yoAghQIIF76FthgPtIBwAM3j9nrOc24l1nCFQE/YsAe/70ts5RICy7o6Dy4QiDIICRgYNhUXJfCME3/+Z3MgwAMVCoFBAQS4MTCMVFAYLyYYmFwDz//8Eqh0DLtlsoQ5AENltwENQMAiIA2f////////////JgBz////////////4dTEFNRTMuOTWqqqgAAHHsAAYVAUYBiiAh5BIHiRECotGiaPGD4vG5w/mDgamtpLmAwNmW/8GUxUGu6Dm2AuGVmHhAGGFaID4dmEYqmH4dnMYKBB1mAZgmvIQmFIyGWJxioCgAETJwvAUCq0jGkdS5AhAIHDSDAUMXgfRVCA1CojGKIKjgDFrhACQKIpTERhHOCEF0uSwAyARziqBcgWkUBk9xADLEyEBV9LRVqHgLL7GNwCr3HgJlooCpeEwDEgwaAWyztsinClBgaHimRZgBA2wwEBQNBgDgCMNgbkhfxsBbBp7WjBYGhAD6xnmBQBGAoE5MiMGgVbGFwNhquhiWpAAYqAigHmWQ9GP/ywsBMeP9qc8pgcZ3oAAgHBQANCAGCsACyw4DKlg8CQWDUKBGYShMYLE+YKBChjGB0DgICBEJJgWBTzRkIA0CAuBRKMUQCMNwssy53kIgEB6OMzFMv//8LARFy7wJBIgA4wjAYHCwWhMHAjKAixwwsdjhKBCA0FAyWAJKoFBcEDAsLDCMCh4LwwGtz0v68MDI7OwkkzVDqPAKNAIVAMLvMedTn////////////3+f////////////OcgAJmQABIvDDVFwE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T3y3///MCg7MVhnFiUMOhpMSAXMDAjMHg5yjL//ywsCcOINahC4EAZ3oABSqerSr////zAgDDC8RjBIQzFoWzGAiQCBhhSIRiiOxiAQte5yVQTMw7Eq3/////5jsGYyAxgABBjyXhmCQxhmERh0QJkMKZiUOJKTxluBRk2jxpKZFNTTU+wF0YQ1qozpGVpMC////////+YJjuAhCMTBlMKAyMIAdAIJBUGzCsPBEJpiwA5igRJi8DKPRgEAZgGDgcFUMujIHafaRv7KYq0p9pFqt3H//////////1Amxoqx1iLGoquZlbDnxdxyXqfNrUTkDSYTax5//rXcd81/7/9f///////////////1r8pyps0xBTUUzLjk1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/8sLAaDysAAADSAGAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVTEFNRTMuOTVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//LCwByZ/wAAA0gBgAAAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUxBTUUzLjk1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==</file> </questiontext>
+ <generalfeedback format="html">
+ <text></text>
+ </generalfeedback>
+ <defaultgrade>1.0000000</defaultgrade>
+ <penalty>0.1000000</penalty>
+ <hidden>0</hidden>
+ <single>true</single>
+ <shuffleanswers>true</shuffleanswers>
+ <answernumbering>abc</answernumbering>
+ <correctfeedback format="html">
+ <text></text>
+ </correctfeedback>
+ <partiallycorrectfeedback format="html">
+ <text></text>
+ </partiallycorrectfeedback>
+ <incorrectfeedback format="html">
+ <text></text>
+ </incorrectfeedback>
+ <answer fraction="0" format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/flag-uk.jpg" alt="British Flag" width="30" height="20" /> English</p>]]></text>
+<file name="flag-uk.jpg" encoding="base64">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</file> <feedback format="html">
+ <text><![CDATA[<p>Sorry, listen again.</p>]]></text>
+ </feedback>
+ </answer>
+ <answer fraction="100" format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/flag-france.jpg" alt="French flag" width="30" height="20" /> French</p>]]></text>
+<file name="flag-france.jpg" encoding="base64">/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAFAAeAwERAAIRAQMRAf/EALYAAAMBAQAAAAAAAAAAAAAAAAgJCgcLAQADAQEAAAAAAAAAAAAAAAAHCAkFChAAAAEHCQEIEwEAAAAAAAAAAgEREgMTBAUAFBUGFgcXCAkYMUFhMkIjdSchUYEisjOktDZmN0dnxzhIiLgKOREAAAEIAwUQEAcAAAAAAAAAAQARAhIDEwQFFAYHQaEzFRYhMVFxscHRIkKCI3M0hDUXgZFyorLCQ4OTo7O0RYU3CbXFJjZHCBj/2gAMAwEAAhEDEQA/ABDzlatOaG7e+OM1XgMTdiOEPeX53ViG9vQBjCoeWYCiCAKJCkCSVB6p2YVcmEpQiWyIrpAFwNAl3m9aZlDxYskB2oCJWtaIl9Vb8w+mBljvir4tAvrXXDGilVoBjWBFZ/MJexVdxMNZ35UYbBFJOzvkkolsMohZFaNMZVBAaGZUdXfQrFMb6QkYamxjWPq3DRbfCpvD9hqmiF4CFzXNzN3i5ctl2wDwrUWxxspZNasVpWewjmBmZCnRpxdu9uQTnsU0hnTvdLXldkq1fbbsdqpazlnlOiKWL8UOjAA4fGa+fxKBTaPWo1mPer0YbGx1lWhUw2DrmMJA9LyOKxY8O706DXricYa0gV5SkLuEMThlioRjdJmnECO2RADBpiAFQ6sFg1nUqrTIbNoOCZhATSKiEm7YUQFqkDGCiG6CAXAQBNkiIhdHNEcwABJ+oX9RFaekIp56WViKi9BM+5DULkCn/SCWmJdED+cv/GjJz+Qn7UX4SRG3v6szbmvucOR6s/8A2jCed9s0IL/6S/sx/Ir5FSXesvkd/wCKVzftFfyD8i/OSlJL6ZE6JJ4YpYbLkbXSDwgKjlcvrjVDjY38MjSW5mgs5jxeZaS3dLWqik58cY84FxJ5zrE/E5KJjSpel1mUdjQ1aG7BR2ZU2ofRLjODJh4m+O+WFZbPPsFUzpW7cOwXcRgHijhN1n2UmzBh7Zbw6dQP6yzw/CeSm2k41y1jcdnxnwK58/AMle8VIuVZomI2FB5Lt1fSJnvnLA9WDa06hNoHE73pWSnM3+HNPIeRH7khdNqNwdINujXj6xUV/o/1tfqfqtX+HUpXn7k/rSTu6T6dRZpb6l6Odpu0ZtGU+d02CPNpM0jpck5t6WajQXSRjKZh+2GuTeTj/R2WkppzzKR42oxzn5K2eGuYJ4e6X//Z</file> <feedback format="html">
+ <text><![CDATA[<p>Yes, well done!</p>]]></text>
+ </feedback>
+ </answer>
+ <answer fraction="0" format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/flag-german.jpg" alt="German flag" width="30" height="20" /> German</p>]]></text>
+<file name="flag-german.jpg" encoding="base64">/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAFAAeAwERAAIRAQMRAf/EAKYAAQACAwAAAAAAAAAAAAAAAAcACQEICgEAAQMFAQAAAAAAAAAAAAAAAAUGCQECAwQHCBAAAAMFBQMICwAAAAAAAAAAAQIFEQMEBggAMRIUByETFWEyldUWF1cYQVFxgZGhsSIjNSgRAAACBQYGDQ0AAAAAAAAAAAEEABECAwUhMRITBgdhk9MVFghBkaEiMtIjoxTUVVYXUYHBUmKiwnM1lSYnGP/aAAwDAQACEQMRAD8ApA1tqzq/RdQlxOSpRn4YGHinjtxuZTmM7vAUwlBhiQLLg9dk9qOQJkVNnSgDhfOw+JHm7uwvOfs1jizkfbdjMLMPNiA+cHIghOFZlahQYWVNRwALgCUpoAPgEFawY3Z0RWJwkI/OdcZMnhXer3atD9uOZFMDWZWoN8p6jD7ZSmgfrBWAjdnQmOksc64yVC629YJrNWi+3HMihAtVN1dKmqMnTVGImoIK0tPFR4kp3ZqYimO8UENUSYl4LgYPePTFgo94xgbL7ZAjMDFgWwNlKsJxrXatukpNdq7m8tl+yVagEdA01wWBIm6YyLFTNUsZAEZAmTqM1SpOqUjpyVomD0smN9DvIh4Lt4SPQylMAmFjAMslH5Wixjms9q/k4i8LmrSkWHzIygLsysNpwKT+2Rviu7LwNy6fRlyy8BkFhy3EQ78oVTvhPMvSKD13ZI/qjV370EMUZ6ujm8aLtu23HPZNJ5QqnfCeZekUHrux/VGrv3oIYoz1dDxou27bcc9k01zWqXah3Wu8mpDzTSYCqcTxTLwox6KLx5u0NVenwmBXF2GF27MO0wXWepXWRuLe2SMxR3aIkMPd0KTdWYUC3jABJULlEQCQNlOUxC9mwLd5BA6zF3IlmKxbXKqBbp4HqLnEAS+zXvzHdvY3gOS4EweG5HHzMX5M3j+7OYuf6GMZsZaHKC6C0X2ltZpHWjXUpl7FD2FcHZnXKtPBhnO62c3K6FR3qvTh8qCf9R8tlv8AUaav5Jh3Un9R8tj9RofkmHdQXU++PvXlvON7bNj+EXN/WR+Z92S3tn0U0H0ONVH0DeVmMYo+9RRKeZ2zk7pr6ZLR2hXuLT//2Q==</file> <feedback format="html">
+ <text><![CDATA[<p>Sorry, listen again.</p>]]></text>
+ </feedback>
+ </answer>
+ <answer fraction="0" format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/flag-denmark.jpg" alt="Denmark flag" width="30" height="20" /> Danish</p>]]></text>
+<file name="flag-denmark.jpg" encoding="base64">/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAFAAeAwERAAIRAQMRAf/EALoAAAMBAQAAAAAAAAAAAAAAAAYJCgQHAQACAgMBAAAAAAAAAAAAAAAHCQYIAwQFChAAAAAKBwIIDwEAAAAAAAAAARECEgMTBBQVFwAFBhYIGAkxByFBM2QnR2cZYSJC0iNDhJSkVShoqOgKGhEAAAMEBQQICxkAAAAAAAAAARECEgMTFAAEBRUGMRYHFyFBIqJjCBgJUWFxcoJDg2RFZSaBkaGx0TJCUmKSsjNTcyREpOQl5aYnZygZ/9oADAMBAAIRAxEAPwAlxSak2IOwu9CtLP1O3oAMbEna0KMJTQ0ElFEok5hBwCSTQBAClHsTaRLeqNpKq7lQMJEQyjT1R6DuJpolxRghxa1oulTDxCBHcpHKkxo6HX9xWbzMMeUyXTSjZ77z3jCxKlRH3ak1DxKwBONj6fbsHQwadcUWlhu6rvEo0y12EuXwhot/moNBGCtNmf2eCBXdlyQSABKYveJl+YRSc3vWMTHzFn96afNpX7WhiP2weeNHB8hLQt8iv3qfVoD1tqfYnWy3FlK2vIWgQVQzVwVDELU0EsrclamJMxgSNgRHFgZyGg4gkQgFgGEfALO6x3iCsu3tpLeiCqsgGUgIkIrWlAirqAoSDo05VocU3Q9YddqGCavZ7tbu26ysHr9SQF47RV6u+rKUugyA08cpbUZinYAgM6L99n9Gcnbb1hY3JzeJwTNCGJZhIQtUJVZznI+tDD9oloRUNls8YG6K6qp3REZEQOaZydKWV6dFdaNOZ71iYZdYi1iScVKRh3DFJoD9ffTsy60KMH1RNUTu2ZG9Bs55zzM6zJdXbl1L7s+t3GIxfvmru6+tW+jnukvSXq7kvoU5ORu3QmIULgnjTUT3JM7Z7FSuI/xH+WXnP5T5t5t3d4OvCYvCf7/qUGDJcLEi+wY3amf9RP2N/kx+v1BZylfEv2z7rS+/+IH8n/pz8+pyi1H9Kcc3n7srXZLnW5RdpGuH5jF8Sitm63qBW9yJQuaiLrRqkpys0QDjid5xxiY9Tf1u5yggkSmzNpaU5ZbYJo8g5CpFbW5mW68R2XYGshu8nj1ETN9mHCq75+bN9i21CYJpJNNGJEM2WLycM+Lev0UFH6ydXh3Vu7wFW7eSpNFs49vDQS1rNCdfXzMTkQTaLe7RdSjEMP8AKLzXszVrc2bkmhmC0Zl20903121k2KOC16c830p5hnPrzuhC1PY9H15/sRovDQ66cM3fwu/2/rMNnuDR72in+au1zeXeqOX8CzcU/G0Bku7H5lJ4+lLnXwtAJ+3XC+hRuf8AczvDfUwFzGiSBc/PbqmdDXMzlES5YPxuSGIXHTpVbMOQrMKJLspb6JREEXZFSE25ys87rFnZO9oz+XI2WpSsRGtv4psi2yp//9k=</file> <feedback format="html">
+ <text><![CDATA[<p>Sorry, listen again.</p>]]></text>
+ </feedback>
+ </answer>
+ </question>
+
+</quiz>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<quiz>
+<!-- question: 0 -->
+ <question type="category">
+ <category>
+ <text>$course$/Default for testhead/TrueFalse</text>
+
+ </category>
+ </question>
+
+<!-- question: 2284 -->
+ <question type="truefalse">
+ <name>
+ <text>Moodle acronym (False)</text>
+ </name>
+ <questiontext format="html">
+ <text><![CDATA[<p>Moodle <img src="@@PLUGINFILE@@/logo.jpg" alt="Moodle logo" width="48" height="48" /> is an acronym for <span style="font-style: italic;">Modular Object-Oriented Dynamic Learning Education</span>.</p>]]></text>
+<file name="logo.jpg" encoding="base64">/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBggGBQkIBwgKCQkKDRYODQwMDRoTFBAWHxwhICocHh4jJzIqIyUvLR4eNzssLy41ODg0JSo4QTAqPDwsNDUBCQoKDQsNGQ4OGTUkHiQ1NTU1NTU1NTU1NTUuNTU1LTU1NTU1NTQsMjU1NTU1NSk0KSw0MjQ2Miw1NDQyNDQ0Nf/AABEIADAAMAMBIgACEQEDEQH/xAAbAAEAAgIDAAAAAAAAAAAAAAAHAAYDBQEECP/EADUQAAEDAwEEBgcJAAAAAAAAAAECAwQABREGEiExURNBYXORsQcUFRZDYqEXIyQ2QnGywfD/xAAYAQEAAwEAAAAAAAAAAAAAAAAAAQMEAv/EACIRAAEEAgIBBQAAAAAAAAAAAAMAAQIEETESIeEFUYGhsf/aAAwDAQACEQMRAD8AcalSsT8lmMkKfdbaSeBWoJH1oiy1K0z+sbDGTly7Q+WEuhR8BWW16lt16dUm3vF9KeLiUKCM8tojGaItpUqVKIqRq7Xr9sBj2i3yZEg/FUyoIT2jPH/caHbtepdzubqr3ch06fhLXgp7N/DwFOMwx/f9MZxoEuQUuBRJI3OKGMcOsdtHOsNMRGLxNu7TilqcfUVNuIBAwcYBGKpKcYcc3xlWjFMueDaVEj3Bj2mwOi9ZZ6QBaUfqGeA516GsKbTAtTD7LiSgpGyAN6ezZHDFG1j9GsyVLXd0pSwlP3jTSgOXnXfuM+VDiNR4qg2uSpKARu3msNu7MBIwjHPL9WqtViaDzeWkie9ltSrZcW432qbOK2caUzLZDsdxLrauCknIo6XpCdbrYJ65q3hu20L5E43eNcaZubtq1emEFH1eUkko6goddViuHhYYB2bvWF3OsKQXKF9e6sdzVI+0SGCn8N6go7Xz9Kn+qquskj2fK71f8qTHojTzyHlIBcQMJV1gccfQUa6ptl7lPSYzVv2mluKUle2N4Jzzp6oEheHBs4dcUiRg8uT46V8s35fa7s+VHN8QBNtffN+YpItTTjdjbQUkL6PGDzo6m2q9yrnEDtvKG47ySVBQO4H96i+EhDilBum39KapIxHNnfaQruM6acHyJ8xVAaSB6QIGOSqQbsy+7px1uO30j2wnZRnGSCKoVstt3e1dFly4JZbbyCQoGoshJK8ObN02O/l0CSLVpRd+38L/2Q==</file> </questiontext>
+ <generalfeedback format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/infos.jpg" alt="Informations" width="34" height="49" />For further information, see the <a title="Moodle Docs - About Moodle" href="http://docs.moodle.org/en/About_Moodle">documentation about Moodle</a>.</p>]]></text>
+<file name="infos.jpg" encoding="base64">/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBggGBQkIBwgKCQkKGRYaDQwMDRodFBAhKhwlIB8lHh4jIjIoIyQvJSQeKy8sLzMtODgsISo9QTs2QTIuMywBCQoKDQsNGQ4OGTUkHiQ1NTU1NTU1NTU1NTU1NTU1Ly82NTU1NDUtLTQ0NTU1MCwsLCw0KTU0LzU2NjMpKTQ2Kf/AABEIADEAIgMBIgACEQEDEQH/xAAaAAEAAwEBAQAAAAAAAAAAAAAABQYHBAID/8QALhAAAQMCBAMHBAMAAAAAAAAAAgABAwQFBhEhMUFRgRITIjJxsfAHYWKRFBVC/8QAGQEAAgMBAAAAAAAAAAAAAAAAAAEDBAUC/8QAIREAAgEDBAMBAAAAAAAAAAAAAAECAxExBBITISIjQQX/2gAMAwEAAhEDEQA/ANxXk5AiHtSGINzJ8lz3GvitlCdTOTCAcVl16xZU3SoMhMoof8iz65fdWaGmlXfWCOpUUMmrDVwGbCM8RE+zMbZuvqsdvzR2WSme3Xf+W8o5n3ZeX11dsn5PyVowJjUrof8AX1xN3w+Qufzbq3TuppHCHJF3RzGqnLa8l6REVMmKV9UpzhsMLA7sJF4v2yySe5OD9mPV+LvwW84osg3+xzUj6G7eF23+cfVmWAXW01Vnrnp62JwJn0LLwn6fNFt/mzi4OH0p6iLvuJ3HZi01EUEQQCTFm0YMLPtyUdg+eePFNI8RF2vFx/F392ZSGN7va7sVva0yHI0Ik0jlG46u7ZZZ77Kx/TPBdQFc1zr4ii7HkAm1bjryd9NOWee7KS/Fo/Zl3FbdV8TV0RFgF0LiuFmoboDjWU4SZ75t78H6rtRCdgISiwdaKCbvYKUBPg4gIu3UWZ1MhGEQMEYsAtswtoy9Im5OXbYrWCIiQwiIgAiIgAiIgD//2Q==</file> </generalfeedback>
+ <defaultgrade>1.0000000</defaultgrade>
+ <penalty>1.0000000</penalty>
+ <hidden>0</hidden>
+ <answer fraction="0" format="moodle_auto_format">
+ <text>true</text>
+ <feedback format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/thumbdown.jpg" alt="Thumb down" width="24" height="24" /> Your answer is incorrect.</p>]]></text>
+<file name="thumbdown.jpg" encoding="base64">/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5Ojf/2wBDAQoKCg0MDRoPDxo3JR8lNzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzf/wAARCAAYABgDASIAAhEBAxEB/8QAGgABAAIDAQAAAAAAAAAAAAAAAAQFAQMGB//EACcQAAIBAwMDBAMBAAAAAAAAAAECAwAEBQYRIRITMTJBUXEiUmKh/8QAFwEAAwEAAAAAAAAAAAAAAAAAAgQFA//EACIRAAIBAwQCAwAAAAAAAAAAAAECAwAEERIhMVEFQROh8f/aAAwDAQACEQMRAD8A9AubiTK5m5t5JpEihZlVUiaTbpO3pX5PvWy4wLR2Ml1Fc9QRS/TJAYzsPPnn2+KqsdcompsksjxoO7MAZLpoBv3P2Uf5XTX17BFpm7l7iSKI2jJhnM4DNwPyPJ9QPPipiKkgZn537q9N8kLIkfBx17+6qrd7vC5i2tZpFKzMoKoSVIY7b/e9KrchmoMtqXGS2qyKglhTZwAd+5v7fdKYtGB1BTsDtSfkY2XQzjDEb1jVGlb45Oe6sYmmincuQnJUnzx91GgsdQQ4efFrj5jBO4diYh1Ajbwer+RSlC1jGWLAkZ6/KJPLzhFQgHGOR1x7qTpfSt8MnBdX0TQxQOHAfgsR44+6UpW8ECwrpWlLq7kun1yV/9k=</file> </feedback>
+ </answer>
+ <answer fraction="100" format="moodle_auto_format">
+ <text>false</text>
+ <feedback format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/thumbup.jpg" alt="Thumb up" width="24" height="24" /> Your answer is correct.</p>]]></text>
+<file name="thumbup.jpg" encoding="base64">/9j/4AAQSkZJRgABAQEAYABgAAD/4RDARXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAExAAIAAAAuAAAIVgEyAAIAAAAUAAAIhIdpAAQAAAABAAAImOocAAcAAAgMAAAASgAAAAAc6gAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE1pY3Jvc29mdCBXaW5kb3dzIFBob3RvIFZpZXdlciA2LjEuNzYwMC4xNjM4NQAyMDEzOjAxOjEwIDE4OjI1OjUzAAAB6hwABwAACAwAAAiqAAAAABzqAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4TG4aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49J++7vycgaWQ9J1c1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCc/Pg0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyI+PHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj48cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0idXVpZDpmYWY1YmRkNS1iYTNkLTExZGEtYWQzMS1kMzNkNzUxODJmMWIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+PHhtcDpDcmVhdG9yVG9vbD5NaWNyb3NvZnQgV2luZG93cyBQaG90byBWaWV3ZXIgNi4xLjc2MDAuMTYzODU8L3htcDpDcmVhdG9yVG9vbD48L3JkZjpEZXNjcmlwdGlvbj48L3JkZjpSREY+PC94OnhtcG1ldGE+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSd3Jz8+/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgAGAAYAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A99+OX7RviD/hMdS0fQrt9O0/TpzAzwLh5WUfP83+9WHqPjz4o6Z4D0zxZJ4n1FtPv5ngiCXKeYrLu+8vlf8ATJ61fB3wssfiL8W/FVjfyTRQ/a76dXhKht32nb/ED617p4Y8IadbfA3RbOSCKaFbZLtFvtPfUQkkh3N+6T5m/wBYy/L90e1fndHDYzHValWVVqOtrO2x+w4jG5RleGw9CGHjOS5XO63TXQ8T+CP7RviE+MtN0XxBdvqWn6lOsKNcDc8bsPl+f/eoqv4x0CGy+Lfhia2SCKNbuycrbaVLp6l/tP8Azykb9aK7MFjMRhoSo1ZtuL3/AKZ4ue4HA4ypSxNCkoKcU2vmzvdY0zV/hR4/1TUrOCNo7ySSRJpi5jZZG3bf97dV3Svi5LZ+GbXRbvShPFBGsHm2t+9qwVRhMbfmH3f71FFefi8TVwdepSouy1PXwOEoZlg6dfExvKy8tvQztH8PXHxB8d6TfQ2NxaWVpIksks13LcFfLfcB5sn95v4P9miiivpsqw8MRQdSpq2/L/I+SzitOjinRp6RirL+mf/Z</file> </feedback>
+ </answer>
+ </question>
+
+<!-- question: 2283 -->
+ <question type="truefalse">
+ <name>
+ <text>Moodle acronym (True)</text>
+ </name>
+ <questiontext format="html">
+ <text><![CDATA[<p>Moodle <img src="@@PLUGINFILE@@/logo.jpg" alt="Moodle logo" width="48" height="48" /> is an acronym for <span style="font-style: italic;">Modular Object-Oriented Dynamic Learning Environment</span>.</p>]]></text>
+<file name="logo.jpg" encoding="base64">/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBggGBQkIBwgKCQkKDRYODQwMDRoTFBAWHxwhICocHh4jJzIqIyUvLR4eNzssLy41ODg0JSo4QTAqPDwsNDUBCQoKDQsNGQ4OGTUkHiQ1NTU1NTU1NTU1NTUuNTU1LTU1NTU1NTQsMjU1NTU1NSk0KSw0MjQ2Miw1NDQyNDQ0Nf/AABEIADAAMAMBIgACEQEDEQH/xAAbAAEAAgIDAAAAAAAAAAAAAAAHAAYDBQEECP/EADUQAAEDAwEEBgcJAAAAAAAAAAECAwQABREGEiExURNBYXORsQcUFRZDYqEXIyQ2QnGywfD/xAAYAQEAAwEAAAAAAAAAAAAAAAAAAQMEAv/EACIRAAEEAgIBBQAAAAAAAAAAAAMAAQIEETESIeEFUYGhsf/aAAwDAQACEQMRAD8AcalSsT8lmMkKfdbaSeBWoJH1oiy1K0z+sbDGTly7Q+WEuhR8BWW16lt16dUm3vF9KeLiUKCM8tojGaItpUqVKIqRq7Xr9sBj2i3yZEg/FUyoIT2jPH/caHbtepdzubqr3ch06fhLXgp7N/DwFOMwx/f9MZxoEuQUuBRJI3OKGMcOsdtHOsNMRGLxNu7TilqcfUVNuIBAwcYBGKpKcYcc3xlWjFMueDaVEj3Bj2mwOi9ZZ6QBaUfqGeA516GsKbTAtTD7LiSgpGyAN6ezZHDFG1j9GsyVLXd0pSwlP3jTSgOXnXfuM+VDiNR4qg2uSpKARu3msNu7MBIwjHPL9WqtViaDzeWkie9ltSrZcW432qbOK2caUzLZDsdxLrauCknIo6XpCdbrYJ65q3hu20L5E43eNcaZubtq1emEFH1eUkko6goddViuHhYYB2bvWF3OsKQXKF9e6sdzVI+0SGCn8N6go7Xz9Kn+qquskj2fK71f8qTHojTzyHlIBcQMJV1gccfQUa6ptl7lPSYzVv2mluKUle2N4Jzzp6oEheHBs4dcUiRg8uT46V8s35fa7s+VHN8QBNtffN+YpItTTjdjbQUkL6PGDzo6m2q9yrnEDtvKG47ySVBQO4H96i+EhDilBum39KapIxHNnfaQruM6acHyJ8xVAaSB6QIGOSqQbsy+7px1uO30j2wnZRnGSCKoVstt3e1dFly4JZbbyCQoGoshJK8ObN02O/l0CSLVpRd+38L/2Q==</file> </questiontext>
+ <generalfeedback format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/infos.jpg" alt="Informations" width="34" height="49" />For further information, see the <a title="Moodle Docs - About Moodle" href="http://docs.moodle.org/en/About_Moodle">documentation about Moodle</a></p>\r
+<p>.</p>]]></text>
+<file name="infos.jpg" encoding="base64">/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBggGBQkIBwgKCQkKGRYaDQwMDRodFBAhKhwlIB8lHh4jIjIoIyQvJSQeKy8sLzMtODgsISo9QTs2QTIuMywBCQoKDQsNGQ4OGTUkHiQ1NTU1NTU1NTU1NTU1NTU1Ly82NTU1NDUtLTQ0NTU1MCwsLCw0KTU0LzU2NjMpKTQ2Kf/AABEIADEAIgMBIgACEQEDEQH/xAAaAAEAAwEBAQAAAAAAAAAAAAAABQYHBAID/8QALhAAAQMCBAMHBAMAAAAAAAAAAgABAwQFBhEhMUFRgRITIjJxsfAHYWKRFBVC/8QAGQEAAgMBAAAAAAAAAAAAAAAAAAEDBAUC/8QAIREAAgEDBAMBAAAAAAAAAAAAAAECAxExBBITISIjQQX/2gAMAwEAAhEDEQA/ANxXk5AiHtSGINzJ8lz3GvitlCdTOTCAcVl16xZU3SoMhMoof8iz65fdWaGmlXfWCOpUUMmrDVwGbCM8RE+zMbZuvqsdvzR2WSme3Xf+W8o5n3ZeX11dsn5PyVowJjUrof8AX1xN3w+Qufzbq3TuppHCHJF3RzGqnLa8l6REVMmKV9UpzhsMLA7sJF4v2yySe5OD9mPV+LvwW84osg3+xzUj6G7eF23+cfVmWAXW01Vnrnp62JwJn0LLwn6fNFt/mzi4OH0p6iLvuJ3HZi01EUEQQCTFm0YMLPtyUdg+eePFNI8RF2vFx/F392ZSGN7va7sVva0yHI0Ik0jlG46u7ZZZ77Kx/TPBdQFc1zr4ii7HkAm1bjryd9NOWee7KS/Fo/Zl3FbdV8TV0RFgF0LiuFmoboDjWU4SZ75t78H6rtRCdgISiwdaKCbvYKUBPg4gIu3UWZ1MhGEQMEYsAtswtoy9Im5OXbYrWCIiQwiIgAiIgAiIgD//2Q==</file> </generalfeedback>
+ <defaultgrade>1.0000000</defaultgrade>
+ <penalty>1.0000000</penalty>
+ <hidden>0</hidden>
+ <answer fraction="100" format="moodle_auto_format">
+ <text>true</text>
+ <feedback format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/thumbup.jpg" alt="thumb up" width="24" height="24" /> Your answer is correct.</p>]]></text>
+<file name="thumbup.jpg" encoding="base64">/9j/4AAQSkZJRgABAQEAYABgAAD/4RDARXhpZgAATU0AKgAAAAgABQESAAMAAAABAAEAAAExAAIAAAAuAAAIVgEyAAIAAAAUAAAIhIdpAAQAAAABAAAImOocAAcAAAgMAAAASgAAAAAc6gAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE1pY3Jvc29mdCBXaW5kb3dzIFBob3RvIFZpZXdlciA2LjEuNzYwMC4xNjM4NQAyMDEzOjAxOjEwIDE4OjI1OjUzAAAB6hwABwAACAwAAAiqAAAAABzqAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4TG4aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49J++7vycgaWQ9J1c1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCc/Pg0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyI+PHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj48cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0idXVpZDpmYWY1YmRkNS1iYTNkLTExZGEtYWQzMS1kMzNkNzUxODJmMWIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+PHhtcDpDcmVhdG9yVG9vbD5NaWNyb3NvZnQgV2luZG93cyBQaG90byBWaWV3ZXIgNi4xLjc2MDAuMTYzODU8L3htcDpDcmVhdG9yVG9vbD48L3JkZjpEZXNjcmlwdGlvbj48L3JkZjpSREY+PC94OnhtcG1ldGE+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSd3Jz8+/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgAGAAYAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A99+OX7RviD/hMdS0fQrt9O0/TpzAzwLh5WUfP83+9WHqPjz4o6Z4D0zxZJ4n1FtPv5ngiCXKeYrLu+8vlf8ATJ61fB3wssfiL8W/FVjfyTRQ/a76dXhKht32nb/ED617p4Y8IadbfA3RbOSCKaFbZLtFvtPfUQkkh3N+6T5m/wBYy/L90e1fndHDYzHValWVVqOtrO2x+w4jG5RleGw9CGHjOS5XO63TXQ8T+CP7RviE+MtN0XxBdvqWn6lOsKNcDc8bsPl+f/eoqv4x0CGy+Lfhia2SCKNbuycrbaVLp6l/tP8Azykb9aK7MFjMRhoSo1ZtuL3/AKZ4ue4HA4ypSxNCkoKcU2vmzvdY0zV/hR4/1TUrOCNo7ySSRJpi5jZZG3bf97dV3Svi5LZ+GbXRbvShPFBGsHm2t+9qwVRhMbfmH3f71FFefi8TVwdepSouy1PXwOEoZlg6dfExvKy8tvQztH8PXHxB8d6TfQ2NxaWVpIksks13LcFfLfcB5sn95v4P9miiivpsqw8MRQdSpq2/L/I+SzitOjinRp6RirL+mf/Z</file> </feedback>
+ </answer>
+ <answer fraction="0" format="moodle_auto_format">
+ <text>false</text>
+ <feedback format="html">
+ <text><![CDATA[<p><img src="@@PLUGINFILE@@/thumbdown.jpg" alt="thumb down" width="24" height="24" /> Your answer is incorrect.</p>]]></text>
+<file name="thumbdown.jpg" encoding="base64">/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5Ojf/2wBDAQoKCg0MDRoPDxo3JR8lNzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzf/wAARCAAYABgDASIAAhEBAxEB/8QAGgABAAIDAQAAAAAAAAAAAAAAAAQFAQMGB//EACcQAAIBAwMDBAMBAAAAAAAAAAECAwAEBQYRIRITMTJBUXEiUmKh/8QAFwEAAwEAAAAAAAAAAAAAAAAAAgQFA//EACIRAAIBAwQCAwAAAAAAAAAAAAECAwAEERIhMVEFQROh8f/aAAwDAQACEQMRAD8A9AubiTK5m5t5JpEihZlVUiaTbpO3pX5PvWy4wLR2Ml1Fc9QRS/TJAYzsPPnn2+KqsdcompsksjxoO7MAZLpoBv3P2Uf5XTX17BFpm7l7iSKI2jJhnM4DNwPyPJ9QPPipiKkgZn537q9N8kLIkfBx17+6qrd7vC5i2tZpFKzMoKoSVIY7b/e9KrchmoMtqXGS2qyKglhTZwAd+5v7fdKYtGB1BTsDtSfkY2XQzjDEb1jVGlb45Oe6sYmmincuQnJUnzx91GgsdQQ4efFrj5jBO4diYh1Ajbwer+RSlC1jGWLAkZ6/KJPLzhFQgHGOR1x7qTpfSt8MnBdX0TQxQOHAfgsR44+6UpW8ECwrpWlLq7kun1yV/9k=</file> </feedback>
+ </answer>
+ </question>
+
+</quiz>
\ No newline at end of file
$this->assertEquals(array(
array('text' => 'This is the first hint',
- 'format' => FORMAT_HTML, 'files' => array()),
+ 'format' => FORMAT_HTML),
array('text' => 'This is the second hint',
- 'format' => FORMAT_HTML, 'files' => array()),
+ 'format' => FORMAT_HTML),
), $qo->hint);
$this->assertFalse(isset($qo->hintclearwrong));
$this->assertFalse(isset($qo->hintshownumcorrect));
$this->assertEquals(array(
array('text' => 'This is the first hint',
- 'format' => FORMAT_HTML, 'files' => array()),
+ 'format' => FORMAT_HTML),
array('text' => 'This is the second hint',
- 'format' => FORMAT_HTML, 'files' => array()),
+ 'format' => FORMAT_HTML),
), $qo->hint);
$this->assertEquals(array(1, 0), $qo->hintclearwrong);
$this->assertEquals(array(0, 1), $qo->hintshownumcorrect);
$expectedq->attachments = 0;
$expectedq->graderinfo['text'] = '';
$expectedq->graderinfo['format'] = FORMAT_MOODLE;
- $expectedq->graderinfo['files'] = array();
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
}
$expectedq->attachments = -1;
$expectedq->graderinfo['text'] = '<p>Grade <b>generously</b>!</p>';
$expectedq->graderinfo['format'] = FORMAT_HTML;
- $expectedq->graderinfo['files'] = array();
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
}
$expectedq->questiontext = 'Match the upper and lower case letters.';
$expectedq->questiontextformat = FORMAT_HTML;
$expectedq->correctfeedback = array('text' => 'Well done.',
- 'format' => FORMAT_HTML, 'files' => array());
+ 'format' => FORMAT_HTML);
$expectedq->partiallycorrectfeedback = array('text' => 'Not entirely.',
- 'format' => FORMAT_HTML, 'files' => array());
+ 'format' => FORMAT_HTML);
$expectedq->shownumcorrect = false;
$expectedq->incorrectfeedback = array('text' => 'Completely wrong!',
- 'format' => FORMAT_HTML, 'files' => array());
+ 'format' => FORMAT_HTML);
$expectedq->generalfeedback = 'The answer is A -> a, B -> b and C -> c.';
$expectedq->generalfeedbackformat = FORMAT_HTML;
$expectedq->defaultmark = 1;
$expectedq->penalty = 0.3333333;
$expectedq->shuffleanswers = 0;
$expectedq->subquestions = array(
- array('text' => 'A', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => 'B', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => 'C', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => '', 'format' => FORMAT_HTML, 'files' => array()));
+ array('text' => 'A', 'format' => FORMAT_HTML),
+ array('text' => 'B', 'format' => FORMAT_HTML),
+ array('text' => 'C', 'format' => FORMAT_HTML),
+ array('text' => '', 'format' => FORMAT_HTML));
$expectedq->subanswers = array('a', 'b', 'c', 'd');
$expectedq->hint = array(
- array('text' => 'Hint 1', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => '', 'format' => FORMAT_HTML, 'files' => array()),
+ array('text' => 'Hint 1', 'format' => FORMAT_HTML),
+ array('text' => '', 'format' => FORMAT_HTML),
);
$expectedq->hintshownumcorrect = array(true, true);
$expectedq->hintclearwrong = array(false, true);
$expectedq->questiontextformat = FORMAT_HTML;
$expectedq->correctfeedback = array(
'text' => '<p>Your answer is correct.</p>',
- 'format' => FORMAT_HTML,
- 'files' => array());
+ 'format' => FORMAT_HTML);
$expectedq->shownumcorrect = false;
$expectedq->partiallycorrectfeedback = array(
'text' => '<p>Your answer is partially correct.</p>',
- 'format' => FORMAT_HTML,
- 'files' => array());
+ 'format' => FORMAT_HTML);
$expectedq->shownumcorrect = true;
$expectedq->incorrectfeedback = array(
'text' => '<p>Your answer is incorrect.</p>',
- 'format' => FORMAT_HTML,
- 'files' => array());
+ 'format' => FORMAT_HTML);
$expectedq->generalfeedback = 'The even numbers are 2 and 4.';
$expectedq->defaultmark = 2;
$expectedq->length = 1;
$expectedq->single = false;
$expectedq->answer = array(
- array('text' => '1', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => '2', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => '3', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => '4', 'format' => FORMAT_HTML, 'files' => array()));
+ array('text' => '1', 'format' => FORMAT_HTML),
+ array('text' => '2', 'format' => FORMAT_HTML),
+ array('text' => '3', 'format' => FORMAT_HTML),
+ array('text' => '4', 'format' => FORMAT_HTML));
$expectedq->fraction = array(0, 1, 0, 1);
$expectedq->feedback = array(
- array('text' => '', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => '', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => '', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => '', 'format' => FORMAT_HTML, 'files' => array()));
+ array('text' => '', 'format' => FORMAT_HTML),
+ array('text' => '', 'format' => FORMAT_HTML),
+ array('text' => '', 'format' => FORMAT_HTML),
+ array('text' => '', 'format' => FORMAT_HTML));
$expectedq->hint = array(
- array('text' => 'Hint 1.', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => 'Hint 2.', 'format' => FORMAT_HTML, 'files' => array()),
+ array('text' => 'Hint 1.', 'format' => FORMAT_HTML),
+ array('text' => 'Hint 2.', 'format' => FORMAT_HTML),
);
$expectedq->hintshownumcorrect = array(false, false);
$expectedq->hintclearwrong = array(false, false);
$expectedq->fraction = array(1, 0, 0);
$expectedq->feedback = array(
array('text' => 'Well done!',
- 'format' => FORMAT_HTML, 'files' => array()),
+ 'format' => FORMAT_HTML),
array('text' => 'What were you thinking?!',
- 'format' => FORMAT_HTML, 'files' => array()),
+ 'format' => FORMAT_HTML),
array('text' => 'Completely wrong.',
- 'format' => FORMAT_HTML, 'files' => array()));
+ 'format' => FORMAT_HTML));
$expectedq->tolerance = array(0.001, 1, 0);
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
$expectedq->answer = array('Beta', '*');
$expectedq->fraction = array(1, 0);
$expectedq->feedback = array(
- array('text' => 'Well done!', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => 'Doh!', 'format' => FORMAT_HTML, 'files' => array()));
+ array('text' => 'Well done!', 'format' => FORMAT_HTML),
+ array('text' => 'Doh!', 'format' => FORMAT_HTML));
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
}
$expectedq->penalty = 1;
$expectedq->feedbacktrue = array('text' => 'Well done!',
- 'format' => FORMAT_HTML, 'files' => array());
+ 'format' => FORMAT_HTML);
$expectedq->feedbackfalse = array('text' => 'Doh!',
- 'format' => FORMAT_HTML, 'files' => array());
+ 'format' => FORMAT_HTML);
$expectedq->correctanswer = true;
$this->assert(new question_check_specified_fields_expectation($expectedq), $q);
$expectedqa->penalty = 0.5;
$expectedqa->hint = array(
- array('text' => 'Hint 1', 'format' => FORMAT_HTML, 'files' => array()),
- array('text' => 'Hint 2', 'format' => FORMAT_HTML, 'files' => array()),
+ array('text' => 'Hint 1', 'format' => FORMAT_HTML),
+ array('text' => 'Hint 2', 'format' => FORMAT_HTML),
);
$sa = new stdClass();
$this->assert_same_xml($expectedxml, $xml);
}
+
+ public function test_import_files_as_draft() {
+ $this->resetAfterTest();
+ $this->setAdminUser();
+
+ $xml = <<<END
+<questiontext format="html">
+ <text><![CDATA[<p><a href="@@PLUGINFILE@@/moodle.txt">This text file</a> contains the word 'Moodle'.</p>]]></text>
+ <file name="moodle.txt" encoding="base64">TW9vZGxl</file>
+</questiontext>
+END;
+
+ $textxml = xmlize($xml);
+ $qo = new stdClass();
+
+ $importer = new qformat_xml();
+ $draftitemid = $importer->import_files_as_draft($textxml['questiontext']['#']['file']);
+ $files = file_get_drafarea_files($draftitemid);
+
+ $this->assertEquals(1, count($files->list));
+
+ $file = $files->list[0];
+ $this->assertEquals('moodle.txt', $file->filename);
+ $this->assertEquals('/', $file->filepath);
+ $this->assertEquals(6, $file->size);
+ }
}
'quba.component = :qubacomponent
AND NOT EXISTS (
SELECT 1
- FROM {question_attempts} qa
- JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id
- WHERE qa.questionusageid = quba.id
- AND (qa.timemodified > :qamodifiedcutoff
- OR qas.timecreated > :stepcreatedcutoff)
+ FROM {question_attempts} subq_qa
+ JOIN {question_attempt_steps} subq_qas ON subq_qas.questionattemptid = subq_qa.id
+ JOIN {question_usages} subq_qu ON subq_qu.id = subq_qa.questionusageid
+ WHERE subq_qa.questionusageid = quba.id
+ AND subq_qu.component = :qubacomponent2
+ AND (subq_qa.timemodified > :qamodifiedcutoff
+ OR subq_qas.timecreated > :stepcreatedcutoff)
)
',
- array('qubacomponent' => 'core_question_preview',
+ array('qubacomponent' => 'core_question_preview', 'qubacomponent2' => 'core_question_preview',
'qamodifiedcutoff' => $lastmodifiedcutoff, 'stepcreatedcutoff' => $lastmodifiedcutoff));
question_engine::delete_questions_usage_by_activities($oldpreviews);
if (is_array($extraquestionfields) && !empty($question->options)) {
array_shift($extraquestionfields);
foreach ($extraquestionfields as $field) {
- if (isset($question->options->$field)) {
+ if (property_exists($question->options, $field)) {
$question->$field = $question->options->$field;
}
}
$question->graderinfoformat = $questiondata->options->graderinfoformat;
}
+ public function delete_question($questionid, $contextid) {
+ global $DB;
+
+ $DB->delete_records('qtype_essay_options', array('questionid' => $questionid));
+ parent::delete_question($questionid, $contextid);
+ }
+
/**
* @return array the different response formats that the question type supports.
* internal name => human-readable name.
$options->$questionidcolname = $question->id;
}
foreach ($extraquestionfields as $field) {
- if (!isset($question->$field)) {
- $result = new stdClass();
- $result->error = "No data for field $field when saving " .
- $this->name() . ' question id ' . $question->id;
- return $result;
+ if (property_exists($question, $field)) {
+ $options->$field = $question->$field;
}
- $options->$field = $question->$field;
}
- if (!$DB->{$function}($question_extension_table, $options)) {
- $result = new stdClass();
- $result->error = 'Could not save question options for ' .
- $this->name() . ' question id ' . $question->id;
- return $result;
- }
+ $DB->{$function}($question_extension_table, $options);
}
$extraanswerfields = $this->extra_answer_fields();
$blogcell = new html_table_cell();
$blogcell->attributes['class'] = 'blog';
if ($blogcount = blog_get_associated_count($course->id, $cm->id)) {
- $blogcell->text = html_writer::link('/blog/index.php?modid='.$cm->id, $blogcount);
+ $blogurl = new moodle_url('/blog/index.php', array('modid' => $cm->id));
+ $blogcell->text = html_writer::link($blogurl, $blogcount);
} else {
$blogcell->text = '-';
}
}
public function get_link($photoid) {
- return $this->build_photo_id($photoid);
+ return $this->build_photo_url($photoid);
}
/**
/* Only set these options if we're showing the js container */
.jsenabled .choosercontainer #chooseform .alloptions {
- max-height: 550px;
overflow-x: hidden;
overflow-y: auto;
max-width: 20.3em;
background-color: #FFFFFF;
overflow-x: hidden;
overflow-y: auto;
- max-height: 550px;
line-height: 2em;
}
.dir-rtl.path-course-view li.activity span.autocompletion {right:-20px;left:auto;padding:0px;}
.dir-rtl.path-course-view .completionprogress {float: none;}
+li.section.hidden span.commands a.editing_hide,
+li.section.hidden span.commands a.editing_show {cursor:default;}
+
.section img.movetarget {height:16px;width:80px;}
#page-course-enrol .generalbox,
}
if ($user->maildisplay == 1 or ($user->maildisplay == 2 and ($course->id != SITEID) and !isguestuser()) or
has_capability('moodle/course:viewhiddenuserfields', $context) or
- in_array('email', $extrafields)) {
+ in_array('email', $extrafields) or ($user->id == $USER->id)) {
$row->cells[1]->text .= get_string('email').get_string('labelsep', 'langconfig').html_writer::link("mailto:$user->email", $user->email) . '<br />';
}
foreach ($extrafields as $field) {
array('userid' => $user1->id, 'courseid' => $course->id),
array('userid' => $user2->id, 'courseid' => $course->id)));
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $enrolledusers = external_api::clean_returnvalue(core_user_external::get_course_user_profiles_returns(), $enrolledusers);
+
// Check we retrieve the good total number of enrolled users + no error on capability.
$this->assertEquals(3, count($enrolledusers));
array('userid' => $user1->id, 'courseid' => $course->id),
array('userid' => $user2->id, 'courseid' => $course->id)));
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $enrolledusers = external_api::clean_returnvalue(core_user_external::get_course_user_profiles_returns(), $enrolledusers);
+
foreach($enrolledusers as $enrolleduser) {
if ($enrolleduser['username'] == $user1->username) {
$this->assertEquals($user1->idnumber, $enrolleduser['idnumber']);
// Call the external function.
$createdusers = core_user_external::create_users(array($user1));
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $createdusers = external_api::clean_returnvalue(core_user_external::create_users_returns(), $createdusers);
+
// Check we retrieve the good total number of created users + no error on capability.
$this->assertEquals(1, count($createdusers));
$returnedusers = core_user_external::get_users_by_id(array(
$USER->id, $user1->id, $user2->id));
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $returnedusers = external_api::clean_returnvalue(core_user_external::get_users_by_id_returns(), $returnedusers);
+
// Check we retrieve the good total number of enrolled users + no error on capability.
$this->assertEquals(3, count($returnedusers));
$returnedusers = core_user_external::get_users_by_id(array(
$USER->id, $user1->id, $user2->id));
+ // We need to execute the return values cleaning process to simulate the web service server.
+ $returnedusers = external_api::clean_returnvalue(core_user_external::get_users_by_id_returns(), $returnedusers);
+
foreach($returnedusers as $enrolleduser) {
if ($enrolleduser['username'] == $user1->username) {
$this->assertEquals($user1->idnumber, $enrolleduser['idnumber']);
$this->setExpectedException('required_capability_exception');
core_user_external::update_users(array($user1));
}
-}
\ No newline at end of file
+}
echo '<table class="list" summary="">';
-//checks were performed above that ensure that if we've got to here either the user
-//is viewing their own profile ($USER->id == $user->id) or $user is enrolled in the course
+// Show email if any of the following conditions match.
+// 1. User is viewing his own profile.
+// 2. Has allowed everyone to see email
+// 3. User has allowed course members to can see email and current user is in same course
+// 4. Has either course:viewhiddenuserfields or site:viewuseridentity capability.
if ($currentuser
- or $user->maildisplay == 1 //allow everyone to see email address
- or ($user->maildisplay == 2 && is_enrolled($coursecontext, $USER)) //fellow course members can see email. Already know $user is enrolled
- or has_capability('moodle/course:useremail', $coursecontext)) {
+ or $user->maildisplay == 1
+ or ($user->maildisplay == 2 && is_enrolled($coursecontext, $USER))
+ or has_capability('moodle/course:viewhiddenuserfields', $coursecontext)
+ or has_capability('moodle/site:viewuseridentity', $coursecontext)) {
print_row(get_string("email").":", obfuscate_mailto($user->email, ''));
}
defined('MOODLE_INTERNAL') || die();
-$version = 2012062504.00; // YYYYMMDD = weekly release date of this DEV branch
+$version = 2012062504.01; // YYYYMMDD = weekly release date of this DEV branch
// RR = release increments - 00 in DEV branches
// .XX = incremental changes
-$release = '2.3.4 (Build: 20130114)'; // Human-friendly version name
+$release = '2.3.4+ (Build: 20130118)'; // Human-friendly version name
$branch = '23'; // this version's branch
$maturity = MATURITY_STABLE; // this version's maturity level
} else {
$response = '<?xml version="1.0" encoding="UTF-8" ?>'."\n";
$response .= '<RESPONSE>'."\n";
- $response .= self::xmlize_result($this->returns, $this->function->returns_desc);
+ $response .= self::xmlize_result($validatedvalues, $this->function->returns_desc);
$response .= '</RESPONSE>'."\n";
}
}
public function simpletest($serverurl, $function, $params) {
return download_file_content($serverurl.'&wsfunction='.$function, null, $params);
}
-}
\ No newline at end of file
+}