{"id":19591948,"url":"https://github.com/catalyst/moodle-local_headlessquiz","last_synced_at":"2025-07-01T00:03:11.608Z","repository":{"id":61771325,"uuid":"549357906","full_name":"catalyst/moodle-local_headlessquiz","owner":"catalyst","description":null,"archived":false,"fork":false,"pushed_at":"2024-05-07T01:59:25.000Z","size":128,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":18,"default_branch":"MOODLE_403_STABLE","last_synced_at":"2025-06-27T08:51:42.051Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/catalyst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-11T04:09:05.000Z","updated_at":"2025-01-15T21:03:33.000Z","dependencies_parsed_at":"2024-11-11T08:34:12.227Z","dependency_job_id":"769cecb0-9c20-4ab6-882f-d30d9081ae95","html_url":"https://github.com/catalyst/moodle-local_headlessquiz","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/catalyst/moodle-local_headlessquiz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_headlessquiz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_headlessquiz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_headlessquiz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_headlessquiz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/catalyst","download_url":"https://codeload.github.com/catalyst/moodle-local_headlessquiz/tar.gz/refs/heads/MOODLE_403_STABLE","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_headlessquiz/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262870852,"owners_count":23377309,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T08:32:09.164Z","updated_at":"2025-07-01T00:03:11.478Z","avatar_url":"https://github.com/catalyst.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://github.com/catalyst/moodle-local_headlessquiz/actions/workflows/ci.yml?query=branch%3AMOODLE_403_STABLE\"\u003e\n\u003cimg src=\"https://github.com/catalyst/moodle-local_headlessquiz/workflows/ci/badge.svg?branch=MOODLE_403_STABLE\"\u003e\n\u003c/a\u003e\n\n# local_headlessquiz\nThe primary purpose of this plugin is to facilitate running quizzes on Moodle in 'headless' mode i.e. via webservice calls.\n\nPreviously, up to 6 webservice calls were required to just start a single quiz attempt, making this quite difficult. This plugin combines this functionality into a single call, streamlining the process.\n\n## Usage\nThere is no interface to this plugin, it is interacted with purely via webservices. \n\n1. Create a quiz via the Moodle interface (see Limitations below)\n2. Get the course module ID (from the URL query parameters) \n3. The headless quiz function is attached to the `moodle_mobile_app` webservice, so ensure that it is enabled.\n4. Call the webservice: `/webservice/rest/server.php?wstoken=[TOKEN]\u0026wsfunction=local_headlessquiz_get_attempt\u0026cmid=[CMID]\u0026moodlewsrestformat=json` (replacing variables in brackets where necessary)\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eExample response from webservice function\u003c/b\u003e\u003c/summary\u003e\n\n```json\n{\n\t\"data\": {\n\t\t\"user\": {\n\t\t\t\"id\": 18\n\t\t},\n\t\t\"quiz\": {\n\t\t\t\"id\": 1,\n\t\t\t\"name\": \"Headless Quiz Test 1\",\n\t\t\t\"cmid\": 66,\n\t\t\t\"gradetopass\": 5,\n\t\t\t\"bestgrade\": 10,\n\t\t\t\"maxgrade\": 15,\n\t\t\t\"questions\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": 11,\n\t\t\t\t\t\"name\": \"True or false 1\",\n\t\t\t\t\t\"questiontext\": \"\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eIs this question true? Select True\u003cbr\u003e\u003c\\/p\u003e\",\n\t\t\t\t\t\"type\": \"truefalse\",\n\t\t\t\t\t\"slot\": 1,\n\t\t\t\t\t\"options\": \"{\\\"id\\\":\\\"6\\\",\\\"question\\\":\\\"11\\\",\\\"trueanswer\\\":\\\"21\\\",\\\"falseanswer\\\":\\\"22\\\",\\\"answers\\\":{\\\"21\\\":{\\\"id\\\":\\\"21\\\",\\\"question\\\":\\\"11\\\",\\\"answer\\\":\\\"True\\\",\\\"answerformat\\\":\\\"0\\\",\\\"fraction\\\":\\\"1.0000000\\\",\\\"feedback\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003eFeed back for true test\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"feedbackformat\\\":\\\"1\\\"},\\\"22\\\":{\\\"id\\\":\\\"22\\\",\\\"question\\\":\\\"11\\\",\\\"answer\\\":\\\"False\\\",\\\"answerformat\\\":\\\"0\\\",\\\"fraction\\\":\\\"0.0000000\\\",\\\"feedback\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003e\u003c\\\\\\/p\u003e\u003cp dir=\\\\\\\"ltr\\\\\\\"\u003eFeed back for false test\u003cbr\u003e\u003c\\\\\\/p\u003e\u003cbr\u003e\u003cp\u003e\u003c\\\\\\/p\u003e\\\",\\\"feedbackformat\\\":\\\"1\\\"}}}\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": 12,\n\t\t\t\t\t\"name\": \"multiple choice test 1\",\n\t\t\t\t\t\"questiontext\": \"\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003emultiple choice test 1\u003cbr\u003e\u003c\\/p\u003e\",\n\t\t\t\t\t\"type\": \"multichoice\",\n\t\t\t\t\t\"slot\": 2,\n\t\t\t\t\t\"options\": \"{\\\"id\\\":\\\"3\\\",\\\"questionid\\\":\\\"12\\\",\\\"layout\\\":\\\"0\\\",\\\"single\\\":\\\"1\\\",\\\"shuffleanswers\\\":\\\"1\\\",\\\"correctfeedback\\\":\\\"Your answer is correct.\\\",\\\"correctfeedbackformat\\\":\\\"1\\\",\\\"partiallycorrectfeedback\\\":\\\"Your answer is partially correct.\\\",\\\"partiallycorrectfeedbackformat\\\":\\\"1\\\",\\\"incorrectfeedback\\\":\\\"Your answer is incorrect.\\\",\\\"incorrectfeedbackformat\\\":\\\"1\\\",\\\"answernumbering\\\":\\\"abc\\\",\\\"shownumcorrect\\\":\\\"1\\\",\\\"showstandardinstruction\\\":\\\"0\\\",\\\"answers\\\":{\\\"23\\\":{\\\"id\\\":\\\"23\\\",\\\"question\\\":\\\"12\\\",\\\"answer\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003eC1\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"answerformat\\\":\\\"1\\\",\\\"fraction\\\":\\\"1.0000000\\\",\\\"feedback\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003eC1 feedback here\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"feedbackformat\\\":\\\"1\\\"},\\\"24\\\":{\\\"id\\\":\\\"24\\\",\\\"question\\\":\\\"12\\\",\\\"answer\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003eC2\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"answerformat\\\":\\\"1\\\",\\\"fraction\\\":\\\"0.9000000\\\",\\\"feedback\\\":\\\"\u003cstrong\u003eC2 feedback\u003cbr\u003e\u003c\\\\\\/strong\u003e\\\",\\\"feedbackformat\\\":\\\"1\\\"},\\\"25\\\":{\\\"id\\\":\\\"25\\\",\\\"question\\\":\\\"12\\\",\\\"answer\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003eC3\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"answerformat\\\":\\\"1\\\",\\\"fraction\\\":\\\"0.1111111\\\",\\\"feedback\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003e\u003cem\u003eC3 feddback\u003cbr\u003e\u003c\\\\\\/em\u003e\u003c\\\\\\/p\u003e\\\",\\\"feedbackformat\\\":\\\"1\\\"},\\\"26\\\":{\\\"id\\\":\\\"26\\\",\\\"question\\\":\\\"12\\\",\\\"answer\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003eC4\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"answerformat\\\":\\\"1\\\",\\\"fraction\\\":\\\"0.2500000\\\",\\\"feedback\\\":\\\"\u003ch3 dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003eC4 feedback\u003cbr\u003e\u003c\\\\\\/h3\u003e\\\",\\\"feedbackformat\\\":\\\"1\\\"}}}\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": 5,\n\t\t\t\t\t\"name\": \"Test3\",\n\t\t\t\t\t\"questiontext\": \"\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003etest\u003cbr\u003e\u003c\\/p\u003e\",\n\t\t\t\t\t\"type\": \"multichoice\",\n\t\t\t\t\t\"slot\": 3,\n\t\t\t\t\t\"options\": \"{\\\"id\\\":\\\"2\\\",\\\"questionid\\\":\\\"5\\\",\\\"layout\\\":\\\"0\\\",\\\"single\\\":\\\"0\\\",\\\"shuffleanswers\\\":\\\"1\\\",\\\"correctfeedback\\\":\\\"Your answer is correct.\\\",\\\"correctfeedbackformat\\\":\\\"1\\\",\\\"partiallycorrectfeedback\\\":\\\"Your answer is partially correct.\\\",\\\"partiallycorrectfeedbackformat\\\":\\\"1\\\",\\\"incorrectfeedback\\\":\\\"Your answer is incorrect.\\\",\\\"incorrectfeedbackformat\\\":\\\"1\\\",\\\"answernumbering\\\":\\\"abc\\\",\\\"shownumcorrect\\\":\\\"1\\\",\\\"showstandardinstruction\\\":\\\"0\\\",\\\"answers\\\":{\\\"11\\\":{\\\"id\\\":\\\"11\\\",\\\"question\\\":\\\"5\\\",\\\"answer\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003etest\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"answerformat\\\":\\\"1\\\",\\\"fraction\\\":\\\"0.9000000\\\",\\\"feedback\\\":\\\"\\\",\\\"feedbackformat\\\":\\\"1\\\"},\\\"12\\\":{\\\"id\\\":\\\"12\\\",\\\"question\\\":\\\"5\\\",\\\"answer\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003etest\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"answerformat\\\":\\\"1\\\",\\\"fraction\\\":\\\"0.1000000\\\",\\\"feedback\\\":\\\"\\\",\\\"feedbackformat\\\":\\\"1\\\"},\\\"13\\\":{\\\"id\\\":\\\"13\\\",\\\"question\\\":\\\"5\\\",\\\"answer\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003etest\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"answerformat\\\":\\\"1\\\",\\\"fraction\\\":\\\"0.0000000\\\",\\\"feedback\\\":\\\"\\\",\\\"feedbackformat\\\":\\\"1\\\"},\\\"14\\\":{\\\"id\\\":\\\"14\\\",\\\"question\\\":\\\"5\\\",\\\"answer\\\":\\\"\u003cp dir=\\\\\\\"ltr\\\\\\\" style=\\\\\\\"text-align: left;\\\\\\\"\u003ewrong\u003cbr\u003e\u003c\\\\\\/p\u003e\\\",\\\"answerformat\\\":\\\"1\\\",\\\"fraction\\\":\\\"0.0000000\\\",\\\"feedback\\\":\\\"\\\",\\\"feedbackformat\\\":\\\"1\\\"}}}\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": 4,\n\t\t\t\t\t\"name\": \"Short answer\",\n\t\t\t\t\t\"questiontext\": \"\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eShort answer\u003cbr\u003e\u003c\\/p\u003e\",\n\t\t\t\t\t\"type\": \"shortanswer\",\n\t\t\t\t\t\"slot\": 4,\n\t\t\t\t\t\"options\": \"{\\\"usecase\\\":\\\"0\\\",\\\"answers\\\":{\\\"9\\\":{\\\"id\\\":\\\"9\\\",\\\"question\\\":\\\"4\\\",\\\"answer\\\":\\\"correct\\\",\\\"answerformat\\\":\\\"0\\\",\\\"fraction\\\":\\\"1.0000000\\\",\\\"feedback\\\":\\\"\\\",\\\"feedbackformat\\\":\\\"1\\\"},\\\"10\\\":{\\\"id\\\":\\\"10\\\",\\\"question\\\":\\\"4\\\",\\\"answer\\\":\\\"incorrect\\\",\\\"answerformat\\\":\\\"0\\\",\\\"fraction\\\":\\\"0.5000000\\\",\\\"feedback\\\":\\\"\\\",\\\"feedbackformat\\\":\\\"1\\\"}}}\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t\"attempt\": {\n\t\t\t\"id\": 77,\n\t\t\t\"state\": \"inprogress\",\n\t\t\t\"feedback\": \"\",\n\t\t\t\"summarks\": 0,\n\t\t\t\"passed\": false,\n\t\t\t\"scaledgrade\": 0,\n\t\t\t\"timestart\": 1667178056,\n\t\t\t\"timemodified\": 1667179192,\n\t\t\t\"number\": 64,\n\t\t\t\"responses\": [\n\t\t\t\t{\n\t\t\t\t\t\"questionid\": 11,\n\t\t\t\t\t\"state\": \"gradedright\",\n\t\t\t\t\t\"mark\": 1,\n\t\t\t\t\t\"status\": \"Correct\",\n\t\t\t\t\t\"data\": \"{\\\"answer\\\":\\\"1\\\"}\",\n\t\t\t\t\t\"slot\": 1,\n\t\t\t\t\t\"html\": \"\u003cdiv id=\\\"question-77-1\\\" class=\\\"que truefalse immediatefeedback correct\\\"\u003e\u003cdiv class=\\\"info\\\"\u003e\u003ch3 class=\\\"no\\\"\u003eQuestion \u003cspan class=\\\"qno\\\"\u003e1\u003c\\/span\u003e\u003c\\/h3\u003e\u003cdiv class=\\\"state\\\"\u003eCorrect\u003c\\/div\u003e\u003cdiv class=\\\"grade\\\"\u003eMark 1.00 out of 1.00\u003c\\/div\u003e\u003cdiv class=\\\"questionflag editable\\\"\u003e\u003cinput type=\\\"hidden\\\" name=\\\"q77:1_:flagged\\\" value=\\\"0\\\" \\/\u003e\u003cinput type=\\\"hidden\\\" value=\\\"qaid=273\u0026amp;qubaid=77\u0026amp;qid=11\u0026amp;slot=1\u0026amp;checksum=e1e20dd938322a7e95f3f5894c60ba08\u0026amp;sesskey=DESmM0G03Y\u0026amp;newstate=\\\" class=\\\"questionflagpostdata\\\" \\/\u003e\u003cinput type=\\\"checkbox\\\" id=\\\"q77:1_:flaggedcheckbox\\\" name=\\\"q77:1_:flagged\\\" value=\\\"1\\\" \\/\u003e\u003clabel id=\\\"q77:1_:flaggedlabel\\\" for=\\\"q77:1_:flaggedcheckbox\\\"\u003e\u003cimg src=\\\"https:\\/\\/commercetools.localhost\\/theme\\/image.php\\/boost\\/core\\/1666835649\\/i\\/unflagged\\\" alt=\\\"\\\" class=\\\"questionflagimage\\\" id=\\\"q77:1_:flaggedimg\\\" \\/\u003e\u003cspan\u003eFlag question\u003c\\/span\u003e\u003c\\/label\u003e\\n\u003c\\/div\u003e\u003c\\/div\u003e\u003cdiv class=\\\"content\\\"\u003e\u003cdiv class=\\\"formulation clearfix\\\"\u003e\u003ch4 class=\\\"accesshide\\\"\u003eQuestion text\u003c\\/h4\u003e\u003cinput type=\\\"hidden\\\" name=\\\"q77:1_:sequencecheck\\\" value=\\\"2\\\" \\/\u003e\u003cdiv class=\\\"qtext\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eIs this question true? Select True\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"ablock\\\"\u003e\u003cdiv class=\\\"prompt\\\"\u003eSelect one:\u003c\\/div\u003e\u003cdiv class=\\\"answer\\\"\u003e\u003cdiv class=\\\"r0 correct\\\"\u003e\u003cinput type=\\\"radio\\\" name=\\\"q77:1_answer\\\" value=\\\"1\\\" id=\\\"q77:1_answertrue\\\" disabled=\\\"disabled\\\" checked=\\\"checked\\\" \\/\u003e\u003clabel for=\\\"q77:1_answertrue\\\" class=\\\"ml-1\\\"\u003eTrue\u003c\\/label\u003e \u003ci class=\\\"icon fa fa-check text-success fa-fw \\\"  title=\\\"Correct\\\" role=\\\"img\\\" aria-label=\\\"Correct\\\"\u003e\u003c\\/i\u003e\u003c\\/div\u003e\u003cdiv class=\\\"r1\\\"\u003e\u003cinput type=\\\"radio\\\" name=\\\"q77:1_answer\\\" value=\\\"0\\\" id=\\\"q77:1_answerfalse\\\" disabled=\\\"disabled\\\" \\/\u003e\u003clabel for=\\\"q77:1_answerfalse\\\" class=\\\"ml-1\\\"\u003eFalse\u003c\\/label\u003e \u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003cdiv class=\\\"outcome clearfix\\\"\u003e\u003ch4 class=\\\"accesshide\\\"\u003eFeedback\u003c\\/h4\u003e\u003cdiv class=\\\"feedback\\\"\u003e\u003cdiv class=\\\"specificfeedback\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eFeed back for true test\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"generalfeedback\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eGeneral feedback here\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"rightanswer\\\"\u003eThe correct answer is 'True'.\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\",\n\t\t\t\t\t\"sequencecheck\": 2,\n\t\t\t\t\t\"feedback\": \"\u003cdiv class=\\\"specificfeedback\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eFeed back for true test\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"generalfeedback\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eGeneral feedback here\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"rightanswer\\\"\u003eThe correct answer is 'True'.\u003c\\/div\u003e\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"questionid\": 12,\n\t\t\t\t\t\"state\": \"gradedpartial\",\n\t\t\t\t\t\"mark\": 0.56000000000000005,\n\t\t\t\t\t\"status\": \"Partially correct\",\n\t\t\t\t\t\"data\": \"{\\\"answer\\\":\\\"1\\\"}\",\n\t\t\t\t\t\"slot\": 2,\n\t\t\t\t\t\"html\": \"\u003cdiv id=\\\"question-77-2\\\" class=\\\"que multichoice immediatefeedback partiallycorrect\\\"\u003e\u003cdiv class=\\\"info\\\"\u003e\u003ch3 class=\\\"no\\\"\u003eQuestion \u003cspan class=\\\"qno\\\"\u003e2\u003c\\/span\u003e\u003c\\/h3\u003e\u003cdiv class=\\\"state\\\"\u003ePartially correct\u003c\\/div\u003e\u003cdiv class=\\\"grade\\\"\u003eMark 0.56 out of 5.00\u003c\\/div\u003e\u003cdiv class=\\\"questionflag editable\\\"\u003e\u003cinput type=\\\"hidden\\\" name=\\\"q77:2_:flagged\\\" value=\\\"0\\\" \\/\u003e\u003cinput type=\\\"hidden\\\" value=\\\"qaid=274\u0026amp;qubaid=77\u0026amp;qid=12\u0026amp;slot=2\u0026amp;checksum=78c3bed6d558d9350d71c9ffbda50618\u0026amp;sesskey=DESmM0G03Y\u0026amp;newstate=\\\" class=\\\"questionflagpostdata\\\" \\/\u003e\u003cinput type=\\\"checkbox\\\" id=\\\"q77:2_:flaggedcheckbox\\\" name=\\\"q77:2_:flagged\\\" value=\\\"1\\\" \\/\u003e\u003clabel id=\\\"q77:2_:flaggedlabel\\\" for=\\\"q77:2_:flaggedcheckbox\\\"\u003e\u003cimg src=\\\"https:\\/\\/commercetools.localhost\\/theme\\/image.php\\/boost\\/core\\/1666835649\\/i\\/unflagged\\\" alt=\\\"\\\" class=\\\"questionflagimage\\\" id=\\\"q77:2_:flaggedimg\\\" \\/\u003e\u003cspan\u003eFlag question\u003c\\/span\u003e\u003c\\/label\u003e\\n\u003c\\/div\u003e\u003c\\/div\u003e\u003cdiv class=\\\"content\\\"\u003e\u003cdiv class=\\\"formulation clearfix\\\"\u003e\u003ch4 class=\\\"accesshide\\\"\u003eQuestion text\u003c\\/h4\u003e\u003cinput type=\\\"hidden\\\" name=\\\"q77:2_:sequencecheck\\\" value=\\\"2\\\" \\/\u003e\u003cdiv class=\\\"qtext\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003emultiple choice test 1\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"ablock no-overflow visual-scroll-x\\\"\u003e\u003cdiv class=\\\"answer\\\"\u003e\u003cdiv class=\\\"r0\\\"\u003e\u003cinput type=\\\"radio\\\" name=\\\"q77:2_answer\\\" disabled=\\\"disabled\\\" value=\\\"0\\\" id=\\\"q77:2_answer0\\\" aria-labelledby=\\\"q77:2_answer0_label\\\" \\/\u003e\u003cdiv class=\\\"d-flex w-auto\\\" id=\\\"q77:2_answer0_label\\\" data-region=\\\"answer-label\\\"\u003e\u003cspan class=\\\"answernumber\\\"\u003ea. \u003c\\/span\u003e\u003cdiv class=\\\"flex-fill ml-1\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eC4\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003c\\/div\u003e \u003c\\/div\u003e\\n\u003cdiv class=\\\"r1 partiallycorrect\\\"\u003e\u003cinput type=\\\"radio\\\" name=\\\"q77:2_answer\\\" disabled=\\\"disabled\\\" value=\\\"1\\\" id=\\\"q77:2_answer1\\\" aria-labelledby=\\\"q77:2_answer1_label\\\" checked=\\\"checked\\\" \\/\u003e\u003cdiv class=\\\"d-flex w-auto\\\" id=\\\"q77:2_answer1_label\\\" data-region=\\\"answer-label\\\"\u003e\u003cspan class=\\\"answernumber\\\"\u003eb. \u003c\\/span\u003e\u003cdiv class=\\\"flex-fill ml-1\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eC3\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003c\\/div\u003e \u003ci class=\\\"icon fa fa-check-square fa-fw \\\"  title=\\\"Partially correct\\\" role=\\\"img\\\" aria-label=\\\"Partially correct\\\"\u003e\u003c\\/i\u003e\u003cdiv class=\\\"specificfeedback\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003e\u003cem\u003eC3 feddback\u003cbr\u003e\u003c\\/em\u003e\u003c\\/div\u003e\u003c\\/div\u003e\\n\u003cdiv class=\\\"r0\\\"\u003e\u003cinput type=\\\"radio\\\" name=\\\"q77:2_answer\\\" disabled=\\\"disabled\\\" value=\\\"2\\\" id=\\\"q77:2_answer2\\\" aria-labelledby=\\\"q77:2_answer2_label\\\" \\/\u003e\u003cdiv class=\\\"d-flex w-auto\\\" id=\\\"q77:2_answer2_label\\\" data-region=\\\"answer-label\\\"\u003e\u003cspan class=\\\"answernumber\\\"\u003ec. \u003c\\/span\u003e\u003cdiv class=\\\"flex-fill ml-1\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eC2\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003c\\/div\u003e \u003c\\/div\u003e\\n\u003cdiv class=\\\"r1\\\"\u003e\u003cinput type=\\\"radio\\\" name=\\\"q77:2_answer\\\" disabled=\\\"disabled\\\" value=\\\"3\\\" id=\\\"q77:2_answer3\\\" aria-labelledby=\\\"q77:2_answer3_label\\\" \\/\u003e\u003cdiv class=\\\"d-flex w-auto\\\" id=\\\"q77:2_answer3_label\\\" data-region=\\\"answer-label\\\"\u003e\u003cspan class=\\\"answernumber\\\"\u003ed. \u003c\\/span\u003e\u003cdiv class=\\\"flex-fill ml-1\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eC1\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003c\\/div\u003e \u003c\\/div\u003e\\n\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003cdiv class=\\\"outcome clearfix\\\"\u003e\u003ch4 class=\\\"accesshide\\\"\u003eFeedback\u003c\\/h4\u003e\u003cdiv class=\\\"feedback\\\"\u003e\u003cdiv class=\\\"specificfeedback\\\"\u003eYour answer is partially correct.\u003c\\/div\u003e\u003cdiv class=\\\"generalfeedback\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eGeneral feedback\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"rightanswer\\\"\u003eThe correct answer is: \u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eC1\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\",\n\t\t\t\t\t\"sequencecheck\": 2,\n\t\t\t\t\t\"feedback\": \"\u003cdiv class=\\\"specificfeedback\\\"\u003eYour answer is partially correct.\u003c\\/div\u003e\u003cdiv class=\\\"generalfeedback\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eGeneral feedback\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"rightanswer\\\"\u003eThe correct answer is: \u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eC1\u003c\\/div\u003e\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"questionid\": 5,\n\t\t\t\t\t\"state\": \"complete\",\n\t\t\t\t\t\"mark\": null,\n\t\t\t\t\t\"status\": \"Not changed since last attempt\",\n\t\t\t\t\t\"data\": \"{\\\"choice0\\\":\\\"1\\\",\\\"choice1\\\":\\\"1\\\",\\\"choice2\\\":\\\"0\\\",\\\"choice3\\\":\\\"1\\\",\\\"_order\\\":\\\"13,12,14,11\\\"}\",\n\t\t\t\t\t\"slot\": 3,\n\t\t\t\t\t\"html\": \"\u003cdiv id=\\\"question-77-3\\\" class=\\\"que multichoice immediatefeedback answersaved\\\"\u003e\u003cdiv class=\\\"info\\\"\u003e\u003ch3 class=\\\"no\\\"\u003eQuestion \u003cspan class=\\\"qno\\\"\u003e3\u003c\\/span\u003e\u003c\\/h3\u003e\u003cdiv class=\\\"state\\\"\u003eNot changed since last attempt\u003c\\/div\u003e\u003cdiv class=\\\"grade\\\"\u003eMarked out of 5.00\u003c\\/div\u003e\u003cdiv class=\\\"questionflag editable\\\"\u003e\u003cinput type=\\\"hidden\\\" name=\\\"q77:3_:flagged\\\" value=\\\"0\\\" \\/\u003e\u003cinput type=\\\"hidden\\\" value=\\\"qaid=275\u0026amp;qubaid=77\u0026amp;qid=5\u0026amp;slot=3\u0026amp;checksum=5fc3e96a79e420b52a66575db21df023\u0026amp;sesskey=DESmM0G03Y\u0026amp;newstate=\\\" class=\\\"questionflagpostdata\\\" \\/\u003e\u003cinput type=\\\"checkbox\\\" id=\\\"q77:3_:flaggedcheckbox\\\" name=\\\"q77:3_:flagged\\\" value=\\\"1\\\" \\/\u003e\u003clabel id=\\\"q77:3_:flaggedlabel\\\" for=\\\"q77:3_:flaggedcheckbox\\\"\u003e\u003cimg src=\\\"https:\\/\\/commercetools.localhost\\/theme\\/image.php\\/boost\\/core\\/1666835649\\/i\\/unflagged\\\" alt=\\\"\\\" class=\\\"questionflagimage\\\" id=\\\"q77:3_:flaggedimg\\\" \\/\u003e\u003cspan\u003eFlag question\u003c\\/span\u003e\u003c\\/label\u003e\\n\u003c\\/div\u003e\u003c\\/div\u003e\u003cdiv class=\\\"content\\\"\u003e\u003cdiv class=\\\"formulation clearfix\\\"\u003e\u003ch4 class=\\\"accesshide\\\"\u003eQuestion text\u003c\\/h4\u003e\u003cinput type=\\\"hidden\\\" name=\\\"q77:3_:sequencecheck\\\" value=\\\"1\\\" \\/\u003e\u003cdiv class=\\\"qtext\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003etest\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"ablock no-overflow visual-scroll-x\\\"\u003e\u003cdiv class=\\\"answer\\\"\u003e\u003cdiv class=\\\"r0\\\"\u003e\u003cinput type=\\\"checkbox\\\" name=\\\"q77:3_choice0\\\" disabled=\\\"disabled\\\" value=\\\"1\\\" id=\\\"q77:3_choice0\\\" aria-labelledby=\\\"q77:3_choice0_label\\\" checked=\\\"checked\\\" \\/\u003e\u003cdiv class=\\\"d-flex w-auto\\\" id=\\\"q77:3_choice0_label\\\" data-region=\\\"answer-label\\\"\u003e\u003cspan class=\\\"answernumber\\\"\u003ea. \u003c\\/span\u003e\u003cdiv class=\\\"flex-fill ml-1\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003etest\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003c\\/div\u003e \u003c\\/div\u003e\\n\u003cdiv class=\\\"r1\\\"\u003e\u003cinput type=\\\"checkbox\\\" name=\\\"q77:3_choice1\\\" disabled=\\\"disabled\\\" value=\\\"1\\\" id=\\\"q77:3_choice1\\\" aria-labelledby=\\\"q77:3_choice1_label\\\" checked=\\\"checked\\\" \\/\u003e\u003cdiv class=\\\"d-flex w-auto\\\" id=\\\"q77:3_choice1_label\\\" data-region=\\\"answer-label\\\"\u003e\u003cspan class=\\\"answernumber\\\"\u003eb. \u003c\\/span\u003e\u003cdiv class=\\\"flex-fill ml-1\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003etest\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003c\\/div\u003e \u003c\\/div\u003e\\n\u003cdiv class=\\\"r0\\\"\u003e\u003cinput type=\\\"checkbox\\\" name=\\\"q77:3_choice2\\\" disabled=\\\"disabled\\\" value=\\\"1\\\" id=\\\"q77:3_choice2\\\" aria-labelledby=\\\"q77:3_choice2_label\\\" \\/\u003e\u003cdiv class=\\\"d-flex w-auto\\\" id=\\\"q77:3_choice2_label\\\" data-region=\\\"answer-label\\\"\u003e\u003cspan class=\\\"answernumber\\\"\u003ec. \u003c\\/span\u003e\u003cdiv class=\\\"flex-fill ml-1\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003ewrong\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003c\\/div\u003e \u003c\\/div\u003e\\n\u003cdiv class=\\\"r1\\\"\u003e\u003cinput type=\\\"checkbox\\\" name=\\\"q77:3_choice3\\\" disabled=\\\"disabled\\\" value=\\\"1\\\" id=\\\"q77:3_choice3\\\" aria-labelledby=\\\"q77:3_choice3_label\\\" checked=\\\"checked\\\" \\/\u003e\u003cdiv class=\\\"d-flex w-auto\\\" id=\\\"q77:3_choice3_label\\\" data-region=\\\"answer-label\\\"\u003e\u003cspan class=\\\"answernumber\\\"\u003ed. \u003c\\/span\u003e\u003cdiv class=\\\"flex-fill ml-1\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003etest\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003c\\/div\u003e \u003c\\/div\u003e\\n\u003c\\/div\u003e\u003c\\/div\u003e\u003cdiv class=\\\"im-controls\\\"\u003e\u003cinput type=\\\"submit\\\" id=\\\"q77:3_-submit\\\" name=\\\"q77:3_-submit\\\" value=\\\"Check\\\" class=\\\"submit btn btn-secondary\\\" disabled=\\\"disabled\\\" \\/\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\",\n\t\t\t\t\t\"sequencecheck\": 1,\n\t\t\t\t\t\"feedback\": \"\u003cdiv class=\\\"specificfeedback\\\"\u003eYour answer is correct.\u003c\\/div\u003e\u003cdiv class=\\\"numpartscorrect\\\"\u003eYou have selected too many options.\u003c\\/div\u003e\u003cdiv class=\\\"rightanswer\\\"\u003eThe correct answers are: \u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003etest, \u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003etest\u003c\\/div\u003e\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"questionid\": 4,\n\t\t\t\t\t\"state\": \"complete\",\n\t\t\t\t\t\"mark\": null,\n\t\t\t\t\t\"status\": \"Not changed since last attempt\",\n\t\t\t\t\t\"data\": \"{\\\"answer\\\":\\\"correct\\\"}\",\n\t\t\t\t\t\"slot\": 4,\n\t\t\t\t\t\"html\": \"\u003cdiv id=\\\"question-77-4\\\" class=\\\"que shortanswer immediatefeedback answersaved\\\"\u003e\u003cdiv class=\\\"info\\\"\u003e\u003ch3 class=\\\"no\\\"\u003eQuestion \u003cspan class=\\\"qno\\\"\u003e4\u003c\\/span\u003e\u003c\\/h3\u003e\u003cdiv class=\\\"state\\\"\u003eNot changed since last attempt\u003c\\/div\u003e\u003cdiv class=\\\"grade\\\"\u003eMarked out of 1.00\u003c\\/div\u003e\u003cdiv class=\\\"questionflag editable\\\"\u003e\u003cinput type=\\\"hidden\\\" name=\\\"q77:4_:flagged\\\" value=\\\"0\\\" \\/\u003e\u003cinput type=\\\"hidden\\\" value=\\\"qaid=276\u0026amp;qubaid=77\u0026amp;qid=4\u0026amp;slot=4\u0026amp;checksum=7b1781bf6a5fdf40c5e004d4e797afc6\u0026amp;sesskey=DESmM0G03Y\u0026amp;newstate=\\\" class=\\\"questionflagpostdata\\\" \\/\u003e\u003cinput type=\\\"checkbox\\\" id=\\\"q77:4_:flaggedcheckbox\\\" name=\\\"q77:4_:flagged\\\" value=\\\"1\\\" \\/\u003e\u003clabel id=\\\"q77:4_:flaggedlabel\\\" for=\\\"q77:4_:flaggedcheckbox\\\"\u003e\u003cimg src=\\\"https:\\/\\/commercetools.localhost\\/theme\\/image.php\\/boost\\/core\\/1666835649\\/i\\/unflagged\\\" alt=\\\"\\\" class=\\\"questionflagimage\\\" id=\\\"q77:4_:flaggedimg\\\" \\/\u003e\u003cspan\u003eFlag question\u003c\\/span\u003e\u003c\\/label\u003e\\n\u003c\\/div\u003e\u003c\\/div\u003e\u003cdiv class=\\\"content\\\"\u003e\u003cdiv class=\\\"formulation clearfix\\\"\u003e\u003ch4 class=\\\"accesshide\\\"\u003eQuestion text\u003c\\/h4\u003e\u003cinput type=\\\"hidden\\\" name=\\\"q77:4_:sequencecheck\\\" value=\\\"1\\\" \\/\u003e\u003cdiv class=\\\"qtext\\\"\u003e\u003cp dir=\\\"ltr\\\" style=\\\"text-align: left;\\\"\u003eShort answer\u003cbr\u003e\u003c\\/p\u003e\u003c\\/div\u003e\u003cdiv class=\\\"ablock form-inline\\\"\u003e\u003clabel for=\\\"q77:4_answer\\\"\u003eAnswer: \u003cspan class=\\\"answer\\\"\u003e\u003cinput type=\\\"text\\\" name=\\\"q77:4_answer\\\" value=\\\"correct\\\" id=\\\"q77:4_answer\\\" size=\\\"80\\\" class=\\\"form-control d-inline\\\" readonly=\\\"readonly\\\" \\/\u003e\u003c\\/span\u003e\u003c\\/label\u003e\u003c\\/div\u003e\u003cdiv class=\\\"im-controls\\\"\u003e\u003cinput type=\\\"submit\\\" id=\\\"q77:4_-submit\\\" name=\\\"q77:4_-submit\\\" value=\\\"Check\\\" class=\\\"submit btn btn-secondary\\\" disabled=\\\"disabled\\\" \\/\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\u003c\\/div\u003e\",\n\t\t\t\t\t\"sequencecheck\": 1,\n\t\t\t\t\t\"feedback\": \"\u003cdiv class=\\\"rightanswer\\\"\u003eThe correct answer is: correct\u003c\\/div\u003e\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t}\n}\n```\n\u003c/details\u003e\n\n\n### Behaviour\nWhen the function is called the following happens:\n- If no attempt exists for the user, a new attempt is started\n- If an attempt exists for the user, the attempt is returned\n\nA new attempt can be 'forced' by passing the URL query paramter `forcenew=1`, which will create a new attempt and finish any existing previous attempts that are `inprogress`\n\n![attempt flow](pix/attemptflow.png)\n\n### Calling function relative to a user\nThe function is called relative to the $USER attached to the webservice token. To call this function for abitrary users, a plugin such as [tool_token](https://github.com/catalyst/moodle-tool_token) can be used.\n\nFor example, you can use tool_token to get a token for the user with username `testuser` with the following call:\n\n`/webservice/rest/server.php?wstoken=2bc3138a0323283f481313f5caa6bf3c\u0026wsfunction=tool_token_get_token\u0026moodlewsrestformat=json\u0026idtype=username\u0026idvalue=testuser\u0026service=moodle_mobile_app` \n\nThis returns:\n\n`{\"userid\":18,\"token\":\"3a8de124dd5a142be6a5cc2ae838231a\",\"validuntil\":0}`\n\nIt is then possible to call the headless quiz API using this token:\n\n`/webservice/rest/server.php?wstoken=3a8de124dd5a142be6a5cc2ae838231a\u0026wsfunction=local_headlessquiz_get_attempt\u0026cmid=[CMID]\u0026moodlewsrestformat=json`\n\nThis will call the `local_headlessquiz_get_attempt` relative to the user attached to the token, `testuser`.\n\n## Limitations\n1. Only single page quizzes are supported\n2. Only a subset of question types are supported: `shortanswer`, `truefalse`, `multichoice`, `random`\n3. Only plain question text is supported. For e.g. pluginfiles are not supported.\n\n### Note for `qtype_random`\nIf using the random qtype, you must ensure all questions that it links to (via the selected category) are also of the supported question types and do not contain any non-plain question text.\n\nThis also includes questions in a category that have been 'deleted' but are still used elsewhere - these appear greyed out when `Also show old questions` is selected in the category editor. \n\nTo fix this, use a new category or remove all usages of the question.\n## Branches\n\n| Version   | Branch            |\n|-----------|-------------------|\n| 4.3 - 4.4 | MOODLE_403_STABLE |\n| 4.2 - 4.2 | MOODLE_402_STABLE |\n| 4.0 - 4.1 | MOODLE_400_STABLE |\n\n## Installation\n\nClone the code to your Moodle installation\n\n`git clone git@github.com:catalyst/moodle-local_headlessquiz.git local/headlessquiz`\n\nRun the Moodle upgrade script to install the plugin\n\n`php admin/cli/upgrade.php`\n\n## Contributing and Support\nIssues, and pull requests using github are welcome and encouraged!\n\nIf you would like commercial support or would like to sponsor additional improvements to this plugin please contact us:\n\nhttps://www.catalyst-au.net/contact-us\n\n\n# Credits\n\nThis plugin was developed by Catalyst IT Australia:\n\nhttps://www.catalyst-au.net/\n\n\u003cimg alt=\"Catalyst IT\" src=\"https://cdn.rawgit.com/CatalystIT-AU/moodle-auth_saml2/MOODLE_39_STABLE/pix/catalyst-logo.svg\" width=\"400\"\u003e\n\nWith funding provided by Commerce Tools:\n\nhttps://commercetools.com/\n\n![Commerce Tools](pix/commercetools.png)\n\n## License\nThis program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatalyst%2Fmoodle-local_headlessquiz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcatalyst%2Fmoodle-local_headlessquiz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatalyst%2Fmoodle-local_headlessquiz/lists"}