diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a09c56d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/.idea
diff --git a/icon.svg b/icon.svg
new file mode 100644
index 0000000..8c30b9e
--- /dev/null
+++ b/icon.svg
@@ -0,0 +1,18 @@
+
diff --git a/index.css b/index.css
new file mode 100644
index 0000000..e69de29
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..75ee3c8
--- /dev/null
+++ b/index.html
@@ -0,0 +1,29 @@
+
+
+
+ ').html(guidance)
+ guidanceContainer.append(guidanceText)
+ guidanceBlock.append(guidanceContainer)
+ }
+ }
+
+ const renderResult = () => {
+ // todo render result
+ }
+
+ const getAssessmentState = () => {
+ const result = currentData ? currentData.result : null
+ const answered = result?.state && result?.state !== window.codioAssessmentsHelper.States.RESET
+ const usedAttempts = result?.usedAttempts || 0
+ const canAnswerAgain = !assessment.source.maxAttemptsCount || usedAttempts < assessment.source.maxAttemptsCount
+ const showModify = assessmentOptions.showUnblock && (!answered || canAnswerAgain)
+ const isDisabled = processing ||
+ assessmentOptions.isDisabled ||
+ result?.state === window.codioAssessmentsHelper.States.PROGRESS ||
+ answered && !canAnswerAgain
+ const teacherInStudentsProject = assessmentOptions.showAsTeacher && !assessmentOptions.owner
+
+ return {
+ isDisabled,
+ answered,
+ usedAttempts,
+ canAnswerAgain,
+ showModify,
+ teacherInStudentsProject
+ }
+ }
+
+ const updateHtml = () => {
+ if (!assessment) {
+ return
+ }
+ // processing, new state/results
+ const assessmentState = getAssessmentState()
+ $('.check-button').attr('disabled', assessmentState.isDisabled)
+ const blockActionsEl = $('.block-actions')
+ assessmentState.isDisabled ? blockActionsEl.removeClass('hide') : blockActionsEl.addClass('hide')
+
+ updateFooterButtons()
+ }
+
+ const bindEvents = () => {
+ $('.check-button').on('click', onCheck)
+ $('.unblock-button').on('click', onUnblock)
+ $('.reset-button').on('click', onReset)
+
+ window.codioAssessmentsHelper.addBodyHeightListener()
+ }
+
+ const render = () => {
+ const container = $('.codio-assessment')
+ const nameEl = container.find('.codio-assessment-name')
+ assessment.source.showName ? nameEl.text(assessment.source.name) : nameEl.remove()
+ renderContent()
+ renderFooter()
+ renderGuidance()
+ renderResult()
+ updateHtml()
+ bindEvents()
+ container.removeClass('hide')
+ }
+
+ const processMessage = (jsonData) => {
+ try {
+ const {method, data} = JSON.parse(jsonData)
+ console.log('assessment iframe processMessage', jsonData, method, data)
+ switch (method) {
+ case window.codioAssessmentsHelper.METHODS.GET_STYLES_RESPONSE:
+ window.codioAssessmentsHelper.addStyle(data.css)
+ break
+ case window.codioAssessmentsHelper.METHODS.GET_STATE_RESPONSE:
+ updateProcessing(false)
+ applyState(data)
+ break
+ case window.codioAssessmentsHelper.METHODS.CALLBACK: {
+ window.codioAssessmentsHelper.processCallback(data)
+ break
+ }
+ }
+ } catch {}
+ }
+
+ window.addEventListener('load', () => {
+ window.codioAssessmentsHelper.registerMessageListener(processMessage)
+ window.codioAssessmentsHelper.send(window.codioAssessmentsHelper.METHODS.GET_STATE)
+ window.codioAssessmentsHelper.send(window.codioAssessmentsHelper.METHODS.GET_STYLES)
+ })
+})()
diff --git a/metadata.json b/metadata.json
new file mode 100644
index 0000000..16127b9
--- /dev/null
+++ b/metadata.json
@@ -0,0 +1,12 @@
+{
+ "name": "Standard Code Test",
+ "type": "assessment",
+ "properties": {
+ "type": "code-output-compare",
+ "icon": "./icon.svg",
+ "defaultHeight": 500,
+ "gradingControls": {
+
+ }
+ }
+}
diff --git a/settings.css b/settings.css
new file mode 100644
index 0000000..3d6e420
--- /dev/null
+++ b/settings.css
@@ -0,0 +1,5 @@
+.settings-commands {
+ display: flex;
+ flex-direction: row;
+ gap: 10px;
+}
diff --git a/settings.html b/settings.html
new file mode 100644
index 0000000..84c7e3f
--- /dev/null
+++ b/settings.html
@@ -0,0 +1,34 @@
+
+
+
+
+
Settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/settings.js b/settings.js
new file mode 100644
index 0000000..35e6b74
--- /dev/null
+++ b/settings.js
@@ -0,0 +1,44 @@
+(function () {
+ const collectSettings = () => {
+ const instructions = $('#instructions').val()
+ const command = $('#command').val();
+ const preExecCommand = $('#preExecCommand').val();
+ const timeout = parseInt($('#timeout').val(), 10);
+
+ return {instructions, command, preExecCommand, timeout};
+ }
+
+ const exportSettings = () => {
+ const data = collectSettings();
+ window.codioAssessmentsHelper.send(window.codioAssessmentsHelper.METHODS.EXPORT_SETTINGS_RESPONSE, data);
+ }
+
+ const applySettings = (settings = {}) => {
+ $('#instructions').val(settings.instructions || '');
+ $('#command').val(settings.command || '');
+ $('#preExecCommand').val(settings.preExecCommand || '');
+ $('#timeout').val(settings.timeout || '');
+ }
+
+ const processMessage = (jsonData) => {
+ console.log('settings iframe processMessage', jsonData)
+ try {
+ const {method, data} = JSON.parse(jsonData);
+ switch (method) {
+ case window.codioAssessmentsHelper.METHODS.EXPORT_SETTINGS:
+ exportSettings();
+ break;
+ case window.codioAssessmentsHelper.METHODS.GET_SETTINGS_RESPONSE:
+ applySettings(data.settings);
+ break;
+ }
+ } catch {}
+ }
+
+ const onLoad = async () => {
+ window.codioAssessmentsHelper.registerMessageListener(processMessage)
+ window.codioAssessmentsHelper.send(window.codioAssessmentsHelper.METHODS.GET_SETTINGS)
+ }
+
+ window.addEventListener('load', onLoad);
+})()