@khanacademy/perseus 0.3.3 → 0.4.0

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 (60) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/es/index.js +8247 -5609
  3. package/dist/es/index.js.map +1 -1
  4. package/dist/index.js +17900 -15265
  5. package/dist/index.js.map +1 -1
  6. package/dist/strings.js +0 -1
  7. package/package.json +9 -8
  8. package/src/__tests__/__snapshots__/item-renderer_test.jsx.snap +2 -3
  9. package/src/__tests__/__snapshots__/server-item-renderer_test.jsx.snap +2 -3
  10. package/src/__tests__/renderer-api_test.jsx +3 -27
  11. package/src/components/__stories__/svg-image.stories.jsx +11 -0
  12. package/src/components/fixed-to-responsive.jsx +1 -0
  13. package/src/components/highlighting/ui/util.js +2 -2
  14. package/src/components/input-with-examples.jsx +3 -1
  15. package/src/components/svg-image.jsx +10 -7
  16. package/src/components/text-input.jsx +65 -16
  17. package/src/definition-context.js +59 -0
  18. package/src/index.js +5 -1
  19. package/src/interaction-tracker.js +2 -2
  20. package/src/item-renderer.jsx +1 -1
  21. package/src/mixins/provide-keypad.jsx +1 -1
  22. package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +438 -523
  23. package/src/multi-items/__tests__/multi-renderer_test.js +9 -9
  24. package/src/renderer.jsx +15 -8
  25. package/src/server-item-renderer.jsx +1 -1
  26. package/src/types.js +3 -4
  27. package/src/util/scroll-utils.js +2 -2
  28. package/src/widgets/__stories__/definition.stories.jsx +44 -0
  29. package/src/widgets/__tests__/__snapshots__/categorizer_test.jsx.snap +76 -8
  30. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +6 -9
  31. package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +2 -3
  32. package/src/widgets/__tests__/__snapshots__/grapher_test.jsx.snap +19 -2
  33. package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +338 -390
  34. package/src/widgets/__tests__/__snapshots__/image_test.jsx.snap +38 -4
  35. package/src/widgets/__tests__/__snapshots__/interactive-graph_test.jsx.snap +114 -12
  36. package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +120 -48
  37. package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +8 -12
  38. package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +3615 -4517
  39. package/src/widgets/__tests__/graded-group-set-jipt_test.jsx +0 -1
  40. package/src/widgets/__tests__/grapher.cypress.jsx +236 -176
  41. package/src/widgets/__tests__/group_test.jsx +4 -4
  42. package/src/widgets/__tests__/interactive-graph.cypress.jsx +371 -291
  43. package/src/widgets/__tests__/radio_test.jsx +73 -114
  44. package/src/widgets/definition.jsx +34 -32
  45. package/src/widgets/interactive-graph.jsx +4 -4
  46. package/src/widgets/label-image/answer-choices.jsx +1 -1
  47. package/src/widgets/label-image.jsx +1 -1
  48. package/src/widgets/molecule/molecule-drawing.jsx +1 -1
  49. package/src/widgets/numeric-input.jsx +2 -15
  50. package/src/widgets/radio/base-radio.jsx +1 -1
  51. package/src/widgets/radio/choice-icon.jsx +11 -10
  52. package/src/widgets/radio/choice.jsx +164 -396
  53. package/src/widgets/radio/cross-out-button.jsx +3 -5
  54. package/src/widgets/radio/option-status.jsx +4 -5
  55. package/src/widgets/radio/__stories__/cross-out-menu.stories.jsx +0 -59
  56. package/src/widgets/radio/__stories__/cross-out-tooltip.stories.jsx +0 -59
  57. package/src/widgets/radio/__stories__/toggleable-radio-button.stories.jsx +0 -28
  58. package/src/widgets/radio/cross-out-menu-wrapper.jsx +0 -492
  59. package/src/widgets/radio/cross-out-tooltip.jsx +0 -129
  60. package/src/widgets/radio/toggleable-radio-button.jsx +0 -133
@@ -18,7 +18,6 @@ describe("graded-group-set", () => {
18
18
  ...testDependencies,
19
19
  JIPT: {
20
20
  useJIPT: true,
21
- domInsertChecks: [],
22
21
  },
23
22
  });
24
23
  });
@@ -38,15 +38,19 @@ describe("Grapher widget", () => {
38
38
  );
39
39
 
40
40
  // Act
41
- cy.get(GRAPHIE).then((node) => {
42
- const {left, top} = node[0].getBoundingClientRect();
43
- cy.get(POINTS)
44
- .eq(0)
45
- .dragTo({x: left + 360, y: top + 180});
46
- cy.get(POINTS)
47
- .eq(1)
48
- .dragTo({x: left + 340, y: top + 140});
49
- });
41
+ cy.get(GRAPHIE)
42
+ .should("exist")
43
+ .then((node) => {
44
+ const {left, top} = node[0].getBoundingClientRect();
45
+ cy.get(POINTS)
46
+ .eq(0)
47
+ .should("exist")
48
+ .dragTo({x: left + 360, y: top + 180});
49
+ cy.get(POINTS)
50
+ .eq(1)
51
+ .should("exist")
52
+ .dragTo({x: left + 340, y: top + 140});
53
+ });
50
54
 
51
55
  // Assert
52
56
  cy.then(() => {
@@ -67,15 +71,19 @@ describe("Grapher widget", () => {
67
71
  );
68
72
 
69
73
  // Act
70
- cy.get(GRAPHIE).then((node) => {
71
- const {left, top} = node[0].getBoundingClientRect();
72
- cy.get(POINTS)
73
- .eq(0)
74
- .dragTo({x: left + 200, y: top + 200});
75
- cy.get(POINTS)
76
- .eq(1)
77
- .dragTo({x: left + 100, y: top + 100});
78
- });
74
+ cy.get(GRAPHIE)
75
+ .should("exist")
76
+ .then((node) => {
77
+ const {left, top} = node[0].getBoundingClientRect();
78
+ cy.get(POINTS)
79
+ .eq(0)
80
+ .should("exist")
81
+ .dragTo({x: left + 200, y: top + 200});
82
+ cy.get(POINTS)
83
+ .eq(1)
84
+ .should("exist")
85
+ .dragTo({x: left + 100, y: top + 100});
86
+ });
79
87
 
80
88
  // Assert
81
89
  cy.then(() => {
@@ -96,20 +104,25 @@ describe("Grapher widget", () => {
96
104
  const getRenderer = renderQuestionWithCypress(exponentialQuestion);
97
105
 
98
106
  // Act
99
- cy.get(GRAPHIE).then((node) => {
100
- const {left, top} = node[0].getBoundingClientRect();
101
- cy.get(LINES)
102
- .eq(0)
103
- .dragTo({x: left + 200, y: top + 75});
104
- // [0, 3],
105
- // [1, -1],
106
- cy.get(POINTS)
107
- .eq(0)
108
- .dragTo({x: left + 200, y: top + 120});
109
- cy.get(POINTS)
110
- .eq(1)
111
- .dragTo({x: left + 225, y: top + 225});
112
- });
107
+ cy.get(GRAPHIE)
108
+ .should("exist")
109
+ .then((node) => {
110
+ const {left, top} = node[0].getBoundingClientRect();
111
+ cy.get(LINES)
112
+ .eq(0)
113
+ .should("exist")
114
+ .dragTo({x: left + 200, y: top + 75});
115
+ // [0, 3],
116
+ // [1, -1],
117
+ cy.get(POINTS)
118
+ .eq(0)
119
+ .should("exist")
120
+ .dragTo({x: left + 200, y: top + 120});
121
+ cy.get(POINTS)
122
+ .eq(1)
123
+ .should("exist")
124
+ .dragTo({x: left + 225, y: top + 225});
125
+ });
113
126
 
114
127
  // Assert
115
128
  cy.then(() => {
@@ -128,18 +141,23 @@ describe("Grapher widget", () => {
128
141
  const getRenderer = renderQuestionWithCypress(exponentialQuestion);
129
142
 
130
143
  // Act
131
- cy.get(GRAPHIE).then((node) => {
132
- const {left, top} = node[0].getBoundingClientRect();
133
- cy.get(LINES)
134
- .eq(0)
135
- .dragTo({x: left + 200, y: top + 200});
136
- cy.get(POINTS)
137
- .eq(0)
138
- .dragTo({x: left + 25, y: top + 25});
139
- cy.get(POINTS)
140
- .eq(1)
141
- .dragTo({x: left + 200, y: top + 200});
142
- });
144
+ cy.get(GRAPHIE)
145
+ .should("exist")
146
+ .then((node) => {
147
+ const {left, top} = node[0].getBoundingClientRect();
148
+ cy.get(LINES)
149
+ .eq(0)
150
+ .should("exist")
151
+ .dragTo({x: left + 200, y: top + 200});
152
+ cy.get(POINTS)
153
+ .eq(0)
154
+ .should("exist")
155
+ .dragTo({x: left + 25, y: top + 25});
156
+ cy.get(POINTS)
157
+ .eq(1)
158
+ .should("exist")
159
+ .dragTo({x: left + 200, y: top + 200});
160
+ });
143
161
 
144
162
  // Assert
145
163
  cy.then(() => {
@@ -160,15 +178,19 @@ describe("Grapher widget", () => {
160
178
  const getRenderer = renderQuestionWithCypress(linearQuestion);
161
179
 
162
180
  // Act
163
- cy.get(GRAPHIE).then((node) => {
164
- const {left, top} = node[0].getBoundingClientRect();
165
- cy.get(POINTS)
166
- .eq(0)
167
- .dragTo({x: left + 200, y: top + 100});
168
- cy.get(POINTS)
169
- .eq(1)
170
- .dragTo({x: left + 260, y: top + 200});
171
- });
181
+ cy.get(GRAPHIE)
182
+ .should("exist")
183
+ .then((node) => {
184
+ const {left, top} = node[0].getBoundingClientRect();
185
+ cy.get(POINTS)
186
+ .eq(0)
187
+ .should("exist")
188
+ .dragTo({x: left + 200, y: top + 100});
189
+ cy.get(POINTS)
190
+ .eq(1)
191
+ .should("exist")
192
+ .dragTo({x: left + 260, y: top + 200});
193
+ });
172
194
 
173
195
  // Assert
174
196
  cy.then(() => {
@@ -187,15 +209,19 @@ describe("Grapher widget", () => {
187
209
  const getRenderer = renderQuestionWithCypress(linearQuestion);
188
210
 
189
211
  // Act
190
- cy.get(GRAPHIE).then((node) => {
191
- const {left, top} = node[0].getBoundingClientRect();
192
- cy.get(POINTS)
193
- .eq(0)
194
- .dragTo({x: left + 100, y: top + 100});
195
- cy.get(POINTS)
196
- .eq(1)
197
- .dragTo({x: left + 300, y: top + 300});
198
- });
212
+ cy.get(GRAPHIE)
213
+ .should("exist")
214
+ .then((node) => {
215
+ const {left, top} = node[0].getBoundingClientRect();
216
+ cy.get(POINTS)
217
+ .eq(0)
218
+ .should("exist")
219
+ .dragTo({x: left + 100, y: top + 100});
220
+ cy.get(POINTS)
221
+ .eq(1)
222
+ .should("exist")
223
+ .dragTo({x: left + 300, y: top + 300});
224
+ });
199
225
 
200
226
  // Assert
201
227
  cy.then(() => {
@@ -216,30 +242,35 @@ describe("Grapher widget", () => {
216
242
  const getRenderer = renderQuestionWithCypress(logarithmQuestion);
217
243
 
218
244
  // Act
219
- cy.get(GRAPHIE).then((node) => {
220
- const {left, top} = node[0].getBoundingClientRect();
221
- // Move the Asymptote to x=-6
222
- cy.get(LINES)
223
- .eq(0)
224
- .dragTo({
225
- x: left + 50,
226
- y: top + 200, // It's a vertical line, so this doesn't matter much
227
- });
228
- // Move point A
229
- cy.get(POINTS)
230
- .eq(0)
231
- .dragTo({
232
- x: left + 100,
233
- y: top + 275,
234
- });
235
- // Move point B
236
- cy.get(POINTS)
237
- .eq(1)
238
- .dragTo({
239
- x: left + 75,
240
- y: top + 375,
241
- });
242
- });
245
+ cy.get(GRAPHIE)
246
+ .should("exist")
247
+ .then((node) => {
248
+ const {left, top} = node[0].getBoundingClientRect();
249
+ // Move the Asymptote to x=-6
250
+ cy.get(LINES)
251
+ .eq(0)
252
+ .should("exist")
253
+ .dragTo({
254
+ x: left + 50,
255
+ y: top + 200, // It's a vertical line, so this doesn't matter much
256
+ });
257
+ // Move point A
258
+ cy.get(POINTS)
259
+ .eq(0)
260
+ .should("exist")
261
+ .dragTo({
262
+ x: left + 100,
263
+ y: top + 275,
264
+ });
265
+ // Move point B
266
+ cy.get(POINTS)
267
+ .eq(1)
268
+ .should("exist")
269
+ .dragTo({
270
+ x: left + 75,
271
+ y: top + 375,
272
+ });
273
+ });
243
274
 
244
275
  // Assert
245
276
  cy.then(() => {
@@ -258,30 +289,35 @@ describe("Grapher widget", () => {
258
289
  const getRenderer = renderQuestionWithCypress(logarithmQuestion);
259
290
 
260
291
  // Act
261
- cy.get(GRAPHIE).then((node) => {
262
- const {left, top} = node[0].getBoundingClientRect();
263
- // Move the Asymptote to x=-6
264
- cy.get(LINES)
265
- .eq(0)
266
- .dragTo({
267
- x: left + 50,
268
- y: top + 200, // It's a vertical line, so this doesn't matter much
269
- });
270
- // Move point A
271
- cy.get(POINTS)
272
- .eq(0)
273
- .dragTo({
274
- x: left + 225,
275
- y: top + 125,
276
- });
277
- // Move point B
278
- cy.get(POINTS)
279
- .eq(1)
280
- .dragTo({
281
- x: left + 100,
282
- y: top + 300,
283
- });
284
- });
292
+ cy.get(GRAPHIE)
293
+ .should("exist")
294
+ .then((node) => {
295
+ const {left, top} = node[0].getBoundingClientRect();
296
+ // Move the Asymptote to x=-6
297
+ cy.get(LINES)
298
+ .eq(0)
299
+ .should("exist")
300
+ .dragTo({
301
+ x: left + 50,
302
+ y: top + 200, // It's a vertical line, so this doesn't matter much
303
+ });
304
+ // Move point A
305
+ cy.get(POINTS)
306
+ .eq(0)
307
+ .should("exist")
308
+ .dragTo({
309
+ x: left + 225,
310
+ y: top + 125,
311
+ });
312
+ // Move point B
313
+ cy.get(POINTS)
314
+ .eq(1)
315
+ .should("exist")
316
+ .dragTo({
317
+ x: left + 100,
318
+ y: top + 300,
319
+ });
320
+ });
285
321
 
286
322
  // Assert
287
323
  cy.then(() => {
@@ -302,17 +338,21 @@ describe("Grapher widget", () => {
302
338
  const getRenderer = renderQuestionWithCypress(quadraticQuestion);
303
339
 
304
340
  // Act
305
- cy.get(GRAPHIE).then((node) => {
306
- const {left, top} = node[0].getBoundingClientRect();
307
- // Move point A
308
- cy.get(POINTS)
309
- .eq(0)
310
- .dragTo({x: left + 260, y: top + 360});
311
- // Move point B
312
- cy.get(POINTS)
313
- .eq(1)
314
- .dragTo({x: left + 220, y: top + 200});
315
- });
341
+ cy.get(GRAPHIE)
342
+ .should("exist")
343
+ .then((node) => {
344
+ const {left, top} = node[0].getBoundingClientRect();
345
+ // Move point A
346
+ cy.get(POINTS)
347
+ .eq(0)
348
+ .should("exist")
349
+ .dragTo({x: left + 260, y: top + 360});
350
+ // Move point B
351
+ cy.get(POINTS)
352
+ .eq(1)
353
+ .should("exist")
354
+ .dragTo({x: left + 220, y: top + 200});
355
+ });
316
356
 
317
357
  // Assert
318
358
  cy.then(() => {
@@ -331,17 +371,21 @@ describe("Grapher widget", () => {
331
371
  const getRenderer = renderQuestionWithCypress(quadraticQuestion);
332
372
 
333
373
  // Act
334
- cy.get(GRAPHIE).then((node) => {
335
- const {left, top} = node[0].getBoundingClientRect();
336
- // Move point A
337
- cy.get(POINTS)
338
- .eq(0)
339
- .dragTo({x: left + 50, y: top + 50});
340
- // Move point B
341
- cy.get(POINTS)
342
- .eq(1)
343
- .dragTo({x: left + 200, y: top + 300});
344
- });
374
+ cy.get(GRAPHIE)
375
+ .should("exist")
376
+ .then((node) => {
377
+ const {left, top} = node[0].getBoundingClientRect();
378
+ // Move point A
379
+ cy.get(POINTS)
380
+ .eq(0)
381
+ .should("exist")
382
+ .dragTo({x: left + 50, y: top + 50});
383
+ // Move point B
384
+ cy.get(POINTS)
385
+ .eq(1)
386
+ .should("exist")
387
+ .dragTo({x: left + 200, y: top + 300});
388
+ });
345
389
 
346
390
  // Assert
347
391
  cy.then(() => {
@@ -362,16 +406,20 @@ describe("Grapher widget", () => {
362
406
  const getRenderer = renderQuestionWithCypress(sinusoidQuestion);
363
407
 
364
408
  // Act
365
- cy.get(GRAPHIE).then((node) => {
366
- const {left, top} = node[0].getBoundingClientRect();
367
-
368
- cy.get(POINTS)
369
- .eq(0)
370
- .dragTo({x: left + 220, y: top + 140});
371
- cy.get(POINTS)
372
- .eq(1)
373
- .dragTo({x: left + 200, y: top + 220});
374
- });
409
+ cy.get(GRAPHIE)
410
+ .should("exist")
411
+ .then((node) => {
412
+ const {left, top} = node[0].getBoundingClientRect();
413
+
414
+ cy.get(POINTS)
415
+ .eq(0)
416
+ .should("exist")
417
+ .dragTo({x: left + 220, y: top + 140});
418
+ cy.get(POINTS)
419
+ .eq(1)
420
+ .should("exist")
421
+ .dragTo({x: left + 200, y: top + 220});
422
+ });
375
423
 
376
424
  // Assert
377
425
  cy.then(() => {
@@ -390,16 +438,20 @@ describe("Grapher widget", () => {
390
438
  const getRenderer = renderQuestionWithCypress(sinusoidQuestion);
391
439
 
392
440
  // Act
393
- cy.get(GRAPHIE).then((node) => {
394
- const {left, top} = node[0].getBoundingClientRect();
395
-
396
- cy.get(POINTS)
397
- .eq(0)
398
- .dragTo({x: left + 100, y: top + 140});
399
- cy.get(POINTS)
400
- .eq(1)
401
- .dragTo({x: left + 200, y: top + 220});
402
- });
441
+ cy.get(GRAPHIE)
442
+ .should("exist")
443
+ .then((node) => {
444
+ const {left, top} = node[0].getBoundingClientRect();
445
+
446
+ cy.get(POINTS)
447
+ .eq(0)
448
+ .should("exist")
449
+ .dragTo({x: left + 100, y: top + 140});
450
+ cy.get(POINTS)
451
+ .eq(1)
452
+ .should("exist")
453
+ .dragTo({x: left + 200, y: top + 220});
454
+ });
403
455
 
404
456
  // Assert
405
457
  cy.then(() => {
@@ -424,18 +476,22 @@ describe("Grapher widget", () => {
424
476
  // Act
425
477
  cy.get("button[title=Absolute_value]").click();
426
478
 
427
- cy.get(GRAPHIE).then((node) => {
428
- const rect = node[0].getBoundingClientRect();
429
- const left = rect.left + window.scrollX;
430
- const top = rect.top + window.scrollY;
431
-
432
- cy.get(POINTS)
433
- .eq(0)
434
- .dragTo({x: left + 220, y: top + 260});
435
- cy.get(POINTS)
436
- .eq(1)
437
- .dragTo({x: left + 200, y: top + 200});
438
- });
479
+ cy.get(GRAPHIE)
480
+ .should("exist")
481
+ .then((node) => {
482
+ const rect = node[0].getBoundingClientRect();
483
+ const left = rect.left + window.scrollX;
484
+ const top = rect.top + window.scrollY;
485
+
486
+ cy.get(POINTS)
487
+ .eq(0)
488
+ .should("exist")
489
+ .dragTo({x: left + 220, y: top + 260});
490
+ cy.get(POINTS)
491
+ .eq(1)
492
+ .should("exist")
493
+ .dragTo({x: left + 200, y: top + 200});
494
+ });
439
495
 
440
496
  // Assert
441
497
  cy.then(() => {
@@ -458,18 +514,22 @@ describe("Grapher widget", () => {
458
514
  // Act
459
515
  cy.get("button[title=Absolute_value]").click();
460
516
 
461
- cy.get(GRAPHIE).then((node) => {
462
- const rect = node[0].getBoundingClientRect();
463
- const left = rect.left + window.scrollX;
464
- const top = rect.top + window.scrollY;
465
-
466
- cy.get(POINTS)
467
- .eq(0)
468
- .dragTo({x: left + 200, y: top + 200});
469
- cy.get(POINTS)
470
- .eq(1)
471
- .dragTo({x: left + 100, y: top + 100});
472
- });
517
+ cy.get(GRAPHIE)
518
+ .should("exist")
519
+ .then((node) => {
520
+ const rect = node[0].getBoundingClientRect();
521
+ const left = rect.left + window.scrollX;
522
+ const top = rect.top + window.scrollY;
523
+
524
+ cy.get(POINTS)
525
+ .eq(0)
526
+ .should("exist")
527
+ .dragTo({x: left + 200, y: top + 200});
528
+ cy.get(POINTS)
529
+ .eq(1)
530
+ .should("exist")
531
+ .dragTo({x: left + 100, y: top + 100});
532
+ });
473
533
 
474
534
  // Assert
475
535
  cy.then(() => {
@@ -347,7 +347,7 @@ describe("group widget", () => {
347
347
 
348
348
  // Arrange
349
349
  const {renderer} = renderQuestion(question1);
350
- userEvent.click(screen.getAllByRole("radio")[4]);
350
+ userEvent.click(screen.getAllByRole("checkbox")[4]);
351
351
  userEvent.type(screen.getAllByRole("textbox")[0], "1000");
352
352
  userEvent.type(screen.getAllByRole("textbox")[1], "9999");
353
353
 
@@ -360,7 +360,7 @@ describe("group widget", () => {
360
360
  renderer1.restoreSerializedState(state);
361
361
 
362
362
  // Assert
363
- expect(screen.getAllByRole("radio")[4]).toBeChecked();
363
+ expect(screen.getAllByRole("checkbox")[4]).toBeChecked();
364
364
  expect(screen.getAllByRole("textbox")[0]).toHaveValue("1000");
365
365
  expect(screen.getAllByRole("textbox")[1]).toHaveValue("9999");
366
366
  });
@@ -369,7 +369,7 @@ describe("group widget", () => {
369
369
  // Arrange
370
370
  const {renderer} = renderQuestion(question1);
371
371
  // Answer all widgets correctly
372
- userEvent.click(screen.getAllByRole("radio")[4]);
372
+ userEvent.click(screen.getAllByRole("checkbox")[4]);
373
373
  userEvent.type(screen.getAllByRole("textbox")[0], "230");
374
374
  userEvent.type(screen.getAllByRole("textbox")[1], "200");
375
375
 
@@ -453,7 +453,7 @@ describe("group widget", () => {
453
453
  it("should show rationales for contained widgets", () => {
454
454
  // Arrange
455
455
  const {renderer} = renderQuestion(question1);
456
- userEvent.click(screen.getAllByRole("radio")[2]); // Incorrect!
456
+ userEvent.click(screen.getAllByRole("checkbox")[2]); // Incorrect!
457
457
 
458
458
  // Act
459
459
  renderer.showRationalesForCurrentlySelectedChoices();