@pie-element/image-cloze-association 3.5.0 → 3.5.1-beta.587

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +478 -0
  2. package/configure/CHANGELOG.md +390 -0
  3. package/configure/lib/defaults.js +16 -0
  4. package/configure/lib/defaults.js.map +1 -1
  5. package/configure/lib/index.js +17 -3
  6. package/configure/lib/index.js.map +1 -1
  7. package/configure/lib/root.js +43 -13
  8. package/configure/lib/root.js.map +1 -1
  9. package/configure/package.json +4 -3
  10. package/configure/src/__tests__/index.test.js +12 -15
  11. package/configure/src/defaults.js +20 -4
  12. package/configure/src/index.js +23 -3
  13. package/configure/src/root.jsx +41 -25
  14. package/controller/CHANGELOG.md +63 -0
  15. package/controller/lib/index.js +9 -8
  16. package/controller/lib/index.js.map +1 -1
  17. package/controller/lib/utils.js +4 -4
  18. package/controller/lib/utils.js.map +1 -1
  19. package/controller/package.json +2 -2
  20. package/controller/src/__tests__/index.test.js +108 -62
  21. package/controller/src/index.js +40 -28
  22. package/controller/src/utils.js +10 -10
  23. package/docs/config-schema.json +160 -0
  24. package/docs/config-schema.json.md +127 -0
  25. package/docs/demo/config.js +2 -2
  26. package/docs/demo/generate.js +30 -25
  27. package/docs/demo/session.js +1 -1
  28. package/docs/pie-schema.json +378 -0
  29. package/docs/pie-schema.json.md +295 -0
  30. package/lib/constants.js.map +1 -1
  31. package/lib/evaluation-icon.js.map +1 -1
  32. package/lib/image-container.js +13 -6
  33. package/lib/image-container.js.map +1 -1
  34. package/lib/image-drop-target.js +7 -2
  35. package/lib/image-drop-target.js.map +1 -1
  36. package/lib/index.js +4 -1
  37. package/lib/index.js.map +1 -1
  38. package/lib/interactive-section.js +1 -1
  39. package/lib/interactive-section.js.map +1 -1
  40. package/lib/possible-response.js +17 -5
  41. package/lib/possible-response.js.map +1 -1
  42. package/lib/possible-responses.js.map +1 -1
  43. package/lib/root.js +140 -19
  44. package/lib/root.js.map +1 -1
  45. package/lib/utils-correctness.js +33 -5
  46. package/lib/utils-correctness.js.map +1 -1
  47. package/package.json +8 -5
  48. package/src/__tests__/__snapshots__/{image-container-test.jsx.snap → image-container.test.jsx.snap} +20 -0
  49. package/src/__tests__/__snapshots__/possible-response.test.jsx.snap +5 -0
  50. package/src/__tests__/__snapshots__/root.test.jsx.snap +50 -0
  51. package/src/__tests__/{image-container-test.jsx → image-container.test.jsx} +12 -5
  52. package/src/__tests__/{possible-response-test.jsx → possible-response.test.jsx} +5 -3
  53. package/src/__tests__/{root-test.jsx → root.test.jsx} +4 -3
  54. package/src/__tests__/utils.test.js +207 -0
  55. package/src/constants.js +3 -3
  56. package/src/evaluation-icon.jsx +8 -17
  57. package/src/image-container.jsx +14 -19
  58. package/src/image-drop-target.jsx +45 -38
  59. package/src/index.js +10 -18
  60. package/src/interactive-section.jsx +15 -22
  61. package/src/possible-response.jsx +43 -23
  62. package/src/possible-responses.jsx +17 -25
  63. package/src/root.jsx +174 -100
  64. package/src/utils-correctness.js +44 -14
  65. package/src/__tests__/__snapshots__/possible-response-test.jsx.snap +0 -13
  66. package/src/__tests__/__snapshots__/root-test.jsx.snap +0 -38
  67. package/src/__tests__/utils-test.js +0 -211
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@pie-element/image-cloze-association-configure",
3
3
  "private": true,
4
- "version": "3.1.23",
4
+ "version": "4.4.0",
5
5
  "description": "",
6
6
  "main": "lib/index.js",
7
7
  "module": "src/index.js",
8
8
  "author": "",
9
9
  "dependencies": {
10
10
  "@material-ui/core": "^3.9.2",
11
- "@pie-framework/pie-configure-events": "^1.2.0",
12
- "@pie-lib/config-ui": "^10.8.57",
11
+ "@pie-framework/pie-configure-events": "^1.3.0",
12
+ "@pie-lib/config-ui": "12.0.0-beta.3",
13
+ "@pie-lib/editable-html": "10.0.0-beta.4",
13
14
  "debug": "^3.1.0",
14
15
  "prop-types": "^15.7.2",
15
16
  "react": "^16.8.6",
@@ -5,27 +5,26 @@ import * as React from 'react';
5
5
  import defaultValues from '../defaults';
6
6
  import { Root } from '../root';
7
7
 
8
-
9
8
  jest.mock('react-dom', () => ({
10
- render: jest.fn()
9
+ render: jest.fn(),
11
10
  }));
12
11
 
13
12
  jest.mock('@pie-lib/config-ui', () => ({
14
- FeedbackConfig: props => (<div/>),
15
- InputCheckbox: props => (<div/>),
13
+ FeedbackConfig: (props) => <div />,
14
+ InputCheckbox: (props) => <div />,
16
15
  layout: {
17
- ConfigLayout: props => <div>{props.children}</div>
16
+ ConfigLayout: (props) => <div>{props.children}</div>,
18
17
  },
19
18
  settings: {
20
- Panel: props => <div onChange={props.onChange} />,
19
+ Panel: (props) => <div onChange={props.onChange} />,
21
20
  toggle: jest.fn(),
22
- }
21
+ },
23
22
  }));
24
23
 
25
24
  export const defaultProps = {
26
25
  classes: {},
27
26
  model: {},
28
- configuration: defaultValues.configuration
27
+ configuration: defaultValues.configuration,
29
28
  };
30
29
 
31
30
  describe('Root', () => {
@@ -33,13 +32,13 @@ describe('Root', () => {
33
32
  let component;
34
33
 
35
34
  beforeEach(() => {
36
- wrapper = props => {
35
+ wrapper = (props) => {
37
36
  const configProps = {
38
37
  ...defaultProps,
39
- ...props
38
+ ...props,
40
39
  };
41
40
 
42
- return shallow(<Root { ...configProps } />);
41
+ return shallow(<Root {...configProps} />);
43
42
  };
44
43
  });
45
44
 
@@ -51,14 +50,12 @@ describe('Root', () => {
51
50
  let onModelChanged = jest.fn();
52
51
 
53
52
  component = wrapper({
54
- onModelChanged
53
+ onModelChanged,
55
54
  });
56
55
 
57
56
  component.instance().onTeacherInstructionsChanged('New Teacher Instructions');
58
57
 
59
- expect(onModelChanged).toBeCalledWith(
60
- expect.objectContaining({ teacherInstructions: 'New Teacher Instructions' })
61
- );
58
+ expect(onModelChanged).toBeCalledWith(expect.objectContaining({ teacherInstructions: 'New Teacher Instructions' }));
62
59
  });
63
60
  });
64
61
 
@@ -2,12 +2,28 @@ export default {
2
2
  model: {
3
3
  rationaleEnabled: true,
4
4
  teacherInstructionsEnabled: true,
5
- studentInstructionsEnabled: true
5
+ studentInstructionsEnabled: true,
6
6
  },
7
7
  configuration: {
8
+ maxImageWidth: {
9
+ teacherInstructions: 300,
10
+ },
11
+ maxImageHeight: {
12
+ teacherInstructions: 300,
13
+ },
14
+ settingsPanelDisabled: false,
15
+ spellCheck: {
16
+ label: 'Spellcheck',
17
+ settings: false,
18
+ enabled: true,
19
+ },
8
20
  teacherInstructions: {
9
21
  settings: true,
10
- label: 'Teacher Instructions'
11
- }
12
- }
22
+ label: 'Teacher Instructions',
23
+ },
24
+ withRubric: {
25
+ settings: false,
26
+ label: 'Add Rubric',
27
+ },
28
+ },
13
29
  };
@@ -1,4 +1,10 @@
1
- import { DeleteImageEvent, InsertImageEvent, ModelUpdatedEvent } from '@pie-framework/pie-configure-events';
1
+ import {
2
+ ModelUpdatedEvent,
3
+ DeleteImageEvent,
4
+ InsertImageEvent,
5
+ InsertSoundEvent,
6
+ DeleteSoundEvent,
7
+ } from '@pie-framework/pie-configure-events';
2
8
 
3
9
  import React from 'react';
4
10
  import ReactDOM from 'react-dom';
@@ -66,8 +72,17 @@ export default class ImageClozeAssociationConfigure extends HTMLElement {
66
72
  this.dispatchEvent(new DeleteImageEvent(src, done));
67
73
  }
68
74
 
75
+ insertSound(handler) {
76
+ this.dispatchEvent(new InsertSoundEvent(handler));
77
+ }
78
+
79
+ onDeleteSound(src, done) {
80
+ this.dispatchEvent(new DeleteSoundEvent(src, done));
81
+ }
82
+
69
83
  _render() {
70
84
  log('_render');
85
+
71
86
  let element = React.createElement(Root, {
72
87
  disableSidePanel: this._disableSidePanel,
73
88
  model: this._model,
@@ -76,9 +91,14 @@ export default class ImageClozeAssociationConfigure extends HTMLElement {
76
91
  onConfigurationChanged: this.onConfigurationChanged.bind(this),
77
92
  imageSupport: {
78
93
  add: this.insertImage.bind(this),
79
- delete: this.onDeleteImage.bind(this)
80
- }
94
+ delete: this.onDeleteImage.bind(this),
95
+ },
96
+ uploadSoundSupport: {
97
+ add: this.insertSound.bind(this),
98
+ delete: this.onDeleteSound.bind(this),
99
+ },
81
100
  });
101
+
82
102
  ReactDOM.render(element, this);
83
103
  }
84
104
  }
@@ -1,39 +1,46 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { withStyles } from '@material-ui/core/styles';
4
- import {
5
- settings,
6
- layout,
7
- InputContainer
8
- } from '@pie-lib/config-ui';
3
+ import { settings, layout, InputContainer } from '@pie-lib/config-ui';
9
4
  import EditableHtml from '@pie-lib/editable-html';
5
+ import { withStyles } from '@material-ui/core/styles';
10
6
 
11
7
  const { Panel, toggle } = settings;
12
8
 
13
9
  export class Root extends React.Component {
14
- onTeacherInstructionsChanged = teacherInstructions => {
15
- this.props.onModelChanged({
16
- ...this.props.model,
17
- teacherInstructions
18
- });
10
+ onTeacherInstructionsChanged = (teacherInstructions) => {
11
+ this.props.onModelChanged({ ...this.props.model, teacherInstructions });
19
12
  };
20
13
 
21
14
  render() {
22
- const { classes, model, configuration, onModelChanged, onConfigurationChanged, imageSupport } = this.props;
23
- const { teacherInstructions = {} } = configuration || {};
15
+ const { classes, model, configuration, onModelChanged, onConfigurationChanged, imageSupport, uploadSoundSupport } =
16
+ this.props;
17
+ const {
18
+ maxImageWidth = {},
19
+ maxImageHeight = {},
20
+ settingsPanelDisabled,
21
+ spellCheck = {},
22
+ teacherInstructions = {},
23
+ withRubric = {},
24
+ } = configuration || {};
25
+ const { spellCheckEnabled } = model || {};
26
+
27
+ const panelProperties = {
28
+ teacherInstructionsEnabled: teacherInstructions.settings && toggle(teacherInstructions.label),
29
+ spellCheckEnabled: spellCheck.settings && toggle(spellCheck.label),
30
+ rubricEnabled: withRubric?.settings && toggle(withRubric?.label),
31
+ };
24
32
 
25
33
  return (
26
34
  <layout.ConfigLayout
35
+ hideSettings={settingsPanelDisabled}
27
36
  settings={
28
37
  <Panel
29
38
  model={model}
30
39
  configuration={configuration}
31
- onChangeModel={model => onModelChanged(model)}
32
- onChangeConfiguration={config => onConfigurationChanged(config)}
40
+ onChangeModel={(model) => onModelChanged(model)}
41
+ onChangeConfiguration={(config) => onConfigurationChanged(config)}
33
42
  groups={{
34
- 'Properties': {
35
- teacherInstructionsEnabled: teacherInstructions.settings && toggle(teacherInstructions.label),
36
- },
43
+ Properties: panelProperties,
37
44
  }}
38
45
  />
39
46
  }
@@ -47,28 +54,33 @@ export class Root extends React.Component {
47
54
  onChange={this.onTeacherInstructionsChanged}
48
55
  imageSupport={imageSupport}
49
56
  nonEmpty={false}
57
+ spellCheck={spellCheckEnabled}
58
+ maxImageWidth={maxImageWidth && maxImageWidth.teacherInstructions}
59
+ maxImageHeight={maxImageHeight && maxImageHeight.teacherInstructions}
60
+ uploadSoundSupport={uploadSoundSupport}
61
+ languageCharactersProps={[{ language: 'spanish' }, { language: 'special' }]}
50
62
  />
51
63
  </InputContainer>
52
64
  )}
53
65
 
54
- Image cloze association
66
+ <div>Image cloze association</div>
55
67
  </div>
56
68
  </layout.ConfigLayout>
57
69
  );
58
70
  }
59
71
  }
60
72
 
61
- const styles = theme => ({
73
+ const styles = (theme) => ({
62
74
  base: {
63
- marginTop: theme.spacing.unit * 3
75
+ marginTop: theme.spacing.unit * 3,
64
76
  },
65
77
  promptHolder: {
66
78
  width: '100%',
67
- paddingTop: theme.spacing.unit * 2
79
+ paddingTop: theme.spacing.unit * 2,
68
80
  },
69
81
  prompt: {
70
82
  paddingTop: theme.spacing.unit * 2,
71
- width: '100%'
83
+ width: '100%',
72
84
  },
73
85
  });
74
86
 
@@ -80,8 +92,12 @@ Root.propTypes = {
80
92
  configuration: PropTypes.object.isRequired,
81
93
  imageSupport: PropTypes.shape({
82
94
  add: PropTypes.func.isRequired,
83
- delete: PropTypes.func.isRequired
84
- })
95
+ delete: PropTypes.func.isRequired,
96
+ }),
97
+ uploadSoundSupport: PropTypes.shape({
98
+ add: PropTypes.func.isRequired,
99
+ delete: PropTypes.func.isRequired,
100
+ }),
85
101
  };
86
102
 
87
103
  export default withStyles(styles)(Root);
@@ -3,6 +3,69 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.2.23](https://github.com/pie-framework/pie-elements/compare/@pie-element/image-cloze-association-controller@3.2.22...@pie-element/image-cloze-association-controller@3.2.23) (2022-12-07)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * update libs ([441f403](https://github.com/pie-framework/pie-elements/commit/441f403870b7bec0d61fab58b8d93dbe0ead4c32))
12
+
13
+
14
+
15
+
16
+
17
+ ## [3.2.19](https://github.com/pie-framework/pie-elements/compare/@pie-element/image-cloze-association-controller@3.2.17...@pie-element/image-cloze-association-controller@3.2.19) (2021-11-11)
18
+
19
+ **Note:** Version bump only for package @pie-element/image-cloze-association-controller
20
+
21
+
22
+
23
+
24
+
25
+ ## [3.2.18](https://github.com/pie-framework/pie-elements/compare/@pie-element/image-cloze-association-controller@3.2.16...@pie-element/image-cloze-association-controller@3.2.18) (2021-11-11)
26
+
27
+
28
+ ### Bug Fixes
29
+
30
+ * **image-cloze-association:** Fixed scoring method console errors PD-1249 ([1484c63](https://github.com/pie-framework/pie-elements/commit/1484c6354d59afcc0b541232c70ddfc5869ecfee))
31
+
32
+
33
+
34
+
35
+
36
+ ## [3.2.17](https://github.com/pie-framework/pie-elements/compare/@pie-element/image-cloze-association-controller@3.2.16...@pie-element/image-cloze-association-controller@3.2.17) (2021-08-05)
37
+
38
+
39
+ ### Bug Fixes
40
+
41
+ * **image-cloze-association:** Fixed scoring method console errors PD-1249 ([1484c63](https://github.com/pie-framework/pie-elements/commit/1484c6354d59afcc0b541232c70ddfc5869ecfee))
42
+
43
+
44
+
45
+
46
+
47
+ ## [3.2.16](https://github.com/pie-framework/pie-elements/compare/@pie-element/image-cloze-association-controller@3.2.14...@pie-element/image-cloze-association-controller@3.2.16) (2021-08-05)
48
+
49
+
50
+ ### Bug Fixes
51
+
52
+ * force bump ([5ea7295](https://github.com/pie-framework/pie-elements/commit/5ea7295e4755fbc492a76e7ec69e5fc35b196919))
53
+
54
+
55
+
56
+
57
+
58
+ ## [3.2.14](https://github.com/pie-framework/pie-elements/compare/@pie-element/image-cloze-association-controller@3.2.13...@pie-element/image-cloze-association-controller@3.2.14) (2021-06-29)
59
+
60
+
61
+ ### Bug Fixes
62
+
63
+ * image-cloze-association create schemas for PD-1095 ([#562](https://github.com/pie-framework/pie-elements/issues/562)) ([d2e39da](https://github.com/pie-framework/pie-elements/commit/d2e39da045f594938239f1a25ac9786bdaffa6d9))
64
+
65
+
66
+
67
+
68
+
6
69
  ## [3.2.13](https://github.com/pie-framework/pie-elements/compare/@pie-element/image-cloze-association-controller@3.2.10...@pie-element/image-cloze-association-controller@3.2.13) (2021-03-03)
7
70
 
8
71
  **Note:** Version bump only for package @pie-element/image-cloze-association-controller
@@ -5,9 +5,10 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
+ exports.isResponseCorrect = exports.getPartialScore = exports.createCorrectResponseSession = void 0;
8
9
  exports.model = model;
10
+ exports.normalize = void 0;
9
11
  exports.outcome = outcome;
10
- exports.createCorrectResponseSession = exports.getPartialScore = exports.isResponseCorrect = exports.normalize = void 0;
11
12
 
12
13
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
14
 
@@ -21,9 +22,9 @@ var _controllerUtils = require("@pie-lib/controller-utils");
21
22
 
22
23
  var _utils = require("./utils");
23
24
 
24
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
25
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
25
26
 
26
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
27
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
27
28
 
28
29
  var log = (0, _debug["default"])('pie-elements:image-cloze-association:controller');
29
30
 
@@ -67,12 +68,12 @@ var isResponseCorrect = function isResponseCorrect(responses, session) {
67
68
  }
68
69
 
69
70
  responses.forEach(function (value) {
70
- return totalValidResponses += value.length;
71
+ return totalValidResponses += (value.images || []).length;
71
72
  });
72
73
 
73
74
  if (session.answers && totalValidResponses === session.answers.length) {
74
75
  session.answers.forEach(function (answer) {
75
- if (!responses[answer.containerIndex].includes(answer.value)) {
76
+ if (!(responses[answer.containerIndex].images || []).includes(answer.value)) {
76
77
  isCorrect = false;
77
78
  }
78
79
  });
@@ -111,7 +112,7 @@ var getDeductionPerContainer = function getDeductionPerContainer(containerIndex,
111
112
  var incorrectStack = totalStack.filter(function (item) {
112
113
  return !item.isCorrect;
113
114
  });
114
- var maxValid = valid.value[containerIndex].length;
115
+ var maxValid = (valid.value[containerIndex].images || []).length;
115
116
 
116
117
  if (totalStack.length > maxValid) {
117
118
  var ignored = totalStack.length - maxValid;
@@ -133,7 +134,7 @@ var getPartialScore = function getPartialScore(question, session) {
133
134
  }
134
135
 
135
136
  validResponse.value.forEach(function (value) {
136
- return possibleResponses += value.length;
137
+ return possibleResponses += (value.images || []).length;
137
138
  });
138
139
 
139
140
  if (session.answers && session.answers.length) {
@@ -208,7 +209,7 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
208
209
 
209
210
  if (value) {
210
211
  value.forEach(function (container, i) {
211
- container.forEach(function (v) {
212
+ (container.images || []).forEach(function (v) {
212
213
  answers.push({
213
214
  value: v,
214
215
  containerIndex: i
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","model","session","env","questionNormalized","questionCamelized","Promise","resolve","out","disabled","mode","responseCorrect","getScore","undefined","role","teacherInstructions","isResponseCorrect","responses","isCorrect","totalValidResponses","forEach","value","length","answers","answer","containerIndex","includes","isDefaultOrAltResponseCorrect","validation","validResponse","altResponses","altResponse","getDeductionPerContainer","valid","totalStack","filter","item","incorrectStack","maxValid","ignored","slice","getPartialScore","maxResponsePerZone","responseContainers","correctAnswers","possibleResponses","all","deductionList","id","denominator","str","toFixed","parseFloat","config","isPartialScoring","partialScoring","enabled","correct","outcome","score","empty","configCamelized","createCorrectResponseSession","valid_response","container","i","v","push"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport { camelizeKeys } from 'humps';\nimport { partialScoring } from '@pie-lib/controller-utils';\n\nimport { getAllUniqueCorrectness } from './utils';\n\nconst log = debug('pie-elements:image-cloze-association:controller');\n\nexport const normalize = question => ({\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n});\n\nexport function model(question, session, env) {\n const questionNormalized = normalize(question);\n const questionCamelized = camelizeKeys(questionNormalized);\n\n return new Promise(resolve => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n ...questionCamelized,\n responseCorrect:\n env.mode === 'evaluate'\n ? getScore(questionCamelized, session) === 1\n : undefined,\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = questionCamelized.teacherInstructionsEnabled ? questionCamelized.teacherInstructions : null;\n } else {\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nexport const isResponseCorrect = (responses, session) => {\n let isCorrect = true;\n let totalValidResponses = 0;\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n responses.forEach(value => totalValidResponses += value.length);\n\n if (session.answers && totalValidResponses === session.answers.length) {\n session.answers.forEach(answer => {\n if (!responses[answer.containerIndex].includes(answer.value)) {\n isCorrect = false;\n }\n });\n } else {\n isCorrect = false;\n }\n return isCorrect;\n};\n\n// This applies for items that don't support partial scoring.\nconst isDefaultOrAltResponseCorrect = (question, session) => {\n const { validation: { validResponse: { value }, altResponses } } = question;\n\n let isCorrect = isResponseCorrect(value, session);\n\n // Look for correct answers in alternate responses.\n if (!isCorrect && (altResponses && altResponses.length)) {\n altResponses.forEach(altResponse => {\n if (isResponseCorrect(altResponse.value, session)) {\n isCorrect = true;\n }\n });\n }\n return isCorrect;\n};\n\n// Deduct only the items that exceeded the maximum valid response per container.\nconst getDeductionPerContainer = (containerIndex, answers, valid) => {\n const totalStack = answers.filter(item => item.containerIndex === containerIndex);\n const incorrectStack = totalStack.filter(item => !item.isCorrect);\n const maxValid = valid.value[containerIndex].length;\n\n if (totalStack.length > maxValid) {\n const ignored = totalStack.length - maxValid;\n return incorrectStack.slice(-ignored);\n }\n return [];\n};\n\nexport const getPartialScore = (question, session) => {\n const { validation: { validResponse }, maxResponsePerZone, responseContainers } = question;\n let correctAnswers = 0;\n let possibleResponses = 0;\n\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n validResponse.value.forEach(value => possibleResponses += value.length);\n\n if (session.answers && session.answers.length) {\n const all = getAllUniqueCorrectness(session.answers, validResponse.value);\n correctAnswers = all.filter(item => item.isCorrect).length;\n\n // deduction rules: https://docs.google.com/document/d/1Oprm8Qs5fg_Dwoj2pNpsfu4D63QgCZgvcqTgeaVel7I/edit\n session.answers.forEach(answer => {\n if (maxResponsePerZone > 1) {\n const deductionList = getDeductionPerContainer(answer.containerIndex, all, validResponse);\n\n if (deductionList.length) {\n deductionList.forEach(item => {\n if (item.id === answer.id) {\n correctAnswers -= 1;\n }\n });\n }\n }\n });\n } else {\n correctAnswers = 0;\n }\n // negative values will implicitly make the score equal to zero\n correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;\n\n const denominator = maxResponsePerZone > 1 ? possibleResponses : responseContainers.length;\n const str = (correctAnswers / denominator).toFixed(2);\n\n return parseFloat(str);\n};\n\nconst getScore = (config, session, env = {}) => {\n const isPartialScoring = partialScoring.enabled(config, env);\n const correct = isDefaultOrAltResponseCorrect(config, session);\n\n return isPartialScoring ? getPartialScore(config, session) : (correct ? 1 : 0);\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise(resolve => {\n log('outcome...');\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const configCamelized = camelizeKeys(config);\n\n if (session.answers || []) {\n const score = getScore(configCamelized, session, env);\n resolve({ score });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise(resolve => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { validation: { valid_response: { value } } } = question;\n const answers = [];\n\n if (value) {\n value.forEach((container, i) => {\n container.forEach(v => {\n answers.push({\n value: v,\n containerIndex: i\n });\n });\n });\n }\n\n resolve({\n answers,\n id: '1'\n });\n } else {\n resolve(null);\n }\n });\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","model","session","env","questionNormalized","questionCamelized","Promise","resolve","out","disabled","mode","responseCorrect","getScore","undefined","role","teacherInstructions","isResponseCorrect","responses","isCorrect","totalValidResponses","forEach","value","images","length","answers","answer","containerIndex","includes","isDefaultOrAltResponseCorrect","validation","validResponse","altResponses","altResponse","getDeductionPerContainer","valid","totalStack","filter","item","incorrectStack","maxValid","ignored","slice","getPartialScore","maxResponsePerZone","responseContainers","correctAnswers","possibleResponses","all","deductionList","id","denominator","str","toFixed","parseFloat","config","isPartialScoring","partialScoring","enabled","correct","outcome","score","empty","configCamelized","createCorrectResponseSession","valid_response","container","i","v","push"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport { camelizeKeys } from 'humps';\nimport { partialScoring } from '@pie-lib/controller-utils';\n\nimport { getAllUniqueCorrectness } from './utils';\n\nconst log = debug('pie-elements:image-cloze-association:controller');\n\nexport const normalize = (question) => ({\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n});\n\nexport function model(question, session, env) {\n const questionNormalized = normalize(question);\n const questionCamelized = camelizeKeys(questionNormalized);\n\n return new Promise((resolve) => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n ...questionCamelized,\n responseCorrect: env.mode === 'evaluate' ? getScore(questionCamelized, session) === 1 : undefined,\n };\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = questionCamelized.teacherInstructionsEnabled\n ? questionCamelized.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n}\n\nexport const isResponseCorrect = (responses, session) => {\n let isCorrect = true;\n let totalValidResponses = 0;\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n responses.forEach((value) => (totalValidResponses += (value.images || []).length));\n\n if (session.answers && totalValidResponses === session.answers.length) {\n session.answers.forEach((answer) => {\n if (!(responses[answer.containerIndex].images || []).includes(answer.value)) {\n isCorrect = false;\n }\n });\n } else {\n isCorrect = false;\n }\n return isCorrect;\n};\n\n// This applies for items that don't support partial scoring.\nconst isDefaultOrAltResponseCorrect = (question, session) => {\n const {\n validation: {\n validResponse: { value },\n altResponses,\n },\n } = question;\n\n let isCorrect = isResponseCorrect(value, session);\n\n // Look for correct answers in alternate responses.\n if (!isCorrect && altResponses && altResponses.length) {\n altResponses.forEach((altResponse) => {\n if (isResponseCorrect(altResponse.value, session)) {\n isCorrect = true;\n }\n });\n }\n return isCorrect;\n};\n\n// Deduct only the items that exceeded the maximum valid response per container.\nconst getDeductionPerContainer = (containerIndex, answers, valid) => {\n const totalStack = answers.filter((item) => item.containerIndex === containerIndex);\n const incorrectStack = totalStack.filter((item) => !item.isCorrect);\n const maxValid = (valid.value[containerIndex].images || []).length;\n\n if (totalStack.length > maxValid) {\n const ignored = totalStack.length - maxValid;\n return incorrectStack.slice(-ignored);\n }\n return [];\n};\n\nexport const getPartialScore = (question, session) => {\n const {\n validation: { validResponse },\n maxResponsePerZone,\n responseContainers,\n } = question;\n let correctAnswers = 0;\n let possibleResponses = 0;\n\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n validResponse.value.forEach((value) => (possibleResponses += (value.images || []).length));\n\n if (session.answers && session.answers.length) {\n const all = getAllUniqueCorrectness(session.answers, validResponse.value);\n correctAnswers = all.filter((item) => item.isCorrect).length;\n\n // deduction rules: https://docs.google.com/document/d/1Oprm8Qs5fg_Dwoj2pNpsfu4D63QgCZgvcqTgeaVel7I/edit\n session.answers.forEach((answer) => {\n if (maxResponsePerZone > 1) {\n const deductionList = getDeductionPerContainer(answer.containerIndex, all, validResponse);\n\n if (deductionList.length) {\n deductionList.forEach((item) => {\n if (item.id === answer.id) {\n correctAnswers -= 1;\n }\n });\n }\n }\n });\n } else {\n correctAnswers = 0;\n }\n // negative values will implicitly make the score equal to zero\n correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;\n\n const denominator = maxResponsePerZone > 1 ? possibleResponses : responseContainers.length;\n const str = (correctAnswers / denominator).toFixed(2);\n\n return parseFloat(str);\n};\n\nconst getScore = (config, session, env = {}) => {\n const isPartialScoring = partialScoring.enabled(config, env);\n const correct = isDefaultOrAltResponseCorrect(config, session);\n\n return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise((resolve) => {\n log('outcome...');\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const configCamelized = camelizeKeys(config);\n\n if (session.answers || []) {\n const score = getScore(configCamelized, session, env);\n resolve({ score });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const {\n validation: {\n valid_response: { value },\n },\n } = question;\n const answers = [];\n\n if (value) {\n value.forEach((container, i) => {\n (container.images || []).forEach((v) => {\n answers.push({\n value: v,\n containerIndex: i,\n });\n });\n });\n }\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n"],"file":"index.js"}
@@ -9,20 +9,20 @@ exports.getAllUniqueCorrectness = void 0;
9
9
 
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
 
12
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
12
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
13
13
 
14
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
14
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
15
15
 
16
16
  var getAllCorrectness = function getAllCorrectness(answers, responses) {
17
17
  return answers.map(function (answer) {
18
18
  return _objectSpread(_objectSpread({}, answer), {}, {
19
- isCorrect: responses[answer.containerIndex].includes(answer.value)
19
+ isCorrect: (responses[answer.containerIndex].images || []).includes(answer.value)
20
20
  });
21
21
  });
22
22
  };
23
23
 
24
24
  var getValidAnswer = function getValidAnswer(answer, response) {
25
- return response[answer.containerIndex].filter(function (res) {
25
+ return (response[answer.containerIndex].images || []).filter(function (res) {
26
26
  return res === answer.value;
27
27
  });
28
28
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.js"],"names":["getAllCorrectness","answers","responses","map","answer","isCorrect","containerIndex","includes","value","getValidAnswer","response","filter","res","getAllUniqueCorrectness","validResponses","allCorrectness","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid"],"mappings":";;;;;;;;;;;;;;;AAAA,IAAMA,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,OAAD,EAAUC,SAAV;AAAA,SACxBD,OAAO,CAACE,GAAR,CAAY,UAAAC,MAAM;AAAA,2CACbA,MADa;AAEhBC,MAAAA,SAAS,EAAEH,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,CAAiCC,QAAjC,CAA0CH,MAAM,CAACI,KAAjD;AAFK;AAAA,GAAlB,CADwB;AAAA,CAA1B;;AAMA,IAAMC,cAAc,GAAG,SAAjBA,cAAiB,CAACL,MAAD,EAASM,QAAT;AAAA,SACrBA,QAAQ,CAACN,MAAM,CAACE,cAAR,CAAR,CAAgCK,MAAhC,CAAuC,UAAAC,GAAG;AAAA,WAAIA,GAAG,KAAKR,MAAM,CAACI,KAAnB;AAAA,GAA1C,CADqB;AAAA,CAAvB;;AAGO,IAAMK,uBAAuB,GAAG,SAA1BA,uBAA0B,CAACZ,OAAD,EAAUa,cAAV,EAA6B;AAClE,MAAIC,cAAc,GAAGf,iBAAiB,CAACC,OAAD,EAAUa,cAAV,CAAtC;AAEAb,EAAAA,OAAO,CAACe,OAAR,CAAgB,UAACC,OAAD,EAAa;AAC3B,QAAMC,aAAa,GAAGjB,OAAO,CAACU,MAAR,CAAe,UAAAQ,OAAO;AAAA,aACzCA,OAAO,CAACX,KAAR,KAAkBS,OAAO,CAACT,KAA3B,IAAsCW,OAAO,CAACb,cAAR,KAA2BW,OAAO,CAACX,cAD/B;AAAA,KAAtB,CAAtB;;AAGA,QAAIY,aAAa,CAACE,MAAd,GAAuB,CAA3B,EAA8B;AAC5B;AACAF,MAAAA,aAAa,CAACG,KAAd,GAF4B,CAG5B;;AACAH,MAAAA,aAAa,CAACF,OAAd,CAAsB,UAACR,KAAD,EAAQc,KAAR,EAAkB;AACtCP,QAAAA,cAAc,GAAGA,cAAc,CAACZ,GAAf,CAAmB,UAAAoB,WAAW,EAAI;AACjD,cAAIA,WAAW,CAACC,EAAZ,KAAmBhB,KAAK,CAACgB,EAA7B,EAAiC;AAC/B,gBAAIC,KAAK,GAAGhB,cAAc,CAACc,WAAD,EAAcT,cAAd,CAA1B;AAEA,mDACKS,WADL;AAEElB,cAAAA,SAAS,EAAEoB,KAAK,CAACL,MAAN,GAAeE,KAAK,GAAG;AAFpC;AAID;;AACD,iBAAOC,WAAP;AACD,SAVgB,CAAjB;AAWD,OAZD;AAaD;AACF,GAtBD;AAuBA,SAAOR,cAAP;AACD,CA3BM","sourcesContent":["const getAllCorrectness = (answers, responses) =>\n answers.map(answer => ({\n ...answer,\n isCorrect: responses[answer.containerIndex].includes(answer.value)\n }));\n\nconst getValidAnswer = (answer, response) =>\n response[answer.containerIndex].filter(res => res === answer.value);\n\nexport const getAllUniqueCorrectness = (answers, validResponses) => {\n let allCorrectness = getAllCorrectness(answers, validResponses);\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(answer2 =>\n (answer2.value === answer1.value) && (answer2.containerIndex === answer1.containerIndex));\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n allCorrectness = allCorrectness.map(finalAnswer => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1\n }\n }\n return finalAnswer;\n })\n });\n }\n });\n return allCorrectness;\n};\n"],"file":"utils.js"}
1
+ {"version":3,"sources":["../src/utils.js"],"names":["getAllCorrectness","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getAllUniqueCorrectness","validResponses","allCorrectness","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid"],"mappings":";;;;;;;;;;;;;;;AAAA,IAAMA,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,OAAD,EAAUC,SAAV;AAAA,SACxBD,OAAO,CAACE,GAAR,CAAY,UAACC,MAAD;AAAA,2CACPA,MADO;AAEVC,MAAAA,SAAS,EAAE,CAACH,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,CAAiCC,MAAjC,IAA2C,EAA5C,EAAgDC,QAAhD,CAAyDJ,MAAM,CAACK,KAAhE;AAFD;AAAA,GAAZ,CADwB;AAAA,CAA1B;;AAMA,IAAMC,cAAc,GAAG,SAAjBA,cAAiB,CAACN,MAAD,EAASO,QAAT;AAAA,SACrB,CAACA,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,CAAgCC,MAAhC,IAA0C,EAA3C,EAA+CK,MAA/C,CAAsD,UAACC,GAAD;AAAA,WAASA,GAAG,KAAKT,MAAM,CAACK,KAAxB;AAAA,GAAtD,CADqB;AAAA,CAAvB;;AAGO,IAAMK,uBAAuB,GAAG,SAA1BA,uBAA0B,CAACb,OAAD,EAAUc,cAAV,EAA6B;AAClE,MAAIC,cAAc,GAAGhB,iBAAiB,CAACC,OAAD,EAAUc,cAAV,CAAtC;AAEAd,EAAAA,OAAO,CAACgB,OAAR,CAAgB,UAACC,OAAD,EAAa;AAC3B,QAAMC,aAAa,GAAGlB,OAAO,CAACW,MAAR,CACpB,UAACQ,OAAD;AAAA,aAAaA,OAAO,CAACX,KAAR,KAAkBS,OAAO,CAACT,KAA1B,IAAmCW,OAAO,CAACd,cAAR,KAA2BY,OAAO,CAACZ,cAAnF;AAAA,KADoB,CAAtB;;AAIA,QAAIa,aAAa,CAACE,MAAd,GAAuB,CAA3B,EAA8B;AAC5B;AACAF,MAAAA,aAAa,CAACG,KAAd,GAF4B,CAG5B;;AACAH,MAAAA,aAAa,CAACF,OAAd,CAAsB,UAACR,KAAD,EAAQc,KAAR,EAAkB;AACtCP,QAAAA,cAAc,GAAGA,cAAc,CAACb,GAAf,CAAmB,UAACqB,WAAD,EAAiB;AACnD,cAAIA,WAAW,CAACC,EAAZ,KAAmBhB,KAAK,CAACgB,EAA7B,EAAiC;AAC/B,gBAAIC,KAAK,GAAGhB,cAAc,CAACc,WAAD,EAAcT,cAAd,CAA1B;AACA,mDACKS,WADL;AAEEnB,cAAAA,SAAS,EAAEqB,KAAK,CAACL,MAAN,GAAeE,KAAK,GAAG;AAFpC;AAID;;AACD,iBAAOC,WAAP;AACD,SATgB,CAAjB;AAUD,OAXD;AAYD;AACF,GAtBD;AAuBA,SAAOR,cAAP;AACD,CA3BM","sourcesContent":["const getAllCorrectness = (answers, responses) =>\n answers.map((answer) => ({\n ...answer,\n isCorrect: (responses[answer.containerIndex].images || []).includes(answer.value),\n }));\n\nconst getValidAnswer = (answer, response) =>\n (response[answer.containerIndex].images || []).filter((res) => res === answer.value);\n\nexport const getAllUniqueCorrectness = (answers, validResponses) => {\n let allCorrectness = getAllCorrectness(answers, validResponses);\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(\n (answer2) => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex,\n );\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n allCorrectness = allCorrectness.map((finalAnswer) => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1,\n };\n }\n return finalAnswer;\n });\n });\n }\n });\n return allCorrectness;\n};\n"],"file":"utils.js"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pie-element/image-cloze-association-controller",
3
3
  "private": true,
4
- "version": "3.2.13",
4
+ "version": "3.2.23",
5
5
  "description": "",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -11,7 +11,7 @@
11
11
  "main": "lib/index.js",
12
12
  "module": "src/index.js",
13
13
  "dependencies": {
14
- "@pie-lib/controller-utils": "^0.2.24",
14
+ "@pie-lib/controller-utils": "^0.2.42",
15
15
  "debug": "^4.1.1",
16
16
  "humps": "^2.0.1",
17
17
  "lodash": "^4.17.15"