· 6 years ago · Jun 04, 2019, 07:36 PM
1Checking if node.js is installed in /home/thejedicode/oppia3/oppia_tools
2Generating list of installed node modules...
3Generation completed.
4Checking whether Google App Engine is installed in /home/thejedicode/oppia3/oppia_tools/google_appengine_1.9.67/google_appengine
5Checking whether google-cloud-sdk is installed in /home/thejedicode/oppia3/oppia_tools/google-cloud-sdk-222.0.0/google-cloud-sdk
6Environment setup completed.
7Installing third-party JS libraries and zip files.
8audited 22054 packages in 8.164s
9found 0 vulnerabilities
10
11audited 21690 packages in 4.525s
12found 0 vulnerabilities
13
14Checking whether Skulpt is installed in third_party
15Checking if pip is installed on the local machine
16Checking if pylint is installed in /home/thejedicode/oppia3/oppia_tools
17Checking if pylint-quotes is installed in /home/thejedicode/oppia3/oppia_tools
18Checking if webtest is installed in third_party
19Checking if isort is installed in third_party
20Checking if pycodestyle is installed in third_party
21Checking if esprima is installed in third_party
22Checking if browsermob-proxy is installed in /home/thejedicode/oppia3/oppia_tools
23Checking if selenium is installed in /home/thejedicode/oppia3/oppia_tools
24Checking if PIL is installed in /home/thejedicode/oppia3/oppia_tools
25Checking if PyGithub is installed in /home/thejedicode/oppia3/oppia_tools
26Installing pre-push hook for git
27Symlink already exists
28Compiling typescript...
29Compiling webpack...
30Starting type checking service...
31Using 1 worker with 2048MB memory limit
32Hash: 9c008cbd38f66e4cf3a3
33Version: webpack 4.31.0
34Time: 7789ms
35Built at: 06/05/2019 12:43:46 AM
36 Asset Size Chunks Chunk Names
37 about.73a5afcdf8e5cf9f911a.bundle.js 2.96 KiB 12 [emitted] about
38 about.73a5afcdf8e5cf9f911a.bundle.js.map 12.9 KiB 12 [emitted] about
39 about.html 22.8 KiB [emitted]
40 about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js 3.3 KiB 0 [emitted] about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0
41about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map 20.2 KiB 0 [emitted] about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0
42 admin.0e43f157c75de87dda41.bundle.js 22 KiB 13 [emitted] admin
43 admin.0e43f157c75de87dda41.bundle.js.map 117 KiB 13 [emitted] admin
44 admin.html 2.96 KiB [emitted]
45 admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js 7.5 KiB 4 [emitted] admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a
46admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map 36 KiB 4 [emitted] admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a
47 admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js 14.4 KiB 1 [emitted] admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963
48admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map 77.5 KiB 1 [emitted] admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963
49 app.3a832a81c9290cfe0045.bundle.js 29.2 KiB 14 [emitted] app
50 app.3a832a81c9290cfe0045.bundle.js.map 134 KiB 14 [emitted] app
51 app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js 4.09 KiB 2 [emitted] app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829
52app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map 16.8 KiB 2 [emitted] app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829
53 app~library.3bd713e5f19772d7b250.bundle.js 5.63 KiB 10 [emitted] app~library
54 app~library.3bd713e5f19772d7b250.bundle.js.map 24.8 KiB 10 [emitted] app~library
55 base.html 8.24 KiB [emitted]
56 collection_editor.d5d7c2da902175f981e4.bundle.js 53.8 KiB 15 [emitted] collection_editor
57 collection_editor.d5d7c2da902175f981e4.bundle.js.map 279 KiB 15 [emitted] collection_editor
58 collection_editor.html 2.34 KiB [emitted]
59 collection_editor~collection_player.b9979b856a928d9f3787.bundle.js 5.96 KiB 11 [emitted] collection_editor~collection_player
60 collection_editor~collection_player.b9979b856a928d9f3787.bundle.js.map 31.8 KiB 11 [emitted] collection_editor~collection_player
61 collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js 2.89 KiB 3 [emitted] collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736
62collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map 16.1 KiB 3 [emitted] collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736
63 collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js 33.3 KiB 6 [emitted] collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b
64collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js.map 158 KiB 6 [emitted] collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b
65 collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js 2.21 KiB 8 [emitted] collection_editor~skill_editor~story_editor~topic_editor
66 collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js.map 14.7 KiB 8 [emitted] collection_editor~skill_editor~story_editor~topic_editor
67 collection_player.9c68812dfdf7e51f76a1.bundle.js 19.4 KiB 16 [emitted] collection_player
68 collection_player.9c68812dfdf7e51f76a1.bundle.js.map 89.1 KiB 16 [emitted] collection_player
69 collection_player.html 3.85 KiB [emitted]
70 collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js 5.13 KiB 5 [emitted] collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965
71collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map 23.9 KiB 5 [emitted] collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965
72 collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js 4.21 KiB 9 [emitted] collection_player~learner_dashboard~library~profile
73 collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js.map 18.6 KiB 9 [emitted] collection_player~learner_dashboard~library~profile
74 console_errors.html 140 bytes [emitted]
75 contact.69ca35e967b2c6062897.bundle.js 1.97 KiB 17 [emitted] contact
76 contact.69ca35e967b2c6062897.bundle.js.map 11 KiB 17 [emitted] contact
77 contact.html 3.23 KiB [emitted]
78 creator_dashboard.9a0a34f7a5478e77dc79.bundle.js 391 KiB 18, 8 [emitted] [big] creator_dashboard
79 creator_dashboard.9a0a34f7a5478e77dc79.bundle.js.map 1.21 MiB 18, 8 [emitted] creator_dashboard
80 creator_dashboard.html 35.7 KiB [emitted]
81 creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js 3.71 KiB 7 [emitted] creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1
82creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js.map 19.5 KiB 7 [emitted] creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1
83 donate.89e271003ca58f551b56.bundle.js 5.95 KiB 19 [emitted] donate
84 donate.89e271003ca58f551b56.bundle.js.map 26 KiB 19 [emitted] donate
85 donate.html 5.67 KiB [emitted]
86 email_dashboard.ce2048523411200df68f.bundle.js 4.53 KiB 20 [emitted] email_dashboard
87 email_dashboard.ce2048523411200df68f.bundle.js.map 20.6 KiB 20 [emitted] email_dashboard
88 email_dashboard.html 3.1 KiB [emitted]
89 email_dashboard_result.600fc837d2bd509301f0.bundle.js 3.55 KiB 21 [emitted] email_dashboard_result
90 email_dashboard_result.600fc837d2bd509301f0.bundle.js.map 15.8 KiB 21 [emitted] email_dashboard_result
91 email_dashboard_result.html 3.33 KiB [emitted]
92 error.54cbece5212834d34ec0.bundle.js 1.9 KiB 22 [emitted] error
93 error.54cbece5212834d34ec0.bundle.js.map 10.6 KiB 22 [emitted] error
94 error.html 2.55 KiB [emitted]
95 exploration_editor.07de01208fc08d5292d7.bundle.js 586 KiB 23, 9 [emitted] [big] exploration_editor
96 exploration_editor.07de01208fc08d5292d7.bundle.js.map 2.12 MiB 23, 9 [emitted] exploration_editor
97 exploration_editor.html 10 KiB [emitted]
98 exploration_player.8d4cea35e36127c5d4ae.bundle.js 352 KiB 24, 9 [emitted] [big] exploration_player
99 exploration_player.8d4cea35e36127c5d4ae.bundle.js.map 1.03 MiB 24, 9 [emitted] exploration_player
100 exploration_player.html 5.04 KiB [emitted]
101 get_started.44ae16fbbf31c5a61652.bundle.js 1.97 KiB 25 [emitted] get_started
102 get_started.44ae16fbbf31c5a61652.bundle.js.map 11 KiB 25 [emitted] get_started
103 get_started.html 3.11 KiB [emitted]
104 landing.73de90c66695e4b1897f.bundle.js 7.05 KiB 26 [emitted] landing
105 landing.73de90c66695e4b1897f.bundle.js.map 30.1 KiB 26 [emitted] landing
106 landing_page_stewards.html 27.9 KiB [emitted]
107 learner_dashboard.155cb54d3808ca72e628.bundle.js 19.6 KiB 27 [emitted] learner_dashboard
108 learner_dashboard.155cb54d3808ca72e628.bundle.js.map 78.6 KiB 27 [emitted] learner_dashboard
109 learner_dashboard.html 47.9 KiB [emitted]
110 library.7b16e07d3aaf40c9b8f6.bundle.js 21.6 KiB 28 [emitted] library
111 library.7b16e07d3aaf40c9b8f6.bundle.js.map 101 KiB 28 [emitted] library
112 library.html 1.79 KiB [emitted]
113 maintenance.f7488f6c9b6471e499ab.bundle.js 1.7 KiB 29 [emitted] maintenance
114 maintenance.f7488f6c9b6471e499ab.bundle.js.map 9.29 KiB 29 [emitted] maintenance
115 maintenance.html 2.93 KiB [emitted]
116 moderator.ec4f8d6c4e5cd05677ba.bundle.js 3.99 KiB 30 [emitted] moderator
117 moderator.ec4f8d6c4e5cd05677ba.bundle.js.map 19.7 KiB 30 [emitted] moderator
118 moderator.html 4.06 KiB [emitted]
119 notifications_dashboard.9861b4d326fc6013d07a.bundle.js 2.14 KiB 31 [emitted] notifications_dashboard
120 notifications_dashboard.9861b4d326fc6013d07a.bundle.js.map 10.3 KiB 31 [emitted] notifications_dashboard
121 notifications_dashboard.html 3.8 KiB [emitted]
122 practice_session.2b3df5cd3a773d25dccd.bundle.js 353 KiB 32, 9 [emitted] [big] practice_session
123 practice_session.2b3df5cd3a773d25dccd.bundle.js.map 1.03 MiB 32, 9 [emitted] practice_session
124 practice_session.html 4.12 KiB [emitted]
125 preferences.7bc02eeb17ebbbc9f185.bundle.js 10.4 KiB 33 [emitted] preferences
126 preferences.7bc02eeb17ebbbc9f185.bundle.js.map 46.6 KiB 33 [emitted] preferences
127 preferences.html 13.6 KiB [emitted]
128 privacy.html 19.9 KiB [emitted]
129 profile.a1bb8f12366e7119d0cd.bundle.js 7.45 KiB 34 [emitted] profile
130 profile.a1bb8f12366e7119d0cd.bundle.js.map 30.6 KiB 34 [emitted] profile
131 profile.html 13.1 KiB [emitted]
132 signup.11bb671f004fd8d863eb.bundle.js 11.7 KiB 35 [emitted] signup
133 signup.11bb671f004fd8d863eb.bundle.js.map 48.7 KiB 35 [emitted] signup
134 signup.html 4.88 KiB [emitted]
135 skill_editor.d598793dd751f4c60048.bundle.js 408 KiB 36 [emitted] [big] skill_editor
136 skill_editor.d598793dd751f4c60048.bundle.js.map 1.28 MiB 36 [emitted] skill_editor
137 skill_editor.html 5.68 KiB [emitted]
138 splash.52d4f9b9cd1e6bb57ad6.bundle.js 6.82 KiB 37 [emitted] splash
139 splash.52d4f9b9cd1e6bb57ad6.bundle.js.map 28.8 KiB 37 [emitted] splash
140 splash.html 13.3 KiB [emitted]
141 splash_at0.html 13.9 KiB [emitted]
142 splash_at1.html 13.9 KiB [emitted]
143 stewards.13f9d44828df98c384f1.bundle.js 9.19 KiB 38 [emitted] stewards
144 stewards.13f9d44828df98c384f1.bundle.js.map 37.8 KiB 38 [emitted] stewards
145 story_editor.b7304564e379a11e0d00.bundle.js 40.3 KiB 39 [emitted] story_editor
146 story_editor.b7304564e379a11e0d00.bundle.js.map 185 KiB 39 [emitted] story_editor
147 story_editor.html 2.57 KiB [emitted]
148 teach.be72aeaa2d7c1d32497f.bundle.js 6.48 KiB 40 [emitted] teach
149 teach.be72aeaa2d7c1d32497f.bundle.js.map 27.3 KiB 40 [emitted] teach
150 teach.html 7.33 KiB [emitted]
151 terms.html 14.5 KiB [emitted]
152 thanks.074b47a12a2aee714649.bundle.js 2.11 KiB 41 [emitted] thanks
153 thanks.074b47a12a2aee714649.bundle.js.map 11.4 KiB 41 [emitted] thanks
154 thanks.html 1.78 KiB [emitted]
155 topic_editor.5ac5a9d5ae63376009be.bundle.js 407 KiB 42 [emitted] [big] topic_editor
156 topic_editor.5ac5a9d5ae63376009be.bundle.js.map 1.29 MiB 42 [emitted] topic_editor
157 topic_editor.html 5.72 KiB [emitted]
158 topic_landing_page.html 26.5 KiB [emitted]
159 topic_viewer.e3e4af7c1cf85e42c159.bundle.js 7.81 KiB 43 [emitted] topic_viewer
160 topic_viewer.e3e4af7c1cf85e42c159.bundle.js.map 37.6 KiB 43 [emitted] topic_viewer
161 topic_viewer.html 3.93 KiB [emitted]
162 topics_and_skills_dashboard.34e504452028348bdfbf.bundle.js 16.1 KiB 44 [emitted] topics_and_skills_dashboard
163 topics_and_skills_dashboard.34e504452028348bdfbf.bundle.js.map 73.1 KiB 44 [emitted] topics_and_skills_dashboard
164 topics_and_skills_dashboard.html 7.91 KiB [emitted]
165Entrypoint about = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map about.73a5afcdf8e5cf9f911a.bundle.js about.73a5afcdf8e5cf9f911a.bundle.js.map
166Entrypoint admin = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map admin.0e43f157c75de87dda41.bundle.js admin.0e43f157c75de87dda41.bundle.js.map
167Entrypoint app = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map app~library.3bd713e5f19772d7b250.bundle.js app~library.3bd713e5f19772d7b250.bundle.js.map app.3a832a81c9290cfe0045.bundle.js app.3a832a81c9290cfe0045.bundle.js.map
168Entrypoint collection_editor = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js.map collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js.map collection_editor~collection_player.b9979b856a928d9f3787.bundle.js collection_editor~collection_player.b9979b856a928d9f3787.bundle.js.map collection_editor.d5d7c2da902175f981e4.bundle.js collection_editor.d5d7c2da902175f981e4.bundle.js.map
169Entrypoint collection_player = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js.map collection_editor~collection_player.b9979b856a928d9f3787.bundle.js collection_editor~collection_player.b9979b856a928d9f3787.bundle.js.map collection_player.9c68812dfdf7e51f76a1.bundle.js collection_player.9c68812dfdf7e51f76a1.bundle.js.map
170Entrypoint contact = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map contact.69ca35e967b2c6062897.bundle.js contact.69ca35e967b2c6062897.bundle.js.map
171Entrypoint creator_dashboard [big] = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js.map creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js.map creator_dashboard.9a0a34f7a5478e77dc79.bundle.js creator_dashboard.9a0a34f7a5478e77dc79.bundle.js.map
172Entrypoint donate = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map donate.89e271003ca58f551b56.bundle.js donate.89e271003ca58f551b56.bundle.js.map
173Entrypoint email_dashboard = email_dashboard.ce2048523411200df68f.bundle.js email_dashboard.ce2048523411200df68f.bundle.js.map
174Entrypoint email_dashboard_result = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map email_dashboard_result.600fc837d2bd509301f0.bundle.js email_dashboard_result.600fc837d2bd509301f0.bundle.js.map
175Entrypoint error = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map error.54cbece5212834d34ec0.bundle.js error.54cbece5212834d34ec0.bundle.js.map
176Entrypoint exploration_editor [big] = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js.map creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js.map exploration_editor.07de01208fc08d5292d7.bundle.js exploration_editor.07de01208fc08d5292d7.bundle.js.map
177Entrypoint exploration_player [big] = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js.map creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js.map exploration_player.8d4cea35e36127c5d4ae.bundle.js exploration_player.8d4cea35e36127c5d4ae.bundle.js.map
178Entrypoint get_started = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map get_started.44ae16fbbf31c5a61652.bundle.js get_started.44ae16fbbf31c5a61652.bundle.js.map
179Entrypoint landing = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map landing.73de90c66695e4b1897f.bundle.js landing.73de90c66695e4b1897f.bundle.js.map
180Entrypoint learner_dashboard = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js.map learner_dashboard.155cb54d3808ca72e628.bundle.js learner_dashboard.155cb54d3808ca72e628.bundle.js.map
181Entrypoint library = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js.map app~library.3bd713e5f19772d7b250.bundle.js app~library.3bd713e5f19772d7b250.bundle.js.map library.7b16e07d3aaf40c9b8f6.bundle.js library.7b16e07d3aaf40c9b8f6.bundle.js.map
182Entrypoint maintenance = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map maintenance.f7488f6c9b6471e499ab.bundle.js maintenance.f7488f6c9b6471e499ab.bundle.js.map
183Entrypoint moderator = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map moderator.ec4f8d6c4e5cd05677ba.bundle.js moderator.ec4f8d6c4e5cd05677ba.bundle.js.map
184Entrypoint notifications_dashboard = notifications_dashboard.9861b4d326fc6013d07a.bundle.js notifications_dashboard.9861b4d326fc6013d07a.bundle.js.map
185Entrypoint practice_session [big] = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js.map creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js.map practice_session.2b3df5cd3a773d25dccd.bundle.js practice_session.2b3df5cd3a773d25dccd.bundle.js.map
186Entrypoint preferences = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map preferences.7bc02eeb17ebbbc9f185.bundle.js preferences.7bc02eeb17ebbbc9f185.bundle.js.map
187Entrypoint profile = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js.map collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js collection_player~learner_dashboard~library~profile.c973f6bb2b00504932f3.bundle.js.map profile.a1bb8f12366e7119d0cd.bundle.js profile.a1bb8f12366e7119d0cd.bundle.js.map
188Entrypoint signup = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map signup.11bb671f004fd8d863eb.bundle.js signup.11bb671f004fd8d863eb.bundle.js.map
189Entrypoint skill_editor [big] = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js.map creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js.map collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js.map skill_editor.d598793dd751f4c60048.bundle.js skill_editor.d598793dd751f4c60048.bundle.js.map
190Entrypoint splash = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map splash.52d4f9b9cd1e6bb57ad6.bundle.js splash.52d4f9b9cd1e6bb57ad6.bundle.js.map
191Entrypoint stewards = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map stewards.13f9d44828df98c384f1.bundle.js stewards.13f9d44828df98c384f1.bundle.js.map
192Entrypoint story_editor = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js.map collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js.map story_editor.b7304564e379a11e0d00.bundle.js story_editor.b7304564e379a11e0d00.bundle.js.map
193Entrypoint teach = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map teach.be72aeaa2d7c1d32497f.bundle.js teach.be72aeaa2d7c1d32497f.bundle.js.map
194Entrypoint thanks = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map thanks.074b47a12a2aee714649.bundle.js thanks.074b47a12a2aee714649.bundle.js.map
195Entrypoint topic_editor [big] = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js.map app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js.map admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js.map collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js.map creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js.map collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js.map topic_editor.5ac5a9d5ae63376009be.bundle.js topic_editor.5ac5a9d5ae63376009be.bundle.js.map
196Entrypoint topics_and_skills_dashboard = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map topics_and_skills_dashboard.34e504452028348bdfbf.bundle.js topics_and_skills_dashboard.34e504452028348bdfbf.bundle.js.map
197Entrypoint topic_viewer = about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js.map topic_viewer.e3e4af7c1cf85e42c159.bundle.js topic_viewer.e3e4af7c1cf85e42c159.bundle.js.map
198[294] ./core/templates/dev/head/pages/story_editor/StoryEditor.ts 6.04 KiB {39} [built]
199[309] ./core/templates/dev/head/pages/exploration_editor/ExplorationEditor.ts 29.4 KiB {23} [built]
200[318] ./core/templates/dev/head/pages/landing/TopicLandingPage.ts 4.51 KiB {26} [built]
201[326] ./core/templates/dev/head/pages/about/About.ts 3.59 KiB {12} [built]
202[327] ./core/templates/dev/head/pages/admin/Admin.ts 724 bytes {13} [built]
203[338] ./core/templates/dev/head/App.ts 14.9 KiB {14} [built]
204[350] ./core/templates/dev/head/pages/collection_editor/CollectionEditor.ts 905 bytes {15} [built]
205[371] ./core/templates/dev/head/pages/collection_player/CollectionPlayer.ts 885 bytes {16} [built]
206[377] ./core/templates/dev/head/pages/contact/Contact.ts 756 bytes {17} [built]
207[378] ./core/templates/dev/head/pages/creator_dashboard/CreatorDashboard.ts 23.9 KiB {18} [built]
208[381] ./core/templates/dev/head/pages/donate/Donate.ts 2.14 KiB {19} [built]
209[382] ./core/templates/dev/head/pages/email_dashboard/EmailDashboard.ts 3.72 KiB {20} [built]
210[384] ./core/templates/dev/head/pages/email_dashboard/EmailDashboardResult.ts 5.44 KiB {21} [built]
211[385] ./core/templates/dev/head/pages/error/Error.ts 1.14 KiB {22} [built]
212[432] ./core/templates/dev/head/pages/exploration_player/ExplorationPlayer.ts 4.09 KiB {24} [built]
213 + 481 hidden modules
214
215WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
216This can impact web performance.
217Assets:
218 creator_dashboard.9a0a34f7a5478e77dc79.bundle.js (391 KiB)
219 exploration_editor.07de01208fc08d5292d7.bundle.js (586 KiB)
220 exploration_player.8d4cea35e36127c5d4ae.bundle.js (352 KiB)
221 practice_session.2b3df5cd3a773d25dccd.bundle.js (353 KiB)
222 skill_editor.d598793dd751f4c60048.bundle.js (408 KiB)
223 topic_editor.5ac5a9d5ae63376009be.bundle.js (407 KiB)
224
225WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
226Entrypoints:
227 creator_dashboard (465 KiB)
228 about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js
229 admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js
230 app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js
231 collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js
232 admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js
233 collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js
234 collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js
235 creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js
236 creator_dashboard.9a0a34f7a5478e77dc79.bundle.js
237 exploration_editor (661 KiB)
238 about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js
239 admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js
240 app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js
241 collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js
242 admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js
243 collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js
244 collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js
245 creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js
246 exploration_editor.07de01208fc08d5292d7.bundle.js
247 exploration_player (427 KiB)
248 about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js
249 admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js
250 app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js
251 collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js
252 admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js
253 collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js
254 collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js
255 creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js
256 exploration_player.8d4cea35e36127c5d4ae.bundle.js
257 practice_session (428 KiB)
258 about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js
259 admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js
260 app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js
261 collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js
262 admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js
263 collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js
264 collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js
265 creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js
266 practice_session.2b3df5cd3a773d25dccd.bundle.js
267 skill_editor (480 KiB)
268 about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js
269 admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js
270 app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js
271 collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js
272 admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js
273 collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js
274 creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js
275 collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js
276 skill_editor.d598793dd751f4c60048.bundle.js
277 topic_editor (478 KiB)
278 about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js
279 admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js
280 app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js
281 collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js
282 admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js
283 collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js
284 creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js
285 collection_editor~skill_editor~story_editor~topic_editor.9a85b08cda6f2a16f377.bundle.js
286 topic_editor.5ac5a9d5ae63376009be.bundle.js
287
288
289WARNING in webpack performance recommendations:
290You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
291For more info visit https://webpack.js.org/guides/code-splitting/
292Child HtmlWebpackCompiler:
293 38 assets
294 Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0
295 Entrypoint HtmlWebpackPlugin_1 = __child-HtmlWebpackPlugin_1
296 Entrypoint HtmlWebpackPlugin_2 = __child-HtmlWebpackPlugin_2
297 Entrypoint HtmlWebpackPlugin_3 = __child-HtmlWebpackPlugin_3
298 Entrypoint HtmlWebpackPlugin_4 = __child-HtmlWebpackPlugin_4
299 Entrypoint HtmlWebpackPlugin_5 = __child-HtmlWebpackPlugin_5
300 Entrypoint HtmlWebpackPlugin_6 = __child-HtmlWebpackPlugin_6
301 Entrypoint HtmlWebpackPlugin_7 = __child-HtmlWebpackPlugin_7
302 Entrypoint HtmlWebpackPlugin_8 = __child-HtmlWebpackPlugin_8
303 Entrypoint HtmlWebpackPlugin_9 = __child-HtmlWebpackPlugin_9
304 Entrypoint HtmlWebpackPlugin_10 = __child-HtmlWebpackPlugin_10
305 Entrypoint HtmlWebpackPlugin_11 = __child-HtmlWebpackPlugin_11
306 Entrypoint HtmlWebpackPlugin_12 = __child-HtmlWebpackPlugin_12
307 Entrypoint HtmlWebpackPlugin_13 = __child-HtmlWebpackPlugin_13
308 Entrypoint HtmlWebpackPlugin_14 = __child-HtmlWebpackPlugin_14
309 Entrypoint HtmlWebpackPlugin_15 = __child-HtmlWebpackPlugin_15
310 Entrypoint HtmlWebpackPlugin_16 = __child-HtmlWebpackPlugin_16
311 Entrypoint HtmlWebpackPlugin_17 = __child-HtmlWebpackPlugin_17
312 Entrypoint HtmlWebpackPlugin_18 = __child-HtmlWebpackPlugin_18
313 Entrypoint HtmlWebpackPlugin_19 = __child-HtmlWebpackPlugin_19
314 Entrypoint HtmlWebpackPlugin_20 = __child-HtmlWebpackPlugin_20
315 Entrypoint HtmlWebpackPlugin_21 = __child-HtmlWebpackPlugin_21
316 Entrypoint HtmlWebpackPlugin_22 = __child-HtmlWebpackPlugin_22
317 Entrypoint HtmlWebpackPlugin_23 = __child-HtmlWebpackPlugin_23
318 Entrypoint HtmlWebpackPlugin_24 = __child-HtmlWebpackPlugin_24
319 Entrypoint HtmlWebpackPlugin_25 = __child-HtmlWebpackPlugin_25
320 Entrypoint HtmlWebpackPlugin_26 = __child-HtmlWebpackPlugin_26
321 Entrypoint HtmlWebpackPlugin_27 = __child-HtmlWebpackPlugin_27
322 Entrypoint HtmlWebpackPlugin_28 = __child-HtmlWebpackPlugin_28
323 Entrypoint HtmlWebpackPlugin_29 = __child-HtmlWebpackPlugin_29
324 Entrypoint HtmlWebpackPlugin_30 = __child-HtmlWebpackPlugin_30
325 Entrypoint HtmlWebpackPlugin_31 = __child-HtmlWebpackPlugin_31
326 Entrypoint HtmlWebpackPlugin_32 = __child-HtmlWebpackPlugin_32
327 Entrypoint HtmlWebpackPlugin_33 = __child-HtmlWebpackPlugin_33
328 Entrypoint HtmlWebpackPlugin_34 = __child-HtmlWebpackPlugin_34
329 Entrypoint HtmlWebpackPlugin_35 = __child-HtmlWebpackPlugin_35
330 Entrypoint HtmlWebpackPlugin_36 = __child-HtmlWebpackPlugin_36
331 Entrypoint HtmlWebpackPlugin_37 = __child-HtmlWebpackPlugin_37
332 [3] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/admin/admin.html 2.57 KiB {0} [built]
333 [4] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/base.html 8.57 KiB {1} [built]
334 [5] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/about/about.html 23.8 KiB {12} [built]
335 [6] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/collection_editor/collection_editor.html 1.66 KiB {23} [built]
336 [7] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/collection_player/collection_player.html 3.88 KiB {32} [built]
337 [8] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/tests/console_errors.html 358 bytes {33} [built]
338 [9] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/contact/contact.html 3.73 KiB {34} [built]
339 [10] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/creator_dashboard/creator_dashboard.html 37.7 KiB {35} [built]
340 [11] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/donate/donate.html 6.29 KiB {36} [built]
341 [12] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/email_dashboard/email_dashboard.html 3.78 KiB {37} [built]
342 [13] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/email_dashboard/email_dashboard_result.html 3.78 KiB {2} [built]
343 [14] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/error/error.html 3.02 KiB {3} [built]
344 [15] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/exploration_editor/exploration_editor.html 9.22 KiB {4} [built]
345 [16] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/exploration_player/exploration_player.html 4.1 KiB {5} [built]
346 [17] ./node_modules/html-webpack-plugin/lib/loader.js!./core/templates/dev/head/pages/get_started/get_started.html 3.6 KiB {6} [built]
347 + 26 hidden modules
348Building third party libs at third_party/generated/
349Compiling ts files...
35019:13:57 ERROR core.controllers.editor_test.EditorTests: 4.8 secs
351----------------------------------------
352----------------------------------------
353Error 1
354test_add_new_state_error_cases (core.controllers.editor_test.EditorTests) ... ERROR:root:This app cannot send emails to users.
355ERROR:root:Exception raised: Invalid POST request: a version must be specified.
356ERROR:root:Exception raised: Trying to update version 1 of exploration from version 123, which is too old. Please reload the page and try again.
357ERROR:root:Exception raised: The length of a state name should be between 1 and 50 characters; received
358ERROR:root:Exception raised: The length of a state name should be between 1 and 50 characters; received aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
359ERROR:root:Exception raised: Invalid character [ in a state name: [Bad State Name]
360ERROR:root:Exception raised: Names should not start or end with whitespace.
361ERROR:root:Exception raised: Names should not start or end with whitespace.
362ERROR:root:Exception raised: Names should not start or end with whitespace.
363ERROR:root:Exception raised: Adjacent whitespace in a state name should be collapsed.
364ERROR:root:Exception raised: Adjacent whitespace in a state name should be collapsed.
365ok
366test_editor_page (core.controllers.editor_test.EditorTests) ... ERROR:root:This app cannot send emails to users.
367FAIL
368test_new_state_template (core.controllers.editor_test.EditorTests) ... ERROR:root:This app cannot send emails to users.
369ok
370test_that_default_exploration_cannot_be_published (core.controllers.editor_test.EditorTests) ... ERROR:root:This app cannot send emails to users.
371ERROR:root:Exception raised: This state does not have any interaction specified.
372ok
373
374======================================================================
375FAIL: test_editor_page (core.controllers.editor_test.EditorTests)
376----------------------------------------------------------------------
377Traceback (most recent call last):
378 File "/home/thejedicode/oppia3/oppia/core/controllers/editor_test.py", line 149, in test_editor_page
379 self.assertIn('sss', response.body)
380AssertionError: 'sss' not found in '\n\n<!DOCTYPE html>\n<html ng-app="oppia" lang="<[currentLang]>" ng-controller="Base" itemscope itemtype="http://schema.org/Organization">\n <head>\n \n \n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=yes">\n <meta name="referrer" content="no-referrer">\n <meta name="description" content="Oppia is a free site for sharing knowledge via interactive lessons called explorations. Learn from user-created explorations, or teach and create your own.">\n\n <!-- Tiles for Internet Explorer. -->\n <meta name="application-name" content="<[siteName]>">\n <meta name="msapplication-TileColor" content="#ffffff">\n <meta name="msapplication-square70x70logo" content="http://localhost/assets/images/logo/msapplication-tiny.png">\n <meta name="msapplication-square150x150logo" content="http://localhost/assets/images/logo/msapplication-square.png">\n <meta name="msapplication-wide310x150logo" content="http://localhost/assets/images/logo/msapplication-wide.png">\n <meta name="msapplication-square310x310logo" content="http://localhost/assets/images/logo/msapplication-large.png">\n\n <!-- The itemprops are for G+ sharing. -->\n <meta itemprop="name" content="Personalized Online Learning from Oppia">\n <meta itemprop="description" content="Help others learn new things. Create lessons through explorations and share your knowledge with the community.">\n <!-- The og tags are for Facebook sharing. -->\n <meta property="og:title" content="Personalized Online Learning from Oppia">\n <meta property="og:site_name" content="Oppia">\n <meta property="og:url" content="http://localhost/create/0">\n <meta property="og:description" content="Help others learn new things. Create lessons through explorations and share your knowledge with the community.">\n <meta property="og:type" content="article">\n <meta property="og:image" content="http://localhost/assets/images/logo/288x288_logo_mint.png">\n\n <link rel="apple-touch-icon" href="/assets/images/logo/favicon.png">\n\n <title itemprop="name">\n \n Oppia\n \n </title>\n \n \n\n \n <link rel="stylesheet" type="text/css" media="screen"\n href="https://fonts.googleapis.com/css?family=Capriola|Roboto|Material+Icons">\n\n <link rel="stylesheet" type="text/css" media="screen"\n href="/third_party/generated/css/third_party.css">\n\n<link rel="stylesheet" type="text/css" media="screen"\n href="/templates/dev/head/css/oppia.css">\n \n\n <script>\n var GLOBALS = {\n ADDITIONAL_ANGULAR_MODULES: JSON.parse(\n \'[\\"ui-leaflet\\", \\"ui.codemirror\\"]\'),\n csrf_token: JSON.parse(\'\\"1559675635/5wjr78rde0tKCN_nEU7eIg==\\"\'),\n status_code: JSON.parse(\'200\'),\n GCS_RESOURCE_BUCKET_NAME: JSON.parse(\'null\'),\n isTopicManager: JSON.parse(\'false\'),\n userIsLoggedIn: JSON.parse(\'true\')\n };\n </script>\n\n \n \n <script src="/assets/rich_text_components_definitions.js"></script>\n<script src="/assets/constants.js"></script>\n\n<!-- jquery.js, angular.js and jquery-ui.js are removed from bundled js because\nthey need to be at the header. Including bundled js at the header will block\nrendering.-->\n<script src="/third_party/static/jquery-3.4.1/jquery.min.js"></script>\n<script src="/third_party/static/jqueryui-1.12.1/jquery-ui.min.js"></script>\n<script src="/third_party/static/angularjs-1.5.8/angular.min.js"></script>\n<script src="/third_party/static/jquery-ui-touch-punch-0.3.1/jquery.ui.touch-punch-improved.js"></script>\n<script src="/third_party/static/headroom-js-0.9.4/headroom.min.js"></script>\n<script src="/third_party/static/headroom-js-0.9.4/angular.headroom.min.js"></script>\n<script src="/third_party/static/angular-drag-and-drop-lists-2.1.0/angular-drag-and-drop-lists.min.js"></script>\n \n <script type="text/javascript">\n GLOBALS.can_edit = JSON.parse(\'true\');\n GLOBALS.can_publish = JSON.parse(\'false\');\n GLOBALS.can_voiceover = JSON.parse(\'true\');\n GLOBALS.DEFAULT_OBJECT_VALUES = JSON.parse(\n \'{\\"ListOfCoordTwoDim\\": [], \\"Graph\\": {\\"isWeighted\\": false, \\"isDirected\\": false, \\"edges\\": [], \\"isLabeled\\": false, \\"vertices\\": []}, \\"ListOfSetsOfHtmlStrings\\": [], \\"SetOfNormalizedString\\": [], \\"Fraction\\": {\\"denominator\\": 1, \\"numerator\\": 0, \\"wholeNumber\\": 0, \\"isNegative\\": false}, \\"CoordTwoDim\\": [0.0, 0.0], \\"Real\\": 0.0, \\"ListOfCodeEvaluation\\": [], \\"DragAndDropHtmlString\\": \\"\\", \\"LogicErrorCategory\\": \\"mistake\\", \\"DragAndDropPositiveInt\\": 1, \\"NormalizedString\\": \\"\\", \\"MusicPhrase\\": [], \\"ListOfGraph\\": [], \\"SetOfUnicodeString\\": [], \\"SetOfHtmlString\\": [], \\"NonnegativeInt\\": 0, \\"GraphProperty\\": \\"strongly_connected\\", \\"NumberWithUnits\\": {\\"real\\": 0.0, \\"units\\": [], \\"type\\": \\"real\\", \\"fraction\\": {\\"denominator\\": 1, \\"numerator\\": 0, \\"wholeNumber\\": 0, \\"isNegative\\": false}}, \\"Int\\": 0, \\"CodeString\\": \\"\\", \\"UnicodeString\\": \\"\\"}\');\n GLOBALS.DEFAULT_TWITTER_SHARE_MESSAGE_EDITOR = JSON.parse(\n \'\\"Check out this interactive lesson I created on Oppia - a free platform for teaching and learning!\\"\');\n GLOBALS.INTERACTION_SPECS = JSON.parse(\'{\\"ItemSelectionInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Item Selection\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"DoesNotContainAtLeastOneOf\\": \\"omits at least one of {{x|SetOfHtmlString}}\\", \\"ContainsAtLeastOneOf\\": \\"contains at least one of {{x|SetOfHtmlString}}\\", \\"IsProperSubsetOf\\": \\"is a proper subset of {{x|SetOfHtmlString}}\\", \\"Equals\\": \\"is equal to {{x|SetOfHtmlString}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": 1, \\"schema\\": {\\"type\\": \\"int\\", \\"validators\\": [{\\"min_value\\": 0, \\"id\\": \\"is_at_least\\"}]}, \\"name\\": \\"minAllowableSelectionCount\\", \\"description\\": \\"Minimum number of selections permitted.\\"}, {\\"default_value\\": 1, \\"schema\\": {\\"type\\": \\"int\\", \\"validators\\": [{\\"min_value\\": 1, \\"id\\": \\"is_at_least\\"}]}, \\"name\\": \\"maxAllowableSelectionCount\\", \\"description\\": \\"Maximum number of selections permitted\\"}, {\\"default_value\\": [\\"\\"], \\"schema\\": {\\"items\\": {\\"type\\": \\"html\\", \\"ui_config\\": {\\"hide_complex_extensions\\": true, \\"placeholder\\": \\"Sample item answer\\"}}, \\"type\\": \\"list\\", \\"ui_config\\": {\\"add_element_text\\": \\"Add item for selection\\"}}, \\"name\\": \\"choices\\", \\"description\\": \\"Items for selection\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"SetOfHtmlString\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"ItemSelectionInput\\", \\"description\\": \\"Allows learners to select various options.\\"}, \\"GraphInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Graph Theory\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsIsomorphicTo\\": \\"is isomorphic to {{g|Graph}}, including matching labels\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": {\\"isWeighted\\": false, \\"isDirected\\": false, \\"edges\\": [{\\"src\\": 0, \\"dst\\": 1, \\"weight\\": 1}, {\\"src\\": 1, \\"dst\\": 2, \\"weight\\": 1}], \\"isLabeled\\": false, \\"vertices\\": [{\\"y\\": 50.0, \\"x\\": 150.0, \\"label\\": \\"\\"}, {\\"y\\": 50.0, \\"x\\": 200.0, \\"label\\": \\"\\"}, {\\"y\\": 100.0, \\"x\\": 150.0, \\"label\\": \\"\\"}]}, \\"schema\\": {\\"obj_type\\": \\"Graph\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"graph\\", \\"description\\": \\"Initial graph\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canAddVertex\\", \\"description\\": \\"Allow learner to add vertices\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canDeleteVertex\\", \\"description\\": \\"Allow learner to delete vertices\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canMoveVertex\\", \\"description\\": \\"Allow learner to move vertices\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canEditVertexLabel\\", \\"description\\": \\"Allow learner to edit vertex labels\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canAddEdge\\", \\"description\\": \\"Allow learner to add edges\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canDeleteEdge\\", \\"description\\": \\"Allow learner to delete edges\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canEditEdgeWeight\\", \\"description\\": \\"Allow learner to edit edge weights\\"}], \\"narrow_instructions\\": \\"View graph\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"Graph\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Create a graph\\", \\"is_trainable\\": false, \\"id\\": \\"GraphInput\\", \\"description\\": \\"Allows learners to create and manipulate graphs.\\"}, \\"MathExpressionInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Math Expression Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsMathematicallyEquivalentTo\\": \\"is mathematically equivalent to (LaTeX) {{x|UnicodeString}}\\"}, \\"customization_arg_specs\\": [], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"MathExpression\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"MathExpressionInput\\", \\"description\\": \\"Allows learners to enter mathematical expressions.\\"}, \\"CodeRepl\\": {\\"is_terminal\\": false, \\"name\\": \\"Code Editor\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"CodeContains\\": \\"has code that contains {{x|CodeString}}\\", \\"OutputEquals\\": \\"has output equal to {{x|CodeString}}\\", \\"OutputContains\\": \\"has output that contains {{x|CodeString}}\\", \\"CodeEquals\\": \\"has code equal to {{x|CodeString}}\\", \\"CodeDoesNotContain\\": \\"has code that does not contain {{x|CodeString}}\\", \\"ResultsInError\\": \\"results in an error when run\\", \\"ErrorContains\\": \\"has error message that contains {{x|UnicodeString}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": \\"python\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"choices\\": [\\"python\\"]}, \\"name\\": \\"language\\", \\"description\\": \\"Programming language\\"}, {\\"default_value\\": \\"# Type your code here.\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"ui_config\\": {\\"coding_mode\\": \\"none\\"}}, \\"name\\": \\"placeholder\\", \\"description\\": \\"Initial code displayed\\"}, {\\"default_value\\": \\"\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"ui_config\\": {\\"coding_mode\\": \\"none\\"}}, \\"name\\": \\"preCode\\", \\"description\\": \\"Code to prepend to the learner\\\'s submission\\"}, {\\"default_value\\": \\"\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"ui_config\\": {\\"coding_mode\\": \\"none\\"}}, \\"name\\": \\"postCode\\", \\"description\\": \\"Code to append after the learner\\\'s submission\\"}], \\"narrow_instructions\\": \\"Go to code editor\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"CodeEvaluation\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Type code in the editor\\", \\"is_trainable\\": true, \\"id\\": \\"CodeRepl\\", \\"description\\": \\"Allows learners to enter code and get it evaluated.\\"}, \\"FractionInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Fraction Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsEquivalentToAndInSimplestForm\\": \\"is equivalent to {{f|Fraction}} and in simplest form\\", \\"HasIntegerPartEqualTo\\": \\"has integer part equal to {{x|Int}}\\", \\"IsLessThan\\": \\"is less than {{f|Fraction}}\\", \\"IsEquivalentTo\\": \\"is equivalent to {{f|Fraction}}\\", \\"HasDenominatorEqualTo\\": \\"has denominator equal to {{x|NonnegativeInt}}\\", \\"HasNumeratorEqualTo\\": \\"has numerator equal to {{x|Int}}\\", \\"HasNoFractionalPart\\": \\"has no fractional part\\", \\"HasFractionalPartExactlyEqualTo\\": \\"has fractional part exactly equal to {{f|Fraction}}\\", \\"IsGreaterThan\\": \\"is greater than {{f|Fraction}}\\", \\"IsExactlyEqualTo\\": \\"exactly matches {{f|Fraction}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"requireSimplestForm\\", \\"description\\": \\"Require the learner\\\'s answer to be in simplest form\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"allowImproperFraction\\", \\"description\\": \\"Allow improper fractions in the learner\\\'s answer\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"allowNonzeroIntegerPart\\", \\"description\\": \\"Allow the answer to contain an integer part\\"}, {\\"default_value\\": \\"\\", \\"schema\\": {\\"type\\": \\"unicode\\"}, \\"name\\": \\"customPlaceholder\\", \\"description\\": \\"Custom placeholder text (optional)\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"Fraction\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"FractionInput\\", \\"description\\": \\"Allows learners to enter integers and fractions.\\"}, \\"ImageClickInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Image Region\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsInRegion\\": \\"is in the region {{x|UnicodeString}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": {\\"labeledRegions\\": [], \\"imagePath\\": \\"\\"}, \\"schema\\": {\\"obj_type\\": \\"ImageWithRegions\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"imageAndRegions\\", \\"description\\": \\"Image\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"highlightRegionsOnHover\\", \\"description\\": \\"Highlight regions when the learner hovers over them\\"}], \\"narrow_instructions\\": \\"View image\\", \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"ClickOnImage\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Click on the image\\", \\"is_trainable\\": false, \\"id\\": \\"ImageClickInput\\", \\"description\\": \\"Allows learners to click on regions of an image.\\"}, \\"LogicProof\\": {\\"is_terminal\\": false, \\"name\\": \\"Logic Proof\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"NotCorrectByCategory\\": \\"is not correct due to {{c|LogicErrorCategory}}\\", \\"Correct\\": \\"is correct\\", \\"NotCorrect\\": \\"is not correct\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": {\\"assumptions\\": [{\\"arguments\\": [], \\"dummies\\": [], \\"top_kind_name\\": \\"variable\\", \\"top_operator_name\\": \\"p\\"}], \\"default_proof_string\\": \\"\\", \\"results\\": [{\\"arguments\\": [], \\"dummies\\": [], \\"top_kind_name\\": \\"variable\\", \\"top_operator_name\\": \\"p\\"}]}, \\"schema\\": {\\"obj_type\\": \\"LogicQuestion\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"question\\", \\"description\\": \\"Question to ask\\"}], \\"narrow_instructions\\": \\"Construct a proof\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"CheckedProof\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Construct a proof\\", \\"is_trainable\\": false, \\"id\\": \\"LogicProof\\", \\"description\\": \\"Allows learners to write proofs for simple logical statements.\\"}, \\"MultipleChoiceInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Multiple Choice\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"Equals\\": \\"is equal to {{x|NonnegativeInt}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": [\\"\\"], \\"schema\\": {\\"items\\": {\\"type\\": \\"html\\", \\"ui_config\\": {\\"hide_complex_extensions\\": true, \\"placeholder\\": \\"Enter an option for the learner to select\\"}}, \\"type\\": \\"list\\", \\"ui_config\\": {\\"add_element_text\\": \\"Add multiple choice option\\"}, \\"validators\\": [{\\"min_value\\": 1, \\"id\\": \\"has_length_at_least\\"}]}, \\"name\\": \\"choices\\", \\"description\\": \\"Multiple Choice options\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"NonnegativeInt\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"MultipleChoiceInput\\", \\"description\\": \\"Allows learners to select one of a list of multiple-choice options.\\"}, \\"DragAndDropSortInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Drag And Drop Sort\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsEqualToOrdering\\": \\"is equal to ordering {{x|ListOfSetsOfHtmlStrings}}\\", \\"HasElementXBeforeElementY\\": \\"has element {{x|DragAndDropHtmlString}} before element {{y|DragAndDropHtmlString}}\\", \\"IsEqualToOrderingWithOneItemAtIncorrectPosition\\": \\"is equal to ordering with one item at incorrect position {{x|ListOfSetsOfHtmlStrings}}\\", \\"HasElementXAtPositionY\\": \\"has element {{x|DragAndDropHtmlString}} at position {{y|DragAndDropPositiveInt}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": [\\"\\"], \\"schema\\": {\\"items\\": {\\"type\\": \\"html\\", \\"ui_config\\": {\\"hide_complex_extensions\\": true, \\"placeholder\\": \\"Enter an option for the learner to drag and drop.\\"}}, \\"type\\": \\"list\\", \\"ui_config\\": {\\"add_element_text\\": \\"Add a new item\\"}, \\"validators\\": [{\\"min_value\\": 1, \\"id\\": \\"has_length_at_least\\"}]}, \\"name\\": \\"choices\\", \\"description\\": \\"Items for drag and drop\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"allowMultipleItemsInSamePosition\\", \\"description\\": \\"Allow multiple sort items in the same position\\"}], \\"narrow_instructions\\": \\"Drag and drop items\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"ListOfSetsOfHtmlStrings\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Drag and drop items\\", \\"is_trainable\\": false, \\"id\\": \\"DragAndDropSortInput\\", \\"description\\": \\"Allows learners to drag and drop items for sorting.\\"}, \\"PencilCodeEditor\\": {\\"is_terminal\\": false, \\"name\\": \\"Pencil Code Editor\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"CodeContains\\": \\"has code that contains {{x|CodeString}}\\", \\"OutputEquals\\": \\"has output equal to {{x|CodeString}}\\", \\"CodeEquals\\": \\"has code equal to {{x|CodeString}}\\", \\"CodeDoesNotContain\\": \\"has code that does not contain {{x|CodeString}}\\", \\"ResultsInError\\": \\"results in an error when run\\", \\"ErrorContains\\": \\"has error message that contains {{x|UnicodeString}}\\", \\"OutputRoughlyEquals\\": \\"has output equal to {{x|CodeString}}, ignoring spacing and case\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": \\"# Add the initial code snippet here.\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"ui_config\\": {\\"coding_mode\\": \\"coffeescript\\"}}, \\"name\\": \\"initial_code\\", \\"description\\": \\"The initial code\\"}], \\"narrow_instructions\\": \\"Show code editor\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"CodeEvaluation\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Edit the code. Click \\\'Play\\\' to check it!\\", \\"is_trainable\\": false, \\"id\\": \\"PencilCodeEditor\\", \\"description\\": \\"Allows learners to edit code in Pencil Code.\\"}, \\"EndExploration\\": {\\"is_terminal\\": true, \\"name\\": \\"End Exploration\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {}, \\"customization_arg_specs\\": [{\\"default_value\\": [], \\"schema\\": {\\"items\\": {\\"type\\": \\"unicode\\"}, \\"type\\": \\"list\\", \\"ui_config\\": {\\"add_element_text\\": \\"Add exploration ID\\"}}, \\"name\\": \\"recommendedExplorationIds\\", \\"description\\": \\"IDs of explorations to recommend to the learner (at most 3 are shown). The ID of an exploration is the string of characters appearing after \\\'/explore/\\\' in the URL bar.\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": null, \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"EndExploration\\", \\"description\\": \\"Ends the exploration, and suggests recommendations for explorations to try next.\\"}, \\"InteractiveMap\\": {\\"is_terminal\\": false, \\"name\\": \\"World Map\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"Within\\": \\"is within {{d|Real}} km of {{p|CoordTwoDim}}\\", \\"NotWithin\\": \\"is not within {{d|Real}} km of {{p|CoordTwoDim}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": 0.0, \\"schema\\": {\\"type\\": \\"float\\", \\"validators\\": [{\\"min_value\\": -90.0, \\"id\\": \\"is_at_least\\"}, {\\"max_value\\": 90.0, \\"id\\": \\"is_at_most\\"}]}, \\"name\\": \\"latitude\\", \\"description\\": \\"Starting center latitude (-90 to 90)\\"}, {\\"default_value\\": 0.0, \\"schema\\": {\\"type\\": \\"float\\", \\"validators\\": [{\\"min_value\\": -180.0, \\"id\\": \\"is_at_least\\"}, {\\"max_value\\": 180.0, \\"id\\": \\"is_at_most\\"}]}, \\"name\\": \\"longitude\\", \\"description\\": \\"Starting center longitude (-180 to 180)\\"}, {\\"default_value\\": 0.0, \\"schema\\": {\\"type\\": \\"float\\"}, \\"name\\": \\"zoom\\", \\"description\\": \\"Starting zoom level (0 shows the entire earth)\\"}], \\"narrow_instructions\\": \\"View map\\", \\"can_have_solution\\": false, \\"needs_summary\\": true, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"CoordTwoDim\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Click on the map\\", \\"is_trainable\\": false, \\"id\\": \\"InteractiveMap\\", \\"description\\": \\"Allows learners to specify a position on a world map.\\"}, \\"Continue\\": {\\"is_terminal\\": false, \\"name\\": \\"Continue Button\\", \\"default_outcome_heading\\": \\"When the button is clicked\\", \\"rule_descriptions\\": {}, \\"customization_arg_specs\\": [{\\"default_value\\": \\"Continue\\", \\"schema\\": {\\"type\\": \\"unicode\\"}, \\"name\\": \\"buttonText\\", \\"description\\": \\"Button label\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": null, \\"display_mode\\": \\"inline\\", \\"is_linear\\": true, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"Continue\\", \\"description\\": \\"A simple \\\'go to next state\\\' button.\\"}, \\"SetInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Set Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsSubsetOf\\": \\"is a proper subset of {{x|SetOfUnicodeString}}\\", \\"IsDisjointFrom\\": \\"has no elements in common with {{x|SetOfUnicodeString}}\\", \\"Equals\\": \\"is equal to {{x|SetOfUnicodeString}}\\", \\"OmitsElementsIn\\": \\"omits some elements of {{x|SetOfUnicodeString}}\\", \\"IsSupersetOf\\": \\"is a proper superset of {{x|SetOfUnicodeString}}\\", \\"HasElementsIn\\": \\"has elements in common with {{x|SetOfUnicodeString}}\\", \\"HasElementsNotIn\\": \\"has elements not in {{x|SetOfUnicodeString}}\\"}, \\"customization_arg_specs\\": [], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"SetOfUnicodeString\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"SetInput\\", \\"description\\": \\"Allows learners to enter an unordered set of strings.\\"}, \\"TextInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Text Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"CaseSensitiveEquals\\": \\"is equal to {{x|NormalizedString}}, taking case into account\\", \\"StartsWith\\": \\"starts with {{x|NormalizedString}}\\", \\"Contains\\": \\"contains {{x|NormalizedString}}\\", \\"FuzzyEquals\\": \\"is equal to {{x|NormalizedString}}, misspelled by at most one character\\", \\"Equals\\": \\"is equal to {{x|NormalizedString}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": \\"\\", \\"schema\\": {\\"type\\": \\"unicode\\"}, \\"name\\": \\"placeholder\\", \\"description\\": \\"Placeholder text (optional)\\"}, {\\"default_value\\": 1, \\"schema\\": {\\"type\\": \\"int\\", \\"validators\\": [{\\"min_value\\": 1, \\"id\\": \\"is_at_least\\"}, {\\"max_value\\": 200, \\"id\\": \\"is_at_most\\"}]}, \\"name\\": \\"rows\\", \\"description\\": \\"Height (in rows)\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"NormalizedString\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": true, \\"id\\": \\"TextInput\\", \\"description\\": \\"Allows learners to enter arbitrary text strings.\\"}, \\"NumberWithUnits\\": {\\"is_terminal\\": false, \\"name\\": \\"Number With Units\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsEqualTo\\": \\"is equal to {{f|NumberWithUnits}}\\", \\"IsEquivalentTo\\": \\"is equivalent to {{f|NumberWithUnits}}\\"}, \\"customization_arg_specs\\": [], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"NumberWithUnits\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"NumberWithUnits\\", \\"description\\": \\"Allows learners to enter number with units.\\"}, \\"NumericInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Number Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsGreaterThanOrEqualTo\\": \\"is greater than or equal to {{x|Real}}\\", \\"IsLessThanOrEqualTo\\": \\"is less than or equal to {{x|Real}}\\", \\"Equals\\": \\"is equal to {{x|Real}}\\", \\"IsLessThan\\": \\"is less than {{x|Real}}\\", \\"IsGreaterThan\\": \\"is greater than {{x|Real}}\\", \\"IsWithinTolerance\\": \\"is within {{tol|Real}} of {{x|Real}}\\", \\"IsInclusivelyBetween\\": \\"is between {{a|Real}} and {{b|Real}}, inclusive\\"}, \\"customization_arg_specs\\": [], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"Real\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"NumericInput\\", \\"description\\": \\"Allows learners to enter integers and floating point numbers.\\"}, \\"MusicNotesInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Music Notes Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsTranspositionOf\\": \\"is a transposition of {{x|MusicPhrase}} by {{y|Int}} semitones\\", \\"HasLengthInclusivelyBetween\\": \\"has between {{a|NonnegativeInt}} and {{b|NonnegativeInt}} notes, inclusive\\", \\"Equals\\": \\"is equal to {{x|MusicPhrase}}\\", \\"IsEqualToExceptFor\\": \\"is equal to {{x|MusicPhrase}} except for {{k|NonnegativeInt}} notes\\", \\"IsTranspositionOfExceptFor\\": \\"is a transposition of {{x|MusicPhrase}} by {{y|Int}} semitones except for {{k|NonnegativeInt}} notes\\", \\"IsLongerThan\\": \\"has more than {{k|NonnegativeInt}} notes\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": [], \\"schema\\": {\\"obj_type\\": \\"MusicPhrase\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"sequenceToGuess\\", \\"description\\": \\"Correct sequence of notes\\"}, {\\"default_value\\": [], \\"schema\\": {\\"obj_type\\": \\"MusicPhrase\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"initialSequence\\", \\"description\\": \\"Starting notes on the staff\\"}], \\"narrow_instructions\\": \\"Show music staff\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"MusicPhrase\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Drag notes to the staff to form a sequence\\", \\"is_trainable\\": false, \\"id\\": \\"MusicNotesInput\\", \\"description\\": \\"Allows learners to drag and drop notes onto the lines of a music staff.\\"}}\');\n GLOBALS.INVALID_PARAMETER_NAMES = JSON.parse(\n \'[\\"answer\\", \\"choices\\", \\"abs\\", \\"all\\", \\"and\\", \\"any\\", \\"else\\", \\"floor\\", \\"if\\", \\"log\\", \\"or\\", \\"pow\\", \\"round\\", \\"then\\"]\');\n GLOBALS.SHOW_TRAINABLE_UNRESOLVED_ANSWERS = JSON.parse(\n \'false\');\n GLOBALS.TAG_REGEX = JSON.parse(\'\\"^[a-z ]+$\\"\');\n GLOBALS.canDelete = JSON.parse(\'false\');\n GLOBALS.canModifyRoles = JSON.parse(\'false\');\n GLOBALS.canReleaseOwnership = JSON.parse(\n \'false\');\n GLOBALS.canUnpublish = JSON.parse(\'false\');\n </script>\n\n <!-- Updated previous version to current version of google charts\n https://developers.google.com/chart/interactive/docs/basic_load_libs#update-library-loader-code -->\n <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>\n <script type="text/javascript">\n if (window.google && window.google.charts) {\n google.charts.load(\'current\', {packages: [\'corechart\']});\n } else {\n throw \'error: Could not load google visualization library. Are you offline?\';\n }\n </script>\n\n <style>\n html, body {\n background-color: #eee;\n }\n </style>\n\n\n\n \n </head>\n\n <body>\n <div ng-if="iframed">\n <div tabindex="0" aria-label="Oppia Main Content" id="oppia-main-content" class="protractor-test-main-content" ng-cloak>\n <div class="oppia-toast-container toast-top-center">\n <div ng-repeat="warning in (AlertsService.warnings | limitTo:5) track by $index" class="toast toast-warning oppia-toast">\n <button type="button" class="toast-close-button" ng-click="AlertsService.deleteWarning(warning)" role="button">×</button>\n <div class="toast-message">\n <[warning.content]>\n </div>\n </div>\n </div>\n\n <div>\n <div ng-repeat="message in AlertsService.messages track by $index">\n <alert-message message-object="message" message-index="$index"></alert-message>\n </div>\n </div>\n\n <div ng-show="loadingMessage" class="oppia-loading-fullpage">\n <div class="oppia-align-center">\n <span translate="<[loadingMessage]>"></span>\n <span class="oppia-loading-dot-one">.</span>\n <span class="oppia-loading-dot-two">.</span>\n <span class="oppia-loading-dot-three">.</span>\n </div>\n </div>\n <div ng-show="!loadingMessage">\n \n <div ng-controller="ExplorationEditor" ng-cloak>\n <div class="container-fluid oppia-editor-page-container" ng-joy-ride="tutorialInProgress" config="EDITOR_TUTORIAL_OPTIONS" on-finish="onFinishTutorial()" on-skip="onSkipTutorial()">\n <div class="row" ng-if="ExplorationRightsService.isCloned()">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div class="oppia-align-center uib-alert alert-warning" style="padding: 2px; width: 90%;">\n <strong>Note:</strong> This is a private, unpublishable copy of a\n <a ng-href="<[getExplorationUrl(ExplorationRightsService.clonedFrom())]>" target="_blank" rel="noopener">public exploration</a>.\n </div>\n </div>\n </div>\n\n <div ng-show="getActiveTabName() === \'main\'">\n <div class="row">\n <div class="col-lg-8 col-md-8 col-sm-8">\n <div ng-controller="ExplorationEditorTab" class="oppia-editor-cards-container">\n <div class="oppia-editor-header">\n <state-name-editor></state-name-editor>\n </div>\n\n <div ng-if="areParametersEnabled()">\n <state-param-changes-editor></state-param-changes-editor>\n </div>\n\n <state-editor on-save-state-content="saveStateContent"\n on-save-interaction-customization-args="saveInteractionCustomizationArgs"\n on-save-interaction-id="saveInteractionId"\n on-save-interaction-default-outcome="saveInteractionDefaultOutcome"\n on-save-interaction-answer-groups="saveInteractionAnswerGroups"\n on-save-solution="saveSolution"\n on-save-hints="saveHints"\n recompute-graph="recomputeGraph"\n show-mark-all-audio-as-needing-update-modal-if-required="showMarkAllAudioAsNeedingUpdateModalIfRequired"\n state-content-placeholder="getStateContentPlaceholder()"\n navigate-to-state="navigateToState"\n add-state="addState"\n refresh-warnings="refreshWarnings"\n interaction-is-shown="interactionIsShown">\n </state-editor>\n</div>\n </div>\n <div class="col-lg-4 col-md-4 col-sm-4">\n <div class="oppia-editor-sidebar hidden-xs hidden-sm">\n <div ng-controller="ExplorationGraph" ng-show="isGraphShown()" class="oppia-state-graph-animate-show">\n <span style="font-size: 16px;">\n <strong>Exploration Overview</strong>\n </span>\n\n <md-card style="background-color: white; margin: 20px 0px; padding: 8px;">\n <div class="oppia-state-graph-container protractor-test-exploration-graph">\n <div state-graph-visualization graph-data="getGraphData()" current-state-id="getActiveStateName()" on-click-function="onClickStateInMinimap" on-delete-function="deleteState" on-maximize-function="openStateGraphModal" allow-panning="true" center-at-current-state="true" style="height: 100%;" is-editable="isEditable()" show-warning-sign="true">\n </div>\n </div>\n </md-card>\n</div>\n <unresolved-answers-overview></unresolved-answers-overview>\n </div>\n </div>\n <attribution-guide></attribution-guide>\n</div>\n </div>\n\n <div ng-if="getActiveTabName() === \'translation\'">\n <translation-tab></translation-tab>\n </div>\n <!-- This is an ng-if, so that the preview loads the latest version of the exploration each time the tab is accessed. -->\n <div ng-if="getActiveTabName() === \'preview\'">\n <div ng-controller="PreviewTab">\n <div ng-if="isExplorationPopulated">\n <div ng-if="previewWarning">\n <div class="oppia-preview-state-warning"><[previewWarning]></div>\n </div>\n <conversation-skin></conversation-skin>\n <exploration-footer twitter-text=""></exploration-footer>\n\n </div>\n\n <div class="oppia-preview-bottom-right-container">\n <div class="oppia-parameter-summary" ng-if="showParameterSummary()">\n <strong>Parameters:</strong>\n <table>\n <tr ng-repeat="(paramName, paramValue) in allParams">\n <td style="padding: 1px 5px;"><[paramName]>:</td>\n <td style="padding: 1px 5px;">\n <[paramValue != "" ? paramValue : "[Not set]"]>\n </td>\n </tr>\n </table>\n </div>\n <button class="btn-lg" ng-click="resetPreview()">\n <i class="material-icons" style="margin-bottom: 2px;"></i>\n <span style="margin-left: 10px; padding-top: 20px;">Restart From Beginning</span>\n </button>\n </div>\n\n</div>\n\n<style>\n .oppia-preview-bottom-right-container {\n /* Fixed at bottom right corner (before footer) and appear on top of other div*/\n bottom: 10px;\n display: block;\n position: fixed;\n right: 0;\n padding-bottom: 2em;\n z-index: 1060;\n }\n\n .oppia-preview-bottom-right-container .oppia-parameter-summary {\n background-color: #fff;\n font-size: 16px;\n margin: 0px 0px 2px 0px;\n padding: 5px 0px 0px 5px;\n text-align: left;\n }\n\n .oppia-preview-bottom-right-container .btn-lg {\n background-color: #fff;\n border: none;\n border-radius: 0px;\n display: block;\n font-size: 20px;\n text-align: right;\n margin-top: 10px;\n padding-top: 10px;\n }\n\n .oppia-preview-state-warning {\n background-color: #fff;\n border: 1px solid #ccc;\n border-radius: 4px;\n display: block;\n font-size: 16px;\n font-weight: bold;\n left: 6px;\n max-width: 296px;\n padding: 3px;\n position: absolute;\n text-align: left;\n top: 63px;\n white-space: normal;\n z-index: 1060;\n }\n</style>\n </div>\n\n <div ng-show="getActiveTabName() === \'stats\'">\n <div ng-controller="StatisticsTab" ng-cloak>\n <md-card class="oppia-editor-card" ng-if="!loadingMessage">\n <div ng-if="explorationHasBeenVisited">\n <div class="oppia-statistics-display">\n <h3>Exploration Completion Rate</h3>\n <pie-chart data="pieChartData"\n options="COMPLETION_RATE_PIE_CHART_OPTIONS">\n </pie-chart>\n <p style="text-align: center;"><span ng-if="numPassersby" style="font-weight: bold;" class="protractor-test-num-passersby"><[numPassersby]></span><span ng-if="!numPassersby" style="font-weight: bold;">0</span> learners browsed this exploration. They left before reaching the second card.</p>\n\n <h3>Card statistics</h3>\n <div style="font-size: smaller" ng-if="lastUpdated">\n <em>Last updated: <[getLocaleAbbreviatedDatetimeString(lastUpdated)]></em>\n </div>\n <div class="container">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div state-graph-visualization graph-data="statsGraphData"\n node-fill="darkseagreen"\n highlight-states="highlightStates"\n state-stats="stateStats"\n on-click-function="onClickStateInStatsGraph">\n </div>\n </div>\n </div>\n <div class="container" ng-if="playthroughsAreAvailable">\n <playthrough-issues></playthrough-issues>\n </div>\n </div>\n </div>\n </div>\n <div ng-if="!explorationHasBeenVisited">\n <em>\n This exploration has not been visited by anyone yet, so there are no statistics to display.\n </em>\n </div>\n </md-card>\n</div>\n </div>\n\n <improvements-tab ng-if="getActiveTabName() === \'improvements\'">\n </improvements-tab>\n\n <div ng-show="getActiveTabName() === \'settings\'">\n <div ng-controller="SettingsTab">\n <md-card class="oppia-editor-card">\n <h3>Basic Settings</h3>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div ng-if="EditabilityService.isEditable()">\n <div role="form" class="form-horizontal">\n <exploration-title-editor label-text="Title"\n focus-label="<[::EXPLORATION_TITLE_INPUT_FOCUS_LABEL]>"\n form-style="<[::formStyle]>"\n on-input-field-blur="saveExplorationTitle()">\n </exploration-title-editor>\n <exploration-objective-editor label-text="Goal"\n form-style="<[::formStyle]>"\n on-input-field-blur="saveExplorationObjective()">\n </exploration-objective-editor>\n\n <div class="form-group" ng-class="{\'has-error\': !explorationCategoryService.displayed}">\n <label for="explorationCategory" class="col-lg-2 col-md-2 col-sm-2">Category</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <div ng-if="hasPageLoaded">\n <select2-dropdown id="explorationCategory"\n class="protractor-test-exploration-category-input"\n item="explorationCategoryService.displayed"\n choices="CATEGORY_LIST_FOR_SELECT2"\n placeholder="Choose or type new"\n new-choice-regex="^[A-Z a-z]+$"\n on-selection-change="saveExplorationCategory()"\n width="100%"\n invalid-search-term-message="Invalid category name">\n </select2-dropdown>\n </div>\n </div>\n </div>\n\n <div class="form-group">\n <label for="explorationLanguageCode" class="col-lg-2 col-md-2 col-sm-2">Language</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <select id="explorationLanguageCode" class="form-control protractor-test-exploration-language-select" ng-model="explorationLanguageCodeService.displayed" ng-change="saveExplorationLanguageCode()" ng-options="lc.code as lc.description for lc in explorationLanguageCodeService.getAllLanguageCodes()">\n </select>\n <span class="help-block" style="font-size: smaller">\n <em>\n Don\'t see the language you want? <a href="https://github.com/oppia/oppia/issues/new?title=Please%20add%20a%20new%20language%20choice%20to%20the%20exploration%20settings%20tab&body=Please%20add%20the%20language%20choice%20%7B%7BYOUR_LANGUAGE_HERE%7D%7D%20to%20the%20exploration%20settings%20tab.%0A%0AHere%20is%20a%20link%20to%20an%20exploration%20that%20uses%20it:%20%7B%7BINSERT_LINK_HERE%7D%7D" target="_blank" rel="noopener">Tell us.</a>\n </em>\n </span>\n </div>\n </div>\n <div class="form-group">\n <label for="explorationInitStateName" class="col-lg-2 col-md-2 col-sm-2">Name of first card</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <select id="explorationInitStateName" class="form-control protractor-test-initial-state-select" ng-model="explorationInitStateNameService.displayed" ng-change="saveExplorationInitStateName()" ng-options="name as name for name in stateNames track by name">\n </select>\n <span class="help-block" style="font-size: smaller">\n <em>This is the first card the learner sees when playing your exploration.</em>\n </span>\n </div>\n </div>\n <div class="form-group">\n <label for="explorationTags" class="col-lg-2 col-md-2 col-sm-2">Tags</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <div ng-if="hasPageLoaded">\n <select2-dropdown item="$parent.explorationTagsService.displayed"\n choices="$parent.explorationTagsService.displayed"\n allow-multiple-choices="true"\n invalid-search-term-message="Add a new tag (using lowercase letters and spaces)..."\n new-choice-regex="<[::TAG_REGEX]>"\n width="100%"\n placeholder="Skills, concepts, topics..."\n on-selection-change="saveExplorationTags()">\n </select2-dropdown>\n </div>\n <span class="help-block" style="font-size: smaller">\n <em>Tags help learners discover your exploration when searching.</em>\n </span>\n </div>\n </div>\n <div class="text-right">\n <button type="button" class="btn btn-default protractor-test-open-preview-summary-modal"\n ng-click="previewSummaryTile()"\n title="Preview this exploration\'s summary card">\n Preview Summary\n </button>\n </div>\n </div>\n </div>\n\n <div ng-if="!EditabilityService.isEditable()">\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationTitle">\n Title\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationTitle" type="text">\n <[explorationTitleService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationObjective">\n Goal\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationObjective" type="text">\n <[explorationObjectiveService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationCategory">\n Category\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationCategory" type="text">\n <[explorationCategoryService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationLanguageCode">Language</label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <[explorationLanguageCodeService.getCurrentLanguageDescription()]>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationInitStateName">First State</label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <[explorationInitStateNameService.displayed]>\n </div>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <h3>Advanced Features</h3>\n <div class="row">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableParameters" class="col-lg-10 col-md-10 col-sm-10">\n Parameters\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input span ng-if="areParametersEnabled()" type="checkbox" class="oppia-on-off-switch-checkbox" id="parameter-switch" checked disabled>\n <input span ng-if="!areParametersEnabled()" type="checkbox" class="oppia-on-off-switch-checkbox" id="parameter-switch" ng-click="enableParameters()">\n <label class="oppia-on-off-switch-label protractor-test-enable-parameters" for="parameter-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Parameters are values that change as the learner moves between cards (<a href="http://oppia.github.io/#/Parameters" target="_blank" rel="noopener">more info</a>).\n </span>\n </div>\n </div>\n </div>\n <hr>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableAutomaticTextToSpeech" class="col-lg-10 col-md-10 col-sm-10">\n Automatic Text-to-speech\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input type="checkbox" ng-if="isAutomaticTextToSpeechEnabled()" class="oppia-on-off-switch-checkbox" id="text-speech-switch" ng-click="toggleAutomaticTextToSpeech()" checked>\n <input type="checkbox" ng-if="!isAutomaticTextToSpeechEnabled()" class="oppia-on-off-switch-checkbox" id="text-speech-switch" ng-click="toggleAutomaticTextToSpeech()">\n <label class="oppia-on-off-switch-label" for="text-speech-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Automatic text-to-speech generates audio from your content for learners to listen to. It is recommended that you disable this feature if creating an exploration whose content consists of multiple languages.\n </span>\n </div>\n </div>\n </div>\n <hr>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableCorrectnessFeedback" class="col-lg-10 col-md-10 col-sm-10">\n Correctness Feedback\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input type="checkbox" ng-if="!isCorrectnessFeedbackEnabled()" class="oppia-on-off-switch-checkbox" id="correctness-switch" ng-click="toggleCorrectnessFeedback()">\n <input type="checkbox" ng-if="isCorrectnessFeedbackEnabled()" class="oppia-on-off-switch-checkbox" id="correctness-switch" ng-click="toggleCorrectnessFeedback()" checked>\n <label class="oppia-on-off-switch-label" for="correctness-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Correctness feedback allows the user to categorise answer groups as correct or incorrect.\n </span>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card">\n <div ng-if="ExplorationRightsService.ownerNames.length > 0 && !ExplorationRightsService.isCloned()">\n <div class="row">\n <div class="col-lg-5 col-md-5 col-sm-5">\n <h3>Roles</h3>\n <div ng-show="ExplorationRightsService.ownerNames.length > 0">\n <strong>Managers</strong>\n <ul>\n <li ng-repeat="ownerName in ExplorationRightsService.ownerNames track by $index">\n <[ownerName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.editorNames.length > 0">\n <strong>Collaborators</strong>\n <ul>\n <li ng-repeat="editorName in ExplorationRightsService.editorNames track by $index">\n <[editorName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.voiceArtistNames.length > 0">\n <strong>Voice Artists</strong>\n <ul>\n <li ng-repeat="voiceArtistName in ExplorationRightsService.voiceArtistNames track by $index">\n <[voiceArtistName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.viewerNames.length > 0">\n <strong>Playtesters</strong>\n <ul>\n <li ng-repeat="viewerName in ExplorationRightsService.viewerNames track by $index">\n <[viewerName]>\n </li>\n </ul>\n </div>\n\n\n <div ng-if="canModifyRoles" ng-hide="isRolesFormOpen">\n <button type="button" class="btn btn-default protractor-test-edit-roles" ng-click="openEditRolesForm()">\n Edit Roles\n </button>\n </div>\n\n <div ng-if="canModifyRoles" ng-show="isRolesFormOpen">\n <strong>Add or Change Role</strong>\n <div class="form-group">\n <form ng-submit="editRole(newMemberUsername, newMemberRole.value)">\n <label for="newMemberUsername">Username of invited user</label>\n <div>\n <input type="text" id="newMemberUsername" class="form-control protractor-test-role-username" ng-model="newMemberUsername" placeholder="editor">\n </div>\n <br>\n <label for="newMemberRole">Role of invited user</label>\n <div>\n <select ng-model="newMemberRole" class="form-control protractor-test-role-select" ng-options="r.name for r in ROLES" style="width: 250px;">\n </select>\n <span class="help-block">\n Note that managers also have the permissions of collaborators, collaborators also have the permissions of voice artists, and voice artists also have the permissions of viewers. Please note that assigning roles is irreversible (though you can always assign somebody to a higher role).\n </span>\n </div>\n\n <input type="submit" class="btn btn-default protractor-test-save-role" value="Save" ng-disabled="!isTitlePresent()">\n <button type="button" class="btn btn-default" ng-click="closeEditRolesForm()" ng-show="isRolesFormOpen">\n Cancel\n </button>\n <p ng-show="!isTitlePresent()" class="text-danger protractor-test-title-warning">Please provide a title before inviting.</p>\n </form>\n </div>\n </div>\n </div>\n\n <div class="col-lg-7 col-md-7 col-sm-7">\n <h3>Permissions</h3>\n <p ng-if="ExplorationRightsService.isPrivate() && ExplorationRightsService.viewableIfPrivate()">\n This exploration is <strong>private</strong>. Anyone with the link can access it.\n </p>\n <p ng-if="ExplorationRightsService.isPrivate() && !ExplorationRightsService.viewableIfPrivate()">\n This exploration is <strong>private</strong>. Only invited users, moderators and site admins can\n access it.\n </p>\n <p ng-if="!ExplorationRightsService.isPrivate()">\n This exploration is <strong>public</strong>: anyone can access it.\n </p>\n\n <p ng-if="!ExplorationRightsService.isPrivate() || ExplorationRightsService.viewableIfPrivate()">\n <em>Link to share:</em>\n <input class="form-control" type="text" value="<[getExplorePageUrl(explorationId)]>" readonly="readonly" onClick="this.select();">\n </p>\n\n <br>\n\n <p ng-if="ExplorationRightsService.isPrivate()">\n It is <strong>not shown</strong> in the Oppia library.\n </p>\n <p ng-if="!ExplorationRightsService.isPrivate()">\n It is <strong>available</strong> in the Oppia library.\n </p>\n </div>\n </div>\n </div>\n\n <div ng-if="ExplorationRightsService.ownerNames.length === 0 && !ExplorationRightsService.isCloned()">\n <h3>Permissions</h3>\n <div>\n This exploration is <strong>public</strong> and <strong>community-editable</strong>.\n <p ng-if="!ExplorationRightsService.isPrivate()">\n It is <strong>available</strong> in the Oppia library.\n </p>\n </div>\n </div>\n\n <div ng-if="ExplorationRightsService.isCloned()">\n <h3>Status</h3>\n <div>\n This exploration was <strong>cloned</strong> from another exploration.\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <h3>Feedback/Suggestion Email Preferences</h3>\n <div class="row">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="FeedbackNotifications" class="col-lg-3 col-md-3 col-sm-3">\n Feedback emails\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="muteFeedbackNotifications()" ng-if="!UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n Mute\n </button>\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="unmuteFeedbackNotifications()" ng-if="UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n Unmute\n </button>\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="!UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n You are currently receiving notifications of new feedback for this exploration.\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n You have muted feedback notifications for this exploration. You will not receive an email when new feedback is submitted.\n </span>\n </div>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="SuggestionNotifications" class="col-lg-3 col-md-3 col-sm-3">\n Suggestion emails\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="muteSuggestionNotifications()" ng-if="!UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n Mute\n </button>\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="unmuteSuggestionNotifications()" ng-if="UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n Unmute\n </button>\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="!UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n You are currently receiving notifications of new suggestions for this exploration.\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n You have muted suggestion notifications for this exploration. You will not receive an email when new suggestion is submitted.\n </span>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <div class="row">\n <div class="col-lg-6 col-md-6 col-sm-6">\n <h3>Controls</h3>\n\n <p ng-if="canReleaseOwnership" class="oppia-exploration-ctrl" ng-hide="ExplorationRightsService.isCommunityOwned()">\n <button type="button" class="btn btn-default" ng-click="showTransferExplorationOwnershipModal()" ng-disabled="isExplorationLockedForEditing()">\n Transfer ownership to the community\n </button>\n <span ng-if="isExplorationLockedForEditing()">\n <br>\n Please save your changes first.\n </span>\n </p>\n\n <p ng-if="canDelete" class="oppia-exploration-ctrl">\n <button type="button" ng-if="ExplorationRightsService.isPrivate()"\n class="btn btn-danger" ng-click="deleteExploration()"\n title="Delete this exploration">\n Delete Exploration\n </button>\n </p>\n </div>\n\n <div class="col-lg-6 col-md-6 col-sm-6" ng-if="currentUserIsAdmin || currentUserIsModerator">\n <h3>Admin Controls</h3>\n\n <p ng-if="canUnpublish" class="oppia-exploration-ctrl oppia-exploration-ctrl-admin" ng-show="ExplorationRightsService.isPublic()">\n <button type="button" class="btn btn-default" ng-click="unpublishExplorationAsModerator()" ng-disabled="isExplorationLockedForEditing()">\n Unpublish\n <span ng-if="currentUserIsAdmin">(as admin)</span>\n <span ng-if="!currentUserIsAdmin && currentUserIsModerator">(as moderator)</span>\n </button>\n </p>\n\n <p class="oppia-exploration-ctrl oppia-exploration-ctrl-admin" ng-if="ExplorationRightsService.isPublic() && (currentUserIsAdmin || currentUserIsModerator)">\n <button type="button" class="btn btn-danger protractor-test-delete-exploration-button"\n ng-click="deleteExploration()">\n Delete Exploration\n <span ng-if="currentUserIsAdmin">(as admin)</span>\n <span ng-if="!currentUserIsAdmin && currentUserIsModerator">(as moderator)</span>\n </button>\n </p>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="areParametersEnabled()">\n <h3>Parameters used in this exploration</h3>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div ng-show="isEmpty(explorationParamSpecsService.savedMemento.getParamDict())">\n <em>No parameters used.</em>\n </div>\n <ol>\n <li ng-repeat="(paramName, paramSpec) in explorationParamSpecsService.savedMemento.getParamDict()">\n <b><[paramName]></b> (<[paramSpec.getType().getName()]>)\n </li>\n </ol>\n </div>\n </div>\n\n <h3>\n Initial parameter changes\n <i class="material-icons md-18" uib-tooltip="These changes are applied before the learner begins the exploration."\n tooltip-placement="right" style="padding-left: 4px; vertical-align: text-top;">\n \n </i>\n </h3>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12 protractor-test-exploration-edit-param-changes">\n <param-changes-editor param-changes-service="explorationParamChangesService"\n post-save-hook="postSaveParamChangesHook"\n currently-in-settings-tab="true">\n </param-changes-editor>\n </div>\n </div>\n </md-card>\n</div>\n </div>\n\n <div ng-show="getActiveTabName() === \'history\'">\n <div ng-controller="HistoryTab" class="container-fluid" style="word-wrap: break-word;">\n <md-card class="oppia-editor-card">\n <h3>List of Changes</h3>\n <div ng-repeat="versionNumber in versionNumbersToDisplay" class="row">\n <div class="col-sm-4 col-md-4 col-lg-4">\n <input type="checkbox" name="compareVer" ng-model="versionCheckboxArray[versionNumber].selected" ng-init="init()" ng-click="changeSelectedVersions($event, versionNumber)" ng-disabled="isCheckboxDisabled(versionNumber)" ng-hide="comparisonsAreDisabled" class="protractor-test-history-checkbox-selector">\n [<[versionNumber]>]\n <strong><profile-link-text username="explorationVersionMetadata[versionNumber].committerId"></profile-link-text></strong>\n </div>\n <div class="col-sm-4 col-md-4 col-lg-4">\n <[explorationVersionMetadata[versionNumber].commitMessage]>\n </div>\n <div class="col-sm-4 col-md-4 col-lg-4">\n <span>\n <em><[explorationVersionMetadata[versionNumber].createdOnStr]></em>\n <span ng-if="versionNumber !== currentVersion && EditabilityService.isEditable()">\n | <a href="#" class="protractor-test-revert-version" ng-click="showRevertExplorationModal(versionNumber)">Revert</a>\n </span>\n <span>\n | <a href="#" ng-click="downloadExplorationWithVersion(versionNumber)" title="Download exploration as a zip file.">Download</a>\n </span>\n </span>\n </div>\n </div>\n\n <br>\n\n <div ng-hide="!explorationVersionMetadata || compareVersionsButtonIsHidden">\n <button class="btn protractor-test-show-history-graph" ng-class="{\'btn-success\': areCompareVersionsSelected(), \'btn-default\': !areCompareVersionsSelected()}" ng-click="compareSelectedVersions()" ng-disabled="!areCompareVersionsSelected()">Compare selected revisions</button>\n <div class="version-count-prompt">\n <[versionCountPrompt]>\n </div>\n </div>\n\n <div ng-show="versionCheckboxArray.length > VERSIONS_PER_PAGE" style="margin-top: 30px" uib-pagination boundary-links="true" class="pagination-sm" max-size="5" items-per-page="VERSIONS_PER_PAGE" total-items="versionCheckboxArray.length" ng-model="displayedCurrentPageNumber" ng-change="computeVersionsToDisplay()"></div>\n </md-card>\n\n <md-card class="oppia-editor-card" style="position: relative;"\n ng-if="diffData && !hideHistoryGraph && explorationVersionMetadata">\n <h3>\n Changes from version <[compareVersionMetadata.earlierVersion.versionNumber]>\n to version <[compareVersionMetadata.laterVersion.versionNumber]>\n </h3>\n\n <version-diff-visualization diff-data="diffData"\n earlier-version-header="earlierVersionHeader"\n later-version-header="laterVersionHeader">\n </version-diff-visualization>\n </md-card>\n</div>\n </div>\n\n <div ng-show="getActiveTabName() === \'feedback\'">\n <md-card class="oppia-editor-card oppia-feedback-card" ng-controller="FeedbackTab">\n <div ng-if="!activeThread">\n <div ng-if="threadData.suggestionThreads.length > 0">\n <h2>Suggestions from Learners</h2>\n <thread-table threads="threadData.suggestionThreads"\n on-click-row="setActiveThread">\n </thread-table>\n <br>\n </div>\n\n <div class="pull-right">\n <button ng-if="userIsLoggedIn" class="btn btn-success pull-right" ng-click="showCreateThreadModal()">\n Start new thread\n </button>\n </div>\n\n <h2>Exploration Feedback</h2>\n\n <div style="clear: both;"></div>\n\n <div ng-if="threadData.feedbackThreads.length === 0">\n <em>No feedback has been given for this exploration yet.</em>\n </div>\n\n <thread-table threads="threadData.feedbackThreads"\n on-click-row="setActiveThread">\n </thread-table>\n\n <em ng-if="!userIsLoggedIn">To create a new feedback thread, please log in.</em>\n </div>\n\n <div ng-if="activeThread">\n <div class="row">\n <div class="col-lg-9 col-md-9 col-sm-9">\n <span class="oppia-back-arrow">\n <button type="button" class="btn btn-default btn-xs protractor-test-oppia-feedback-back-button" ng-click="onBackButtonClicked()">\n <i class="material-icons oppia-vcenter" title="Return to list of feedback threads"></i>\n </button>\n </span>\n <span style="font-size: larger" ng-show="!activeThread.isSuggestionThread()">Feedback Thread: <[activeThread.subject]></span>\n <span style="font-size: larger" ng-show="activeThread.isSuggestionThread()">Suggestion Thread: <[activeThread.subject]></span>\n </div>\n\n <div style="float: right;" class="col-lg-5 col-md-5 col-sm-5">\n <div class="pull-right">\n <span ng-if="activeThread.stateName" class="label label-info">\n state: <[activeThread.stateName]>\n </span>\n <span ng-class="getLabelClass(activeThread.status)">\n <[getHumanReadableStatus(activeThread.status)]>\n </span>\n </div>\n </div>\n </div>\n\n <div class="row" ng-if="activeThread.messages">\n <div class="col-lg-12 col-md-12 col-sm-12 activeThreadView">\n <table class="table">\n <tr ng-repeat="m in activeThread.messages|orderBy:\'message_id\'">\n <td>\n <div class="row">\n <div class="col-lg-5 col-md-5 col-sm-5">\n <span ng-if="$index !== 0">#<[m.message_id]></span>\n <span ng-if="m.author_username">by <strong><[m.author_username]></strong></span>\n <span ng-if="!m.author_username">(anonymously submitted)</span>\n </div>\n\n <div class="col-lg-4 col-md-4 col-sm-4">\n <span ng-if="m.message_id !== 0">\n <span ng-if="m.updated_status">\n <em>Status changed to \'<[getHumanReadableStatus(m.updated_status)]>\'</em>\n </span>\n <span ng-if="m.updated_subject">\n <em>Subject changed to \'<[m.updated_subject]>\'</em>\n </span>\n </span>\n </div>\n\n <div class="col-lg-3 col-md-3 col-sm-3">\n <span><[getLocaleAbbreviatedDatetimeString(m.created_on)]></span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div style="white-space: pre-wrap;" class="protractor-test-exploration-feedback"><[m.text]></div>\n <div ng-if="activeThread.isSuggestionThread() && $index == 0">\n <button class="btn btn-<[getSuggestionButtonType()]> protractor-test-view-suggestion-btn" style="margin-top: 6px; margin-bottom: 6px" ng-click="showSuggestionModal()">\n View Suggestion\n </button>\n </div>\n </div>\n </div>\n </td>\n </tr>\n </table>\n </div>\n </div>\n\n\n <hr>\n\n <div class="row" ng-if="userIsLoggedIn">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div>\n <label for="tmpMessageText">\n Add new message\n <span ng-if="EditabilityService.isEditable() && !activeThread.isSuggestionThread()">(and/or change status)</span>\n </label>\n <textarea class="form-control protractor-test-feedback-response-textarea" ng-model="tmpMessage.text"\n id="tmpMessageText" rows="6"\n ng-disabled="messageSendingInProgress">\n </textarea>\n </div>\n\n <div>\n <span ng-show="EditabilityService.isEditable() && !activeThread.isSuggestionThread()">\n Change status (optional):\n <select ng-model="tmpMessage.status"\n ng-options="choice.id as choice.text for choice in STATUS_CHOICES"\n ng-disabled="messageSendingInProgress">\n </select>\n <div style="color:#ff0000; margin-top: 7px;" ng-if="!tmpMessage.text && (tmpMessage.status === \'ignored\' || tmpMessage.status === \'not_actionable\')">\n <i class="material-icons"></i>\n <span>Please specify a reason for setting the status to <[getHumanReadableStatus(tmpMessage.status)]>.</span>\n </div>\n </span>\n </div>\n\n <div>\n <button class="btn btn-success protractor-test-oppia-feedback-response-send-btn" style="margin-top: 10px;"\n ng-click="addNewMessage(activeThread.threadId, tmpMessage.text, tmpMessage.status)"\n ng-disabled="messageSendingInProgress || (!tmpMessage.text && activeThread.status === tmpMessage.status) || (!tmpMessage.text && (tmpMessage.status === \'ignored\' || tmpMessage.status === \'not_actionable\'))">\n <span ng-if="messageSendingInProgress">Sending...</span>\n <span ng-if="!messageSendingInProgress">Send</span>\n </button>\n </div>\n </div>\n </div>\n <em ng-if="!userIsLoggedIn">To respond to a feedback thread, please log in.</em>\n </div>\n</md-card>\n\n\n<style>\n /* Overwrite the default "success" color to a darker shade of green in order\n to prevent this overshadowing the active action buttons (like "Create New\n Thread"). */\n .oppia-feedback-card span.label.label-success {\n background-color: #038603;\n }\n .activeThreadView {\n margin-top: 10px;\n word-wrap: break-word;\n }\n</style>\n </div>\n </div>\n </div>\n\n <!-- These definitions must be included exactly once on the page for the graph SVGs to work in Firefox. -->\n <svg width="0" height="0">\n <defs>\n <marker id="arrowhead" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="grey"></path>\n </marker>\n <marker id="arrowhead-green" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="#1F7D1F"></path>\n </marker>\n <marker id="arrowhead-red" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="#B22222"></path>\n </marker>\n <linearGradient id="nodegradient" x1="0%" x2="100%" y1="0%" y2="0%">\n <stop offset="0%" style="stop-opacity: 1; stop-color: darkseagreen;"></stop>\n <stop offset="100%" style="stop-opacity: 0.1; stop-color: darkseagreen;"></stop>\n </linearGradient>\n </defs>\n </svg>\n\n\n \n \n </div>\n </div>\n </div>\n <div ng-if="!iframed">\n <div role="button" tabindex="0" ng-click="skipToMainContent()" class="oppia-skip-to-content protractor-test-skip-link">Skip to Main Content</div>\n <promo-bar>\n </promo-bar>\n <div ng-if="isBackgroundMaskActive()" class="ng-cloak oppia-background-mask">\n </div>\n\n <div class="oppia-base-container" ng-class="{\'oppia-sidebar-menu-open\': isSidebarShown(), \'oppia-sidebar-menu-closed\': !isSidebarShown()}" ng-swipe-left="closeSidebarOnSwipe()" ng-swipe-disable-mouse="false">\n <div class="oppia-content-container">\n <div id="wrapper">\n <div class="oppia-main-body">\n <nav class="navbar navbar-default oppia-navbar oppia-prevent-selection" role="navigation" headroom tolerance="0" offset="0">\n <div class="navbar-container">\n <top-navigation-bar></top-navigation-bar>\n <div class="collapse navbar-collapse oppia-navbar-collapse ng-cloak">\n \n <editor-navbar-breadcrumb></editor-navbar-breadcrumb>\n\n\n \n <editor-navigation></editor-navigation>\n\n <exploration-save-and-publish-buttons></exploration-save-and-publish-buttons>\n\n </div>\n </div>\n </nav>\n\n <div class="oppia-top-of-page-padding">\n </div>\n\n <div tabindex="0" aria-label="Oppia Main Content" id="oppia-main-content" class="protractor-test-main-content" ng-cloak>\n <div class="oppia-toast-container toast-top-center">\n <div ng-repeat="warning in (AlertsService.warnings | limitTo:5) track by $index" class="toast toast-warning oppia-toast">\n <button type="button" class="toast-close-button" ng-click="AlertsService.deleteWarning(warning)" role="button">×</button>\n <div class="toast-message">\n <[warning.content]>\n </div>\n </div>\n </div>\n\n <div>\n <div ng-repeat="message in AlertsService.messages track by $index">\n <alert-message message-object="message" message-index="$index"></alert-message>\n </div>\n </div>\n\n <div ng-show="loadingMessage" class="oppia-loading-fullpage">\n <div class="oppia-align-center">\n <span translate="<[loadingMessage]>"></span>\n <span class="oppia-loading-dot-one">.</span>\n <span class="oppia-loading-dot-two">.</span>\n <span class="oppia-loading-dot-three">.</span>\n </div>\n </div>\n <div ng-show="!loadingMessage">\n \n <div ng-controller="ExplorationEditor" ng-cloak>\n <div class="container-fluid oppia-editor-page-container" ng-joy-ride="tutorialInProgress" config="EDITOR_TUTORIAL_OPTIONS" on-finish="onFinishTutorial()" on-skip="onSkipTutorial()">\n <div class="row" ng-if="ExplorationRightsService.isCloned()">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div class="oppia-align-center uib-alert alert-warning" style="padding: 2px; width: 90%;">\n <strong>Note:</strong> This is a private, unpublishable copy of a\n <a ng-href="<[getExplorationUrl(ExplorationRightsService.clonedFrom())]>" target="_blank" rel="noopener">public exploration</a>.\n </div>\n </div>\n </div>\n\n <div ng-show="getActiveTabName() === \'main\'">\n <div class="row">\n <div class="col-lg-8 col-md-8 col-sm-8">\n <div ng-controller="ExplorationEditorTab" class="oppia-editor-cards-container">\n <div class="oppia-editor-header">\n <state-name-editor></state-name-editor>\n </div>\n\n <div ng-if="areParametersEnabled()">\n <state-param-changes-editor></state-param-changes-editor>\n </div>\n\n <state-editor on-save-state-content="saveStateContent"\n on-save-interaction-customization-args="saveInteractionCustomizationArgs"\n on-save-interaction-id="saveInteractionId"\n on-save-interaction-default-outcome="saveInteractionDefaultOutcome"\n on-save-interaction-answer-groups="saveInteractionAnswerGroups"\n on-save-solution="saveSolution"\n on-save-hints="saveHints"\n recompute-graph="recomputeGraph"\n show-mark-all-audio-as-needing-update-modal-if-required="showMarkAllAudioAsNeedingUpdateModalIfRequired"\n state-content-placeholder="getStateContentPlaceholder()"\n navigate-to-state="navigateToState"\n add-state="addState"\n refresh-warnings="refreshWarnings"\n interaction-is-shown="interactionIsShown">\n </state-editor>\n</div>\n </div>\n <div class="col-lg-4 col-md-4 col-sm-4">\n <div class="oppia-editor-sidebar hidden-xs hidden-sm">\n <div ng-controller="ExplorationGraph" ng-show="isGraphShown()" class="oppia-state-graph-animate-show">\n <span style="font-size: 16px;">\n <strong>Exploration Overview</strong>\n </span>\n\n <md-card style="background-color: white; margin: 20px 0px; padding: 8px;">\n <div class="oppia-state-graph-container protractor-test-exploration-graph">\n <div state-graph-visualization graph-data="getGraphData()" current-state-id="getActiveStateName()" on-click-function="onClickStateInMinimap" on-delete-function="deleteState" on-maximize-function="openStateGraphModal" allow-panning="true" center-at-current-state="true" style="height: 100%;" is-editable="isEditable()" show-warning-sign="true">\n </div>\n </div>\n </md-card>\n</div>\n <unresolved-answers-overview></unresolved-answers-overview>\n </div>\n </div>\n <attribution-guide></attribution-guide>\n</div>\n </div>\n\n <div ng-if="getActiveTabName() === \'translation\'">\n <translation-tab></translation-tab>\n </div>\n <!-- This is an ng-if, so that the preview loads the latest version of the exploration each time the tab is accessed. -->\n <div ng-if="getActiveTabName() === \'preview\'">\n <div ng-controller="PreviewTab">\n <div ng-if="isExplorationPopulated">\n <div ng-if="previewWarning">\n <div class="oppia-preview-state-warning"><[previewWarning]></div>\n </div>\n <conversation-skin></conversation-skin>\n <exploration-footer twitter-text=""></exploration-footer>\n\n </div>\n\n <div class="oppia-preview-bottom-right-container">\n <div class="oppia-parameter-summary" ng-if="showParameterSummary()">\n <strong>Parameters:</strong>\n <table>\n <tr ng-repeat="(paramName, paramValue) in allParams">\n <td style="padding: 1px 5px;"><[paramName]>:</td>\n <td style="padding: 1px 5px;">\n <[paramValue != "" ? paramValue : "[Not set]"]>\n </td>\n </tr>\n </table>\n </div>\n <button class="btn-lg" ng-click="resetPreview()">\n <i class="material-icons" style="margin-bottom: 2px;"></i>\n <span style="margin-left: 10px; padding-top: 20px;">Restart From Beginning</span>\n </button>\n </div>\n\n</div>\n\n<style>\n .oppia-preview-bottom-right-container {\n /* Fixed at bottom right corner (before footer) and appear on top of other div*/\n bottom: 10px;\n display: block;\n position: fixed;\n right: 0;\n padding-bottom: 2em;\n z-index: 1060;\n }\n\n .oppia-preview-bottom-right-container .oppia-parameter-summary {\n background-color: #fff;\n font-size: 16px;\n margin: 0px 0px 2px 0px;\n padding: 5px 0px 0px 5px;\n text-align: left;\n }\n\n .oppia-preview-bottom-right-container .btn-lg {\n background-color: #fff;\n border: none;\n border-radius: 0px;\n display: block;\n font-size: 20px;\n text-align: right;\n margin-top: 10px;\n padding-top: 10px;\n }\n\n .oppia-preview-state-warning {\n background-color: #fff;\n border: 1px solid #ccc;\n border-radius: 4px;\n display: block;\n font-size: 16px;\n font-weight: bold;\n left: 6px;\n max-width: 296px;\n padding: 3px;\n position: absolute;\n text-align: left;\n top: 63px;\n white-space: normal;\n z-index: 1060;\n }\n</style>\n </div>\n\n <div ng-show="getActiveTabName() === \'stats\'">\n <div ng-controller="StatisticsTab" ng-cloak>\n <md-card class="oppia-editor-card" ng-if="!loadingMessage">\n <div ng-if="explorationHasBeenVisited">\n <div class="oppia-statistics-display">\n <h3>Exploration Completion Rate</h3>\n <pie-chart data="pieChartData"\n options="COMPLETION_RATE_PIE_CHART_OPTIONS">\n </pie-chart>\n <p style="text-align: center;"><span ng-if="numPassersby" style="font-weight: bold;" class="protractor-test-num-passersby"><[numPassersby]></span><span ng-if="!numPassersby" style="font-weight: bold;">0</span> learners browsed this exploration. They left before reaching the second card.</p>\n\n <h3>Card statistics</h3>\n <div style="font-size: smaller" ng-if="lastUpdated">\n <em>Last updated: <[getLocaleAbbreviatedDatetimeString(lastUpdated)]></em>\n </div>\n <div class="container">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div state-graph-visualization graph-data="statsGraphData"\n node-fill="darkseagreen"\n highlight-states="highlightStates"\n state-stats="stateStats"\n on-click-function="onClickStateInStatsGraph">\n </div>\n </div>\n </div>\n <div class="container" ng-if="playthroughsAreAvailable">\n <playthrough-issues></playthrough-issues>\n </div>\n </div>\n </div>\n </div>\n <div ng-if="!explorationHasBeenVisited">\n <em>\n This exploration has not been visited by anyone yet, so there are no statistics to display.\n </em>\n </div>\n </md-card>\n</div>\n </div>\n\n <improvements-tab ng-if="getActiveTabName() === \'improvements\'">\n </improvements-tab>\n\n <div ng-show="getActiveTabName() === \'settings\'">\n <div ng-controller="SettingsTab">\n <md-card class="oppia-editor-card">\n <h3>Basic Settings</h3>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div ng-if="EditabilityService.isEditable()">\n <div role="form" class="form-horizontal">\n <exploration-title-editor label-text="Title"\n focus-label="<[::EXPLORATION_TITLE_INPUT_FOCUS_LABEL]>"\n form-style="<[::formStyle]>"\n on-input-field-blur="saveExplorationTitle()">\n </exploration-title-editor>\n <exploration-objective-editor label-text="Goal"\n form-style="<[::formStyle]>"\n on-input-field-blur="saveExplorationObjective()">\n </exploration-objective-editor>\n\n <div class="form-group" ng-class="{\'has-error\': !explorationCategoryService.displayed}">\n <label for="explorationCategory" class="col-lg-2 col-md-2 col-sm-2">Category</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <div ng-if="hasPageLoaded">\n <select2-dropdown id="explorationCategory"\n class="protractor-test-exploration-category-input"\n item="explorationCategoryService.displayed"\n choices="CATEGORY_LIST_FOR_SELECT2"\n placeholder="Choose or type new"\n new-choice-regex="^[A-Z a-z]+$"\n on-selection-change="saveExplorationCategory()"\n width="100%"\n invalid-search-term-message="Invalid category name">\n </select2-dropdown>\n </div>\n </div>\n </div>\n\n <div class="form-group">\n <label for="explorationLanguageCode" class="col-lg-2 col-md-2 col-sm-2">Language</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <select id="explorationLanguageCode" class="form-control protractor-test-exploration-language-select" ng-model="explorationLanguageCodeService.displayed" ng-change="saveExplorationLanguageCode()" ng-options="lc.code as lc.description for lc in explorationLanguageCodeService.getAllLanguageCodes()">\n </select>\n <span class="help-block" style="font-size: smaller">\n <em>\n Don\'t see the language you want? <a href="https://github.com/oppia/oppia/issues/new?title=Please%20add%20a%20new%20language%20choice%20to%20the%20exploration%20settings%20tab&body=Please%20add%20the%20language%20choice%20%7B%7BYOUR_LANGUAGE_HERE%7D%7D%20to%20the%20exploration%20settings%20tab.%0A%0AHere%20is%20a%20link%20to%20an%20exploration%20that%20uses%20it:%20%7B%7BINSERT_LINK_HERE%7D%7D" target="_blank" rel="noopener">Tell us.</a>\n </em>\n </span>\n </div>\n </div>\n <div class="form-group">\n <label for="explorationInitStateName" class="col-lg-2 col-md-2 col-sm-2">Name of first card</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <select id="explorationInitStateName" class="form-control protractor-test-initial-state-select" ng-model="explorationInitStateNameService.displayed" ng-change="saveExplorationInitStateName()" ng-options="name as name for name in stateNames track by name">\n </select>\n <span class="help-block" style="font-size: smaller">\n <em>This is the first card the learner sees when playing your exploration.</em>\n </span>\n </div>\n </div>\n <div class="form-group">\n <label for="explorationTags" class="col-lg-2 col-md-2 col-sm-2">Tags</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <div ng-if="hasPageLoaded">\n <select2-dropdown item="$parent.explorationTagsService.displayed"\n choices="$parent.explorationTagsService.displayed"\n allow-multiple-choices="true"\n invalid-search-term-message="Add a new tag (using lowercase letters and spaces)..."\n new-choice-regex="<[::TAG_REGEX]>"\n width="100%"\n placeholder="Skills, concepts, topics..."\n on-selection-change="saveExplorationTags()">\n </select2-dropdown>\n </div>\n <span class="help-block" style="font-size: smaller">\n <em>Tags help learners discover your exploration when searching.</em>\n </span>\n </div>\n </div>\n <div class="text-right">\n <button type="button" class="btn btn-default protractor-test-open-preview-summary-modal"\n ng-click="previewSummaryTile()"\n title="Preview this exploration\'s summary card">\n Preview Summary\n </button>\n </div>\n </div>\n </div>\n\n <div ng-if="!EditabilityService.isEditable()">\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationTitle">\n Title\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationTitle" type="text">\n <[explorationTitleService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationObjective">\n Goal\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationObjective" type="text">\n <[explorationObjectiveService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationCategory">\n Category\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationCategory" type="text">\n <[explorationCategoryService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationLanguageCode">Language</label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <[explorationLanguageCodeService.getCurrentLanguageDescription()]>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationInitStateName">First State</label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <[explorationInitStateNameService.displayed]>\n </div>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <h3>Advanced Features</h3>\n <div class="row">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableParameters" class="col-lg-10 col-md-10 col-sm-10">\n Parameters\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input span ng-if="areParametersEnabled()" type="checkbox" class="oppia-on-off-switch-checkbox" id="parameter-switch" checked disabled>\n <input span ng-if="!areParametersEnabled()" type="checkbox" class="oppia-on-off-switch-checkbox" id="parameter-switch" ng-click="enableParameters()">\n <label class="oppia-on-off-switch-label protractor-test-enable-parameters" for="parameter-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Parameters are values that change as the learner moves between cards (<a href="http://oppia.github.io/#/Parameters" target="_blank" rel="noopener">more info</a>).\n </span>\n </div>\n </div>\n </div>\n <hr>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableAutomaticTextToSpeech" class="col-lg-10 col-md-10 col-sm-10">\n Automatic Text-to-speech\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input type="checkbox" ng-if="isAutomaticTextToSpeechEnabled()" class="oppia-on-off-switch-checkbox" id="text-speech-switch" ng-click="toggleAutomaticTextToSpeech()" checked>\n <input type="checkbox" ng-if="!isAutomaticTextToSpeechEnabled()" class="oppia-on-off-switch-checkbox" id="text-speech-switch" ng-click="toggleAutomaticTextToSpeech()">\n <label class="oppia-on-off-switch-label" for="text-speech-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Automatic text-to-speech generates audio from your content for learners to listen to. It is recommended that you disable this feature if creating an exploration whose content consists of multiple languages.\n </span>\n </div>\n </div>\n </div>\n <hr>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableCorrectnessFeedback" class="col-lg-10 col-md-10 col-sm-10">\n Correctness Feedback\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input type="checkbox" ng-if="!isCorrectnessFeedbackEnabled()" class="oppia-on-off-switch-checkbox" id="correctness-switch" ng-click="toggleCorrectnessFeedback()">\n <input type="checkbox" ng-if="isCorrectnessFeedbackEnabled()" class="oppia-on-off-switch-checkbox" id="correctness-switch" ng-click="toggleCorrectnessFeedback()" checked>\n <label class="oppia-on-off-switch-label" for="correctness-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Correctness feedback allows the user to categorise answer groups as correct or incorrect.\n </span>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card">\n <div ng-if="ExplorationRightsService.ownerNames.length > 0 && !ExplorationRightsService.isCloned()">\n <div class="row">\n <div class="col-lg-5 col-md-5 col-sm-5">\n <h3>Roles</h3>\n <div ng-show="ExplorationRightsService.ownerNames.length > 0">\n <strong>Managers</strong>\n <ul>\n <li ng-repeat="ownerName in ExplorationRightsService.ownerNames track by $index">\n <[ownerName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.editorNames.length > 0">\n <strong>Collaborators</strong>\n <ul>\n <li ng-repeat="editorName in ExplorationRightsService.editorNames track by $index">\n <[editorName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.voiceArtistNames.length > 0">\n <strong>Voice Artists</strong>\n <ul>\n <li ng-repeat="voiceArtistName in ExplorationRightsService.voiceArtistNames track by $index">\n <[voiceArtistName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.viewerNames.length > 0">\n <strong>Playtesters</strong>\n <ul>\n <li ng-repeat="viewerName in ExplorationRightsService.viewerNames track by $index">\n <[viewerName]>\n </li>\n </ul>\n </div>\n\n\n <div ng-if="canModifyRoles" ng-hide="isRolesFormOpen">\n <button type="button" class="btn btn-default protractor-test-edit-roles" ng-click="openEditRolesForm()">\n Edit Roles\n </button>\n </div>\n\n <div ng-if="canModifyRoles" ng-show="isRolesFormOpen">\n <strong>Add or Change Role</strong>\n <div class="form-group">\n <form ng-submit="editRole(newMemberUsername, newMemberRole.value)">\n <label for="newMemberUsername">Username of invited user</label>\n <div>\n <input type="text" id="newMemberUsername" class="form-control protractor-test-role-username" ng-model="newMemberUsername" placeholder="editor">\n </div>\n <br>\n <label for="newMemberRole">Role of invited user</label>\n <div>\n <select ng-model="newMemberRole" class="form-control protractor-test-role-select" ng-options="r.name for r in ROLES" style="width: 250px;">\n </select>\n <span class="help-block">\n Note that managers also have the permissions of collaborators, collaborators also have the permissions of voice artists, and voice artists also have the permissions of viewers. Please note that assigning roles is irreversible (though you can always assign somebody to a higher role).\n </span>\n </div>\n\n <input type="submit" class="btn btn-default protractor-test-save-role" value="Save" ng-disabled="!isTitlePresent()">\n <button type="button" class="btn btn-default" ng-click="closeEditRolesForm()" ng-show="isRolesFormOpen">\n Cancel\n </button>\n <p ng-show="!isTitlePresent()" class="text-danger protractor-test-title-warning">Please provide a title before inviting.</p>\n </form>\n </div>\n </div>\n </div>\n\n <div class="col-lg-7 col-md-7 col-sm-7">\n <h3>Permissions</h3>\n <p ng-if="ExplorationRightsService.isPrivate() && ExplorationRightsService.viewableIfPrivate()">\n This exploration is <strong>private</strong>. Anyone with the link can access it.\n </p>\n <p ng-if="ExplorationRightsService.isPrivate() && !ExplorationRightsService.viewableIfPrivate()">\n This exploration is <strong>private</strong>. Only invited users, moderators and site admins can\n access it.\n </p>\n <p ng-if="!ExplorationRightsService.isPrivate()">\n This exploration is <strong>public</strong>: anyone can access it.\n </p>\n\n <p ng-if="!ExplorationRightsService.isPrivate() || ExplorationRightsService.viewableIfPrivate()">\n <em>Link to share:</em>\n <input class="form-control" type="text" value="<[getExplorePageUrl(explorationId)]>" readonly="readonly" onClick="this.select();">\n </p>\n\n <br>\n\n <p ng-if="ExplorationRightsService.isPrivate()">\n It is <strong>not shown</strong> in the Oppia library.\n </p>\n <p ng-if="!ExplorationRightsService.isPrivate()">\n It is <strong>available</strong> in the Oppia library.\n </p>\n </div>\n </div>\n </div>\n\n <div ng-if="ExplorationRightsService.ownerNames.length === 0 && !ExplorationRightsService.isCloned()">\n <h3>Permissions</h3>\n <div>\n This exploration is <strong>public</strong> and <strong>community-editable</strong>.\n <p ng-if="!ExplorationRightsService.isPrivate()">\n It is <strong>available</strong> in the Oppia library.\n </p>\n </div>\n </div>\n\n <div ng-if="ExplorationRightsService.isCloned()">\n <h3>Status</h3>\n <div>\n This exploration was <strong>cloned</strong> from another exploration.\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <h3>Feedback/Suggestion Email Preferences</h3>\n <div class="row">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="FeedbackNotifications" class="col-lg-3 col-md-3 col-sm-3">\n Feedback emails\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="muteFeedbackNotifications()" ng-if="!UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n Mute\n </button>\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="unmuteFeedbackNotifications()" ng-if="UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n Unmute\n </button>\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="!UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n You are currently receiving notifications of new feedback for this exploration.\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n You have muted feedback notifications for this exploration. You will not receive an email when new feedback is submitted.\n </span>\n </div>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="SuggestionNotifications" class="col-lg-3 col-md-3 col-sm-3">\n Suggestion emails\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="muteSuggestionNotifications()" ng-if="!UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n Mute\n </button>\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="unmuteSuggestionNotifications()" ng-if="UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n Unmute\n </button>\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="!UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n You are currently receiving notifications of new suggestions for this exploration.\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n You have muted suggestion notifications for this exploration. You will not receive an email when new suggestion is submitted.\n </span>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <div class="row">\n <div class="col-lg-6 col-md-6 col-sm-6">\n <h3>Controls</h3>\n\n <p ng-if="canReleaseOwnership" class="oppia-exploration-ctrl" ng-hide="ExplorationRightsService.isCommunityOwned()">\n <button type="button" class="btn btn-default" ng-click="showTransferExplorationOwnershipModal()" ng-disabled="isExplorationLockedForEditing()">\n Transfer ownership to the community\n </button>\n <span ng-if="isExplorationLockedForEditing()">\n <br>\n Please save your changes first.\n </span>\n </p>\n\n <p ng-if="canDelete" class="oppia-exploration-ctrl">\n <button type="button" ng-if="ExplorationRightsService.isPrivate()"\n class="btn btn-danger" ng-click="deleteExploration()"\n title="Delete this exploration">\n Delete Exploration\n </button>\n </p>\n </div>\n\n <div class="col-lg-6 col-md-6 col-sm-6" ng-if="currentUserIsAdmin || currentUserIsModerator">\n <h3>Admin Controls</h3>\n\n <p ng-if="canUnpublish" class="oppia-exploration-ctrl oppia-exploration-ctrl-admin" ng-show="ExplorationRightsService.isPublic()">\n <button type="button" class="btn btn-default" ng-click="unpublishExplorationAsModerator()" ng-disabled="isExplorationLockedForEditing()">\n Unpublish\n <span ng-if="currentUserIsAdmin">(as admin)</span>\n <span ng-if="!currentUserIsAdmin && currentUserIsModerator">(as moderator)</span>\n </button>\n </p>\n\n <p class="oppia-exploration-ctrl oppia-exploration-ctrl-admin" ng-if="ExplorationRightsService.isPublic() && (currentUserIsAdmin || currentUserIsModerator)">\n <button type="button" class="btn btn-danger protractor-test-delete-exploration-button"\n ng-click="deleteExploration()">\n Delete Exploration\n <span ng-if="currentUserIsAdmin">(as admin)</span>\n <span ng-if="!currentUserIsAdmin && currentUserIsModerator">(as moderator)</span>\n </button>\n </p>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="areParametersEnabled()">\n <h3>Parameters used in this exploration</h3>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div ng-show="isEmpty(explorationParamSpecsService.savedMemento.getParamDict())">\n <em>No parameters used.</em>\n </div>\n <ol>\n <li ng-repeat="(paramName, paramSpec) in explorationParamSpecsService.savedMemento.getParamDict()">\n <b><[paramName]></b> (<[paramSpec.getType().getName()]>)\n </li>\n </ol>\n </div>\n </div>\n\n <h3>\n Initial parameter changes\n <i class="material-icons md-18" uib-tooltip="These changes are applied before the learner begins the exploration."\n tooltip-placement="right" style="padding-left: 4px; vertical-align: text-top;">\n \n </i>\n </h3>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12 protractor-test-exploration-edit-param-changes">\n <param-changes-editor param-changes-service="explorationParamChangesService"\n post-save-hook="postSaveParamChangesHook"\n currently-in-settings-tab="true">\n </param-changes-editor>\n </div>\n </div>\n </md-card>\n</div>\n </div>\n\n <div ng-show="getActiveTabName() === \'history\'">\n <div ng-controller="HistoryTab" class="container-fluid" style="word-wrap: break-word;">\n <md-card class="oppia-editor-card">\n <h3>List of Changes</h3>\n <div ng-repeat="versionNumber in versionNumbersToDisplay" class="row">\n <div class="col-sm-4 col-md-4 col-lg-4">\n <input type="checkbox" name="compareVer" ng-model="versionCheckboxArray[versionNumber].selected" ng-init="init()" ng-click="changeSelectedVersions($event, versionNumber)" ng-disabled="isCheckboxDisabled(versionNumber)" ng-hide="comparisonsAreDisabled" class="protractor-test-history-checkbox-selector">\n [<[versionNumber]>]\n <strong><profile-link-text username="explorationVersionMetadata[versionNumber].committerId"></profile-link-text></strong>\n </div>\n <div class="col-sm-4 col-md-4 col-lg-4">\n <[explorationVersionMetadata[versionNumber].commitMessage]>\n </div>\n <div class="col-sm-4 col-md-4 col-lg-4">\n <span>\n <em><[explorationVersionMetadata[versionNumber].createdOnStr]></em>\n <span ng-if="versionNumber !== currentVersion && EditabilityService.isEditable()">\n | <a href="#" class="protractor-test-revert-version" ng-click="showRevertExplorationModal(versionNumber)">Revert</a>\n </span>\n <span>\n | <a href="#" ng-click="downloadExplorationWithVersion(versionNumber)" title="Download exploration as a zip file.">Download</a>\n </span>\n </span>\n </div>\n </div>\n\n <br>\n\n <div ng-hide="!explorationVersionMetadata || compareVersionsButtonIsHidden">\n <button class="btn protractor-test-show-history-graph" ng-class="{\'btn-success\': areCompareVersionsSelected(), \'btn-default\': !areCompareVersionsSelected()}" ng-click="compareSelectedVersions()" ng-disabled="!areCompareVersionsSelected()">Compare selected revisions</button>\n <div class="version-count-prompt">\n <[versionCountPrompt]>\n </div>\n </div>\n\n <div ng-show="versionCheckboxArray.length > VERSIONS_PER_PAGE" style="margin-top: 30px" uib-pagination boundary-links="true" class="pagination-sm" max-size="5" items-per-page="VERSIONS_PER_PAGE" total-items="versionCheckboxArray.length" ng-model="displayedCurrentPageNumber" ng-change="computeVersionsToDisplay()"></div>\n </md-card>\n\n <md-card class="oppia-editor-card" style="position: relative;"\n ng-if="diffData && !hideHistoryGraph && explorationVersionMetadata">\n <h3>\n Changes from version <[compareVersionMetadata.earlierVersion.versionNumber]>\n to version <[compareVersionMetadata.laterVersion.versionNumber]>\n </h3>\n\n <version-diff-visualization diff-data="diffData"\n earlier-version-header="earlierVersionHeader"\n later-version-header="laterVersionHeader">\n </version-diff-visualization>\n </md-card>\n</div>\n </div>\n\n <div ng-show="getActiveTabName() === \'feedback\'">\n <md-card class="oppia-editor-card oppia-feedback-card" ng-controller="FeedbackTab">\n <div ng-if="!activeThread">\n <div ng-if="threadData.suggestionThreads.length > 0">\n <h2>Suggestions from Learners</h2>\n <thread-table threads="threadData.suggestionThreads"\n on-click-row="setActiveThread">\n </thread-table>\n <br>\n </div>\n\n <div class="pull-right">\n <button ng-if="userIsLoggedIn" class="btn btn-success pull-right" ng-click="showCreateThreadModal()">\n Start new thread\n </button>\n </div>\n\n <h2>Exploration Feedback</h2>\n\n <div style="clear: both;"></div>\n\n <div ng-if="threadData.feedbackThreads.length === 0">\n <em>No feedback has been given for this exploration yet.</em>\n </div>\n\n <thread-table threads="threadData.feedbackThreads"\n on-click-row="setActiveThread">\n </thread-table>\n\n <em ng-if="!userIsLoggedIn">To create a new feedback thread, please log in.</em>\n </div>\n\n <div ng-if="activeThread">\n <div class="row">\n <div class="col-lg-9 col-md-9 col-sm-9">\n <span class="oppia-back-arrow">\n <button type="button" class="btn btn-default btn-xs protractor-test-oppia-feedback-back-button" ng-click="onBackButtonClicked()">\n <i class="material-icons oppia-vcenter" title="Return to list of feedback threads"></i>\n </button>\n </span>\n <span style="font-size: larger" ng-show="!activeThread.isSuggestionThread()">Feedback Thread: <[activeThread.subject]></span>\n <span style="font-size: larger" ng-show="activeThread.isSuggestionThread()">Suggestion Thread: <[activeThread.subject]></span>\n </div>\n\n <div style="float: right;" class="col-lg-5 col-md-5 col-sm-5">\n <div class="pull-right">\n <span ng-if="activeThread.stateName" class="label label-info">\n state: <[activeThread.stateName]>\n </span>\n <span ng-class="getLabelClass(activeThread.status)">\n <[getHumanReadableStatus(activeThread.status)]>\n </span>\n </div>\n </div>\n </div>\n\n <div class="row" ng-if="activeThread.messages">\n <div class="col-lg-12 col-md-12 col-sm-12 activeThreadView">\n <table class="table">\n <tr ng-repeat="m in activeThread.messages|orderBy:\'message_id\'">\n <td>\n <div class="row">\n <div class="col-lg-5 col-md-5 col-sm-5">\n <span ng-if="$index !== 0">#<[m.message_id]></span>\n <span ng-if="m.author_username">by <strong><[m.author_username]></strong></span>\n <span ng-if="!m.author_username">(anonymously submitted)</span>\n </div>\n\n <div class="col-lg-4 col-md-4 col-sm-4">\n <span ng-if="m.message_id !== 0">\n <span ng-if="m.updated_status">\n <em>Status changed to \'<[getHumanReadableStatus(m.updated_status)]>\'</em>\n </span>\n <span ng-if="m.updated_subject">\n <em>Subject changed to \'<[m.updated_subject]>\'</em>\n </span>\n </span>\n </div>\n\n <div class="col-lg-3 col-md-3 col-sm-3">\n <span><[getLocaleAbbreviatedDatetimeString(m.created_on)]></span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div style="white-space: pre-wrap;" class="protractor-test-exploration-feedback"><[m.text]></div>\n <div ng-if="activeThread.isSuggestionThread() && $index == 0">\n <button class="btn btn-<[getSuggestionButtonType()]> protractor-test-view-suggestion-btn" style="margin-top: 6px; margin-bottom: 6px" ng-click="showSuggestionModal()">\n View Suggestion\n </button>\n </div>\n </div>\n </div>\n </td>\n </tr>\n </table>\n </div>\n </div>\n\n\n <hr>\n\n <div class="row" ng-if="userIsLoggedIn">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div>\n <label for="tmpMessageText">\n Add new message\n <span ng-if="EditabilityService.isEditable() && !activeThread.isSuggestionThread()">(and/or change status)</span>\n </label>\n <textarea class="form-control protractor-test-feedback-response-textarea" ng-model="tmpMessage.text"\n id="tmpMessageText" rows="6"\n ng-disabled="messageSendingInProgress">\n </textarea>\n </div>\n\n <div>\n <span ng-show="EditabilityService.isEditable() && !activeThread.isSuggestionThread()">\n Change status (optional):\n <select ng-model="tmpMessage.status"\n ng-options="choice.id as choice.text for choice in STATUS_CHOICES"\n ng-disabled="messageSendingInProgress">\n </select>\n <div style="color:#ff0000; margin-top: 7px;" ng-if="!tmpMessage.text && (tmpMessage.status === \'ignored\' || tmpMessage.status === \'not_actionable\')">\n <i class="material-icons"></i>\n <span>Please specify a reason for setting the status to <[getHumanReadableStatus(tmpMessage.status)]>.</span>\n </div>\n </span>\n </div>\n\n <div>\n <button class="btn btn-success protractor-test-oppia-feedback-response-send-btn" style="margin-top: 10px;"\n ng-click="addNewMessage(activeThread.threadId, tmpMessage.text, tmpMessage.status)"\n ng-disabled="messageSendingInProgress || (!tmpMessage.text && activeThread.status === tmpMessage.status) || (!tmpMessage.text && (tmpMessage.status === \'ignored\' || tmpMessage.status === \'not_actionable\'))">\n <span ng-if="messageSendingInProgress">Sending...</span>\n <span ng-if="!messageSendingInProgress">Send</span>\n </button>\n </div>\n </div>\n </div>\n <em ng-if="!userIsLoggedIn">To respond to a feedback thread, please log in.</em>\n </div>\n</md-card>\n\n\n<style>\n /* Overwrite the default "success" color to a darker shade of green in order\n to prevent this overshadowing the active action buttons (like "Create New\n Thread"). */\n .oppia-feedback-card span.label.label-success {\n background-color: #038603;\n }\n .activeThreadView {\n margin-top: 10px;\n word-wrap: break-word;\n }\n</style>\n </div>\n </div>\n </div>\n\n <!-- These definitions must be included exactly once on the page for the graph SVGs to work in Firefox. -->\n <svg width="0" height="0">\n <defs>\n <marker id="arrowhead" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="grey"></path>\n </marker>\n <marker id="arrowhead-green" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="#1F7D1F"></path>\n </marker>\n <marker id="arrowhead-red" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="#B22222"></path>\n </marker>\n <linearGradient id="nodegradient" x1="0%" x2="100%" y1="0%" y2="0%">\n <stop offset="0%" style="stop-opacity: 1; stop-color: darkseagreen;"></stop>\n <stop offset="100%" style="stop-opacity: 0.1; stop-color: darkseagreen;"></stop>\n </linearGradient>\n </defs>\n </svg>\n\n\n \n \n </div>\n </div>\n </div>\n\n <noscript>\n <div class="oppia-page-cards-container">\n <div class="md-default-theme oppia-page-card oppia-long-text">\n <!-- Note to developers: We replicate the translated text inline because, without JavaScript enabled, the translation engine doesn\'t kick in.-->\n <h2>\n <span translate="I18N_SPLASH_JAVASCRIPT_ERROR_TITLE">We Need JavaScript in Your Browser</span>\n <i class="material-icons"></i>\n </h2>\n <p translate="I18N_SPLASH_JAVASCRIPT_ERROR_DESCRIPTION" translate-values="{hrefUrl: \'http://www.enable-javascript.com/\'}">\n Oppia is a free, open-source learning platform full of interactive activities called \'explorations\'. Sadly, Oppia requires JavaScript to be enabled in your web browser in order to function properly and your web browser has JavaScript disabled. If you need help enabling JavaScript, <a href="http://www.enable-javascript.com">click here.</a>\n </p>\n <p translate="I18N_SPLASH_JAVASCRIPT_ERROR_THANKS">Thank you.</p>\n </div>\n </div>\n </noscript>\n\n <side-navigation-bar></side-navigation-bar>\n </div>\n </div>\n </div>\n\n <div ng-if="DEV_MODE" class="oppia-dev-mode" ng-cloak>\n Dev Mode\n </div>\n\n <a ng-if="siteFeedbackFormUrl" ng-href="<[siteFeedbackFormUrl]>" target="_blank" rel="noopener" class="oppia-site-feedback oppia-transition-200">\n <i class="material-icons md-18"></i>\n <span translate="I18N_SPLASH_SITE_FEEDBACK"></span>\n </a>\n </div>\n\n \n <script src="/third_party/generated/js/third_party.js"></script>\n\n <script src="/templates/dev/head/AppInit.js"></script>\n <!-- This code is used for inserting webpack bundles\n https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates -->\n \n \n <script src="/build/templates/head/dist/about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/app~library.3bd713e5f19772d7b250.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/app.3a832a81c9290cfe0045.bundle.js"></script>\n \n \n\n \n \n \n <script src="/third_party/static/ckeditor-4.9.2/ckeditor.js"></script>\n <script src="/third_party/static/d3js-3.4.11/d3.min.js"></script>\n <script src="/templates/dev/head/mathjaxConfig.js"></script>\n <script src="/third_party/static/MathJax-2.6.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>\n <script>\n // Copyright 2014 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for copier value generator.\n */\n// TODO(sll): Remove this directive (as well as the whole of the value\n// generators framework).\noppia.directive(\'copier\', [\'$compile\', function ($compile) {\n return {\n link: function (scope, element) {\n scope.getTemplateUrl = function () {\n return \'/value_generator_handler/\' + scope.generatorId;\n };\n $compile(element.contents())(scope);\n },\n restrict: \'E\',\n scope: {\n customizationArgs: \'=\',\n getGeneratorId: \'&\',\n getInitArgs: \'&\',\n getObjType: \'&\',\n },\n template: \'<span ng-include="getTemplateUrl()"></span>\',\n controller: function ($scope) {\n $scope.generatorId = $scope.getGeneratorId();\n $scope.initArgs = $scope.getInitArgs();\n $scope.objType = $scope.getObjType();\n $scope.$watch(\'initArgs\', function () {\n $scope.initArgs = $scope.getInitArgs();\n }, true);\n $scope.$watch(\'objType\', function () {\n $scope.objType = $scope.getObjType();\n }, true);\n }\n };\n }]);\n// Copyright 2014 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for random selector value generator.\n */\noppia.directive(\'randomSelector\', [\'$compile\', function ($compile) {\n return {\n link: function (scope, element) {\n scope.getTemplateUrl = function () {\n return \'/value_generator_handler/\' + scope.generatorId;\n };\n $compile(element.contents())(scope);\n },\n restrict: \'E\',\n scope: {\n customizationArgs: \'=\',\n getGeneratorId: \'&\'\n },\n template: \'<div ng-include="getTemplateUrl()"></div>\',\n controller: function ($scope) {\n $scope.SCHEMA = {\n type: \'list\',\n items: {\n type: \'unicode\'\n },\n ui_config: {\n add_element_text: \'Add New Choice\'\n }\n };\n $scope.generatorId = $scope.getGeneratorId();\n if (!$scope.customizationArgs.list_of_values) {\n $scope.customizationArgs.list_of_values = [];\n }\n }\n };\n }]);\n\n </script>\n\n <script src="/extensions/objects/templates/BooleanEditorDirective.js"></script>\n <script src="/extensions/objects/templates/CodeStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/CoordTwoDimEditorDirective.js"></script>\n <script src="/extensions/objects/templates/DragAndDropHtmlStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/DragAndDropPositiveIntEditorDirective.js"></script>\n <script src="/extensions/objects/templates/FilepathEditorDirective.js"></script>\n <script src="/extensions/objects/templates/FractionEditorDirective.js"></script>\n <script src="/extensions/objects/templates/GraphEditorDirective.js"></script>\n <script src="/extensions/objects/templates/GraphPropertyEditorDirective.js"></script>\n <script src="/extensions/objects/templates/HtmlEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ImageWithRegionsEditorDirective.js"></script>\n <script src="/extensions/objects/templates/IntEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ListOfSetsOfHtmlStringsEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ListOfTabsEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ListOfUnicodeStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/LogicErrorCategoryEditorDirective.js"></script>\n <script src="/extensions/objects/templates/LogicQuestionEditorDirective.js"></script>\n <script src="/extensions/objects/templates/MathLatexStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/MusicPhraseEditorDirective.js"></script>\n <script src="/extensions/objects/templates/NonnegativeIntEditorDirective.js"></script>\n <script src="/extensions/objects/templates/NormalizedStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/NumberWithUnitsEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ParameterNameEditorDirective.js"></script>\n <script src="/extensions/objects/templates/RealEditorDirective.js"></script>\n <script src="/extensions/objects/templates/SanitizedUrlEditorDirective.js"></script>\n <script src="/extensions/objects/templates/SetOfHtmlStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/SetOfUnicodeStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/UnicodeStringEditorDirective.js"></script>\n\n <script src="/extensions/interactions/baseInteractionValidationService.js"></script>\n\n <!-- This code is used for inserting webpack bundles\n https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates -->\n \n \n <script src="/build/templates/head/dist/about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/exploration_editor.07de01208fc08d5292d7.bundle.js"></script>\n \n \n <script src="/extensions/rich_text_components/Collapsible/directives/OppiaNoninteractiveCollapsibleDirective.js"></script>\n<script src="/extensions/rich_text_components/Image/directives/OppiaNoninteractiveImageDirective.js"></script>\n<script src="/extensions/rich_text_components/Link/directives/OppiaNoninteractiveLinkDirective.js"></script>\n<script src="/extensions/rich_text_components/Math/directives/OppiaNoninteractiveMathDirective.js"></script>\n<script src="/extensions/rich_text_components/Tabs/directives/OppiaNoninteractiveTabsDirective.js"></script>\n<script src="/extensions/rich_text_components/Video/directives/OppiaNoninteractiveVideoDirective.js"></script>\n <script src="/extensions/interactions/Continue/directives/OppiaInteractiveContinueDirective.js"></script>\n<script src="/extensions/interactions/Continue/directives/OppiaResponseContinueDirective.js"></script>\n<script src="/extensions/interactions/Continue/directives/OppiaShortResponseContinueDirective.js"></script>\n<script src="/extensions/interactions/Continue/directives/ContinueRulesService.js"></script>\n<script src="/extensions/interactions/Continue/directives/ContinueValidationService.js"></script>\n \n<script src="/extensions/interactions/EndExploration/directives/OppiaInteractiveEndExplorationDirective.js"></script>\n<script src="/extensions/interactions/EndExploration/directives/OppiaResponseEndExplorationDirective.js"></script>\n<script src="/extensions/interactions/EndExploration/directives/OppiaShortResponseEndExplorationDirective.js"></script>\n<script src="/extensions/interactions/EndExploration/directives/EndExplorationRulesService.js"></script>\n<script src="/extensions/interactions/EndExploration/directives/EndExplorationValidationService.js"></script>\n \n<script src="/extensions/interactions/ImageClickInput/directives/ImageClickInputRulesService.js"></script>\n<script src="/extensions/interactions/ImageClickInput/directives/ImageClickInputValidationService.js"></script>\n<script src="/extensions/interactions/ImageClickInput/directives/OppiaInteractiveImageClickInputDirective.js"></script>\n<script src="/extensions/interactions/ImageClickInput/directives/OppiaResponseImageClickInputDirective.js"></script>\n<script src="/extensions/interactions/ImageClickInput/directives/OppiaShortResponseImageClickInputDirective.js"></script>\n \n<link rel="stylesheet" type="text/css" href="/extensions/interactions/ItemSelectionInput/static/item_selection_input.css">\n\n<script src="/extensions/interactions/ItemSelectionInput/directives/ItemSelectionInputRulesService.js"></script>\n<script src="/extensions/interactions/ItemSelectionInput/directives/ItemSelectionInputValidationService.js"></script>\n<script src="/extensions/interactions/ItemSelectionInput/directives/OppiaInteractiveItemSelectionInputDirective.js"></script>\n<script src="/extensions/interactions/ItemSelectionInput/directives/OppiaResponseItemSelectionInputDirective.js"></script>\n<script src="/extensions/interactions/ItemSelectionInput/directives/OppiaShortResponseItemSelectionInputDirective.js"></script>\n \n<link rel="stylesheet" type="text/css" href="/extensions/interactions/MultipleChoiceInput/static/multiple_choice_input.css">\n\n<script src="/templates/dev/head/filters/ConvertToPlainTextFilter.js"></script>\n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/OppiaInteractiveMultipleChoiceInputDirective.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/OppiaResponseMultipleChoiceInputDirective.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/OppiaShortResponseMultipleChoiceInputDirective.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/MultipleChoiceInputRulesService.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/MultipleChoiceInputValidationService.js"></script>\n \n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/TextInput/directives/OppiaInteractiveTextInputDirective.js"></script>\n<script src="/extensions/interactions/TextInput/directives/OppiaResponseTextInputDirective.js"></script>\n<script src="/extensions/interactions/TextInput/directives/OppiaShortResponseTextInputDirective.js"></script>\n<script src="/extensions/interactions/TextInput/directives/TextInputRulesService.js"></script>\n<script src="/extensions/interactions/TextInput/directives/TextInputValidationService.js"></script>\n \n<script src="/extensions/interactions/DragAndDropSortInput/directives/DragAndDropSortInputRulesService.js"></script>\n<script src="/extensions/interactions/DragAndDropSortInput/directives/DragAndDropSortInputValidationService.js"></script>\n<script src="/extensions/interactions/DragAndDropSortInput/directives/OppiaInteractiveDragAndDropSortInputDirective.js"></script>\n<script src="/extensions/interactions/DragAndDropSortInput/directives/OppiaResponseDragAndDropSortInputDirective.js"></script>\n<script src="/extensions/interactions/DragAndDropSortInput/directives/OppiaShortResponseDragAndDropSortInputDirective.js"></script>\n \n<script src="/extensions/interactions/FractionInput/directives/OppiaInteractiveFractionInputDirective.js"></script>\n<script src="/extensions/interactions/FractionInput/directives/OppiaResponseFractionInputDirective.js"></script>\n<script src="/extensions/interactions/FractionInput/directives/OppiaShortResponseFractionInputDirective.js"></script>\n<script src="/extensions/interactions/FractionInput/directives/FractionInputRulesService.js"></script>\n<script src="/extensions/interactions/FractionInput/directives/FractionInputValidationService.js"></script>\n \n<script src="/extensions/interactions/GraphInput/directives/OppiaInteractiveGraphInputDirective.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/OppiaResponseGraphInputDirective.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/OppiaShortResponseGraphInputDirective.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphVizDirective.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphInputRulesService.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphDetailService.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphUtilsService.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphInputValidationService.js"></script>\n \n<link rel="stylesheet" href="/extensions/interactions/LogicProof/static/logic_proof.css">\n\n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/OppiaInteractiveLogicProofDirective.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/OppiaResponseLogicProofDirective.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/OppiaShortResponseLogicProofDirective.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/LogicProofRulesService.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/LogicProofValidationService.js"></script>\n \n<script src="/extensions/interactions/NumericInput/directives/OppiaInteractiveNumericInputDirective.js"></script>\n<script src="/extensions/interactions/NumericInput/directives/OppiaResponseNumericInputDirective.js"></script>\n<script src="/extensions/interactions/NumericInput/directives/OppiaShortResponseNumericInputDirective.js"></script>\n<script src="/extensions/interactions/NumericInput/directives/NumericInputRulesService.js"></script>\n<script src="/extensions/interactions/NumericInput/directives/NumericInputValidationService.js"></script>\n \n<script src="/extensions/interactions/SetInput/directives/OppiaInteractiveSetInputDirective.js"></script>\n<script src="/extensions/interactions/SetInput/directives/OppiaShortResponseSetInputDirective.js"></script>\n<script src="/extensions/interactions/SetInput/directives/OppiaResponseSetInputDirective.js"></script>\n<script src="/extensions/interactions/SetInput/directives/SetInputRulesService.js"></script>\n<script src="/extensions/interactions/SetInput/directives/SetInputValidationService.js"></script>\n \n<script src="/extensions/interactions/MathExpressionInput/directives/OppiaInteractiveMathExpressionInputDirective.js"></script>\n<script src="/extensions/interactions/MathExpressionInput/directives/OppiaResponseMathExpressionInputDirective.js"></script>\n<script src="/extensions/interactions/MathExpressionInput/directives/OppiaShortResponseMathExpressionInputDirective.js"></script>\n<script src="/extensions/interactions/MathExpressionInput/directives/MathExpressionInputRulesService.js"></script>\n<script src="/extensions/interactions/MathExpressionInput/directives/MathExpressionInputValidationService.js"></script>\n \n<script src="/extensions/interactions/NumberWithUnits/directives/OppiaInteractiveNumberWithUnitsDirective.js"></script>\n<script src="/extensions/interactions/NumberWithUnits/directives/OppiaResponseNumberWithUnitsDirective.js"></script>\n<script src="/extensions/interactions/NumberWithUnits/directives/OppiaShortResponseNumberWithUnitsDirective.js"></script>\n<script src="/extensions/interactions/NumberWithUnits/directives/NumberWithUnitsRulesService.js"></script>\n<script src="/extensions/interactions/NumberWithUnits/directives/NumberWithUnitsValidationService.js"></script>\n \n<link rel="stylesheet" type="text/css" href="/extensions/interactions/CodeRepl/static/code_repl.css">\n\n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/OppiaInteractiveCodeReplDirective.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/OppiaResponseCodeReplDirective.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/OppiaShortResponseCodeReplDirective.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/CodeReplRulesService.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/CodeReplValidationService.js"></script>\n \n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/OppiaInteractivePencilCodeEditorDirective.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/OppiaShortResponsePencilCodeEditorDirective.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/OppiaResponsePencilCodeEditorDirective.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/PencilCodeEditorRulesService.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/PencilCodeEditorValidationService.js"></script>\n \n<link rel="stylesheet" type="text/css" href="/extensions/interactions/MusicNotesInput/static/music_notes_input.css">\n\n<script src="/extensions/interactions/MusicNotesInput/directives/OppiaInteractiveMusicNotesInputDirective.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/OppiaResponseMusicNotesInputDirective.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/OppiaShortResponseMusicNotesInputDirective.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/MusicPhrasePlayerService.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/MusicNotesInputRulesService.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/MusicNotesInputValidationService.js"></script>\n \n<script src="/extensions/interactions/InteractiveMap/directives/OppiaInteractiveInteractiveMapDirective.js"></script>\n<script src="/extensions/interactions/InteractiveMap/directives/OppiaResponseInteractiveMapDirective.js"></script>\n<script src="/extensions/interactions/InteractiveMap/directives/OppiaShortResponseInteractiveMapDirective.js"></script>\n<script src="/extensions/interactions/InteractiveMap/directives/InteractiveMapRulesService.js"></script>\n<script src="/extensions/interactions/InteractiveMap/directives/InteractiveMapValidationService.js"></script>\n\n <script>// Copyright 2019 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for "enumerated frequency table" visualization.\n */\n// Each visualization receives three variables: \'data\', \'options\', and\n// \'isAddressed\'. The exact format for each of these is specific to the\n// particular visualization.\noppia.directive(\'oppiaVisualizationEnumeratedFrequencyTable\', [\n \'UrlInterpolationService\', function (UrlInterpolationService) {\n return {\n restrict: \'E\',\n scope: {},\n bindToController: {},\n templateUrl: UrlInterpolationService.getExtensionResourceUrl(\'/visualizations/enumerated_frequency_table_directive.html\'),\n controllerAs: \'$ctrl\',\n controller: [\n \'$attrs\', \'HtmlEscaperService\',\n function ($attrs, HtmlEscaperService) {\n var ctrl = this;\n ctrl.data = HtmlEscaperService.escapedJsonToObj($attrs.escapedData);\n ctrl.options =\n HtmlEscaperService.escapedJsonToObj($attrs.escapedOptions);\n ctrl.addressedInfoIsSupported = $attrs.addressedInfoIsSupported;\n ctrl.answerVisible = ctrl.data.map(function (_, i) {\n // First element is shown while all others are hidden by default.\n return i === 0;\n });\n ctrl.toggleAnswerVisibility = function (i) {\n ctrl.answerVisible[i] = !ctrl.answerVisible[i];\n };\n }\n ]\n };\n }\n]);\n// Copyright 2014 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for "bar chart" visualization.\n */\n// Each visualization receives three variables: \'data\', \'options\', and\n// \'isAddressed\'. The exact format for each of these is specific to the\n// particular visualization.\noppia.directive(\'oppiaVisualizationBarChart\', [function () {\n return {\n restrict: \'E\',\n scope: {},\n bindToController: {},\n template: \'\',\n controllerAs: \'$ctrl\',\n controller: [\n \'$attrs\', \'$element\', \'HtmlEscaperService\',\n function ($attrs, $element, HtmlEscaperService) {\n var ctrl = this;\n ctrl.data = HtmlEscaperService.escapedJsonToObj($attrs.escapedData);\n ctrl.options =\n HtmlEscaperService.escapedJsonToObj($attrs.escapedOptions);\n var dataArray = [[\'Answers\', \'\']];\n for (var i = 0; i < ctrl.data.length; i++) {\n dataArray.push([\n String(ctrl.data[i].answer), ctrl.data[i].frequency\n ]);\n }\n var data = google.visualization.arrayToDataTable(dataArray);\n var options = {\n chartArea: {\n width: \'60%\'\n },\n hAxis: {\n title: \'Number of times answer was submitted\',\n minValue: 0\n },\n legend: null,\n vAxis: {\n title: \'Answer choice\'\n }\n };\n var chart = new google.visualization.BarChart($element[0]);\n chart.draw(data, options);\n }\n ]\n };\n }]);\n// Copyright 2019 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for the "frequency table" visualization.\n */\n// Each visualization receives three variables: \'data\', \'options\', and\n// \'isAddressed\'. The exact format for each of these is specific to the\n// particular visualization.\noppia.directive(\'oppiaVisualizationFrequencyTable\', [\n \'UrlInterpolationService\', function (UrlInterpolationService) {\n return {\n restrict: \'E\',\n scope: {},\n bindToController: {},\n templateUrl: UrlInterpolationService.getExtensionResourceUrl(\'/visualizations/frequency_table_directive.html\'),\n controllerAs: \'$ctrl\',\n controller: [\n \'$attrs\', \'HtmlEscaperService\',\n function ($attrs, HtmlEscaperService) {\n var ctrl = this;\n ctrl.data = HtmlEscaperService.escapedJsonToObj($attrs.escapedData);\n ctrl.options =\n HtmlEscaperService.escapedJsonToObj($attrs.escapedOptions);\n ctrl.addressedInfoIsSupported = $attrs.addressedInfoIsSupported;\n }\n ]\n };\n }\n]);\n</script>\n\n <script src="https://pencilcode.net/lib/pencilcodeembed.js"></script>\n\n<script src="/third_party/static/math-expressions-1.7.0/math-expressions.js"></script>\n\n<script src="/third_party/static/code-mirror-3.19.0/lib/codemirror.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/coffeescript/coffeescript.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/javascript/javascript.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/lua/lua.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/python/python.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/ruby/ruby.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/scheme/scheme.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/yaml/yaml.js"></script>\n<script src="/third_party/static/ui-codemirror-0.1.2/src/ui-codemirror.js"></script>\n\n<script src="/third_party/static/code-mirror-3.19.0/addon/merge/dep/diff_match_patch.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/addon/merge/merge.js"></script>\n\n<script src="/extensions/interactions/LogicProof/static/js/shared.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/student.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/teacher.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/data.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/generatedDefaultData.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/generatedParser.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/conversion.js"></script>\n\n<script src="/third_party/static/skulpt-0.10.0/skulpt.min.js">\n</script>\n<script src="/third_party/static/skulpt-0.10.0/skulpt-stdlib.js">\n</script>\n\n<script src="/templates/dev/head/domain/classifier/PredictionResultObjectFactory.js"></script>\n<script src="/extensions/interactions/CodeRepl/CodeReplPredictionService.js"></script>\n<script src="/extensions/classifiers/PythonProgramTokenizer.js"></script>\n<script src="/extensions/classifiers/SVMPredictionService.js"></script>\n<script src="/extensions/classifiers/CountVectorizerService.js"></script>\n<script src="/extensions/classifiers/WinnowingPreprocessingService.js"></script>\n\n<script src="/templates/dev/head/domain/classifier/PredictionResultObjectFactory.js"></script>\n<script src="/extensions/interactions/TextInput/TextInputPredictionService.js"></script>\n<script src="/extensions/classifiers/SVMPredictionService.js"></script>\n<script src="/extensions/classifiers/TextInputTokenizer.js"></script>\n<script src="/extensions/classifiers/CountVectorizerService.js"></script>\n\n<link rel="stylesheet" href="/third_party/static/leaflet-1.4.0/leaflet.css">\n<script src="/third_party/static/leaflet-1.4.0/leaflet.js"></script>\n<script src="/third_party/static/angular-ui-leaflet-1.0.3/ui-leaflet.min.no-header.js"></script>\n<!-- The angular-simple-logger is a dependency in ui-leaflet angular plugin. -->\n<script src="/third_party/static/angular-simple-logger-0.1.7/angular-simple-logger.min.js"></script>\n\n<link rel="stylesheet" href="/third_party/static/guppy-b5055b/build/guppy-default.min.css">\n<script type="text/javascript" src="/third_party/static/guppy-b5055b/build/guppy.min.js"></script>\n\n<script type="text/javascript">\n Guppy.init({\n "path": "/third_party/static/guppy-b5055b/build"\n });\n</script>\n\n<style>\n .guppy_active {\n border: 1px solid rgba(81, 203, 238, 1);\n }\n\n .guppy_inactive {\n background: #ffffff;\n border: 1px solid black;\n }\n\n .guppy_active .main_cursor {\n animation: guppy-blink-animation 1s steps(2, start) infinite;\n -webkit-animation: guppy-blink-animation 1s steps(2, start) infinite;\n /* Overrides the inline styling and sets the cursor color to black. */\n color: black !important;\n }\n\n @keyframes guppy-blink-animation {\n to { visibility: hidden; }\n }\n\n @-webkit-keyframes guppy-blink-animation {\n to { visibility: hidden; }\n }\n</style>\n\n<script src="/third_party/static/midi-js-2ef687/build/MIDI.js"></script>\n<!-- This is needed for MIDI.js to work. -->\n<script src="/third_party/static/midi-js-2ef687/inc/base64binary.js"></script>\n<script>\n $(document).ready(function() {\n MIDI.loadPlugin({\n soundfontUrl: \'/third_party/static/midi-js-2ef687/soundfont/\',\n instrument: \'acoustic_grand_piano\',\n callback: function() {}\n });\n });\n</script>\n\n\n </body>\n</html>'
381
382----------------------------------------------------------------------
383Ran 4 tests in 4.019s
384
385FAILED (failures=1)
386Traceback (most recent call last):
387 File "/home/thejedicode/oppia3/oppia/core/tests/gae_suite.py", line 119, in <module>
388 main()
389 File "/home/thejedicode/oppia3/oppia/core/tests/gae_suite.py", line 112, in main
390 result.testsRun, len(result.errors), len(result.failures)))
391Exception: Test suite failed: 4 tests run, 0 errors, 1 failures.
392
393
394+------------------+
395| SUMMARY OF TESTS |
396+------------------+
397
398======================================================================
399FAIL: test_editor_page (core.controllers.editor_test.EditorTests)
400----------------------------------------------------------------------
401Traceback (most recent call last):
402 File "/home/thejedicode/oppia3/oppia/core/controllers/editor_test.py", line 149, in test_editor_page
403 self.assertIn('sss', response.body)
404AssertionError: 'sss' not found in '\n\n<!DOCTYPE html>\n<html ng-app="oppia" lang="<[currentLang]>" ng-controller="Base" itemscope itemtype="http://schema.org/Organization">\n <head>\n \n \n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=yes">\n <meta name="referrer" content="no-referrer">\n <meta name="description" content="Oppia is a free site for sharing knowledge via interactive lessons called explorations. Learn from user-created explorations, or teach and create your own.">\n\n <!-- Tiles for Internet Explorer. -->\n <meta name="application-name" content="<[siteName]>">\n <meta name="msapplication-TileColor" content="#ffffff">\n <meta name="msapplication-square70x70logo" content="http://localhost/assets/images/logo/msapplication-tiny.png">\n <meta name="msapplication-square150x150logo" content="http://localhost/assets/images/logo/msapplication-square.png">\n <meta name="msapplication-wide310x150logo" content="http://localhost/assets/images/logo/msapplication-wide.png">\n <meta name="msapplication-square310x310logo" content="http://localhost/assets/images/logo/msapplication-large.png">\n\n <!-- The itemprops are for G+ sharing. -->\n <meta itemprop="name" content="Personalized Online Learning from Oppia">\n <meta itemprop="description" content="Help others learn new things. Create lessons through explorations and share your knowledge with the community.">\n <!-- The og tags are for Facebook sharing. -->\n <meta property="og:title" content="Personalized Online Learning from Oppia">\n <meta property="og:site_name" content="Oppia">\n <meta property="og:url" content="http://localhost/create/0">\n <meta property="og:description" content="Help others learn new things. Create lessons through explorations and share your knowledge with the community.">\n <meta property="og:type" content="article">\n <meta property="og:image" content="http://localhost/assets/images/logo/288x288_logo_mint.png">\n\n <link rel="apple-touch-icon" href="/assets/images/logo/favicon.png">\n\n <title itemprop="name">\n \n Oppia\n \n </title>\n \n \n\n \n <link rel="stylesheet" type="text/css" media="screen"\n href="https://fonts.googleapis.com/css?family=Capriola|Roboto|Material+Icons">\n\n <link rel="stylesheet" type="text/css" media="screen"\n href="/third_party/generated/css/third_party.css">\n\n<link rel="stylesheet" type="text/css" media="screen"\n href="/templates/dev/head/css/oppia.css">\n \n\n <script>\n var GLOBALS = {\n ADDITIONAL_ANGULAR_MODULES: JSON.parse(\n \'[\\"ui-leaflet\\", \\"ui.codemirror\\"]\'),\n csrf_token: JSON.parse(\'\\"1559675635/5wjr78rde0tKCN_nEU7eIg==\\"\'),\n status_code: JSON.parse(\'200\'),\n GCS_RESOURCE_BUCKET_NAME: JSON.parse(\'null\'),\n isTopicManager: JSON.parse(\'false\'),\n userIsLoggedIn: JSON.parse(\'true\')\n };\n </script>\n\n \n \n <script src="/assets/rich_text_components_definitions.js"></script>\n<script src="/assets/constants.js"></script>\n\n<!-- jquery.js, angular.js and jquery-ui.js are removed from bundled js because\nthey need to be at the header. Including bundled js at the header will block\nrendering.-->\n<script src="/third_party/static/jquery-3.4.1/jquery.min.js"></script>\n<script src="/third_party/static/jqueryui-1.12.1/jquery-ui.min.js"></script>\n<script src="/third_party/static/angularjs-1.5.8/angular.min.js"></script>\n<script src="/third_party/static/jquery-ui-touch-punch-0.3.1/jquery.ui.touch-punch-improved.js"></script>\n<script src="/third_party/static/headroom-js-0.9.4/headroom.min.js"></script>\n<script src="/third_party/static/headroom-js-0.9.4/angular.headroom.min.js"></script>\n<script src="/third_party/static/angular-drag-and-drop-lists-2.1.0/angular-drag-and-drop-lists.min.js"></script>\n \n <script type="text/javascript">\n GLOBALS.can_edit = JSON.parse(\'true\');\n GLOBALS.can_publish = JSON.parse(\'false\');\n GLOBALS.can_voiceover = JSON.parse(\'true\');\n GLOBALS.DEFAULT_OBJECT_VALUES = JSON.parse(\n \'{\\"ListOfCoordTwoDim\\": [], \\"Graph\\": {\\"isWeighted\\": false, \\"isDirected\\": false, \\"edges\\": [], \\"isLabeled\\": false, \\"vertices\\": []}, \\"ListOfSetsOfHtmlStrings\\": [], \\"SetOfNormalizedString\\": [], \\"Fraction\\": {\\"denominator\\": 1, \\"numerator\\": 0, \\"wholeNumber\\": 0, \\"isNegative\\": false}, \\"CoordTwoDim\\": [0.0, 0.0], \\"Real\\": 0.0, \\"ListOfCodeEvaluation\\": [], \\"DragAndDropHtmlString\\": \\"\\", \\"LogicErrorCategory\\": \\"mistake\\", \\"DragAndDropPositiveInt\\": 1, \\"NormalizedString\\": \\"\\", \\"MusicPhrase\\": [], \\"ListOfGraph\\": [], \\"SetOfUnicodeString\\": [], \\"SetOfHtmlString\\": [], \\"NonnegativeInt\\": 0, \\"GraphProperty\\": \\"strongly_connected\\", \\"NumberWithUnits\\": {\\"real\\": 0.0, \\"units\\": [], \\"type\\": \\"real\\", \\"fraction\\": {\\"denominator\\": 1, \\"numerator\\": 0, \\"wholeNumber\\": 0, \\"isNegative\\": false}}, \\"Int\\": 0, \\"CodeString\\": \\"\\", \\"UnicodeString\\": \\"\\"}\');\n GLOBALS.DEFAULT_TWITTER_SHARE_MESSAGE_EDITOR = JSON.parse(\n \'\\"Check out this interactive lesson I created on Oppia - a free platform for teaching and learning!\\"\');\n GLOBALS.INTERACTION_SPECS = JSON.parse(\'{\\"ItemSelectionInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Item Selection\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"DoesNotContainAtLeastOneOf\\": \\"omits at least one of {{x|SetOfHtmlString}}\\", \\"ContainsAtLeastOneOf\\": \\"contains at least one of {{x|SetOfHtmlString}}\\", \\"IsProperSubsetOf\\": \\"is a proper subset of {{x|SetOfHtmlString}}\\", \\"Equals\\": \\"is equal to {{x|SetOfHtmlString}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": 1, \\"schema\\": {\\"type\\": \\"int\\", \\"validators\\": [{\\"min_value\\": 0, \\"id\\": \\"is_at_least\\"}]}, \\"name\\": \\"minAllowableSelectionCount\\", \\"description\\": \\"Minimum number of selections permitted.\\"}, {\\"default_value\\": 1, \\"schema\\": {\\"type\\": \\"int\\", \\"validators\\": [{\\"min_value\\": 1, \\"id\\": \\"is_at_least\\"}]}, \\"name\\": \\"maxAllowableSelectionCount\\", \\"description\\": \\"Maximum number of selections permitted\\"}, {\\"default_value\\": [\\"\\"], \\"schema\\": {\\"items\\": {\\"type\\": \\"html\\", \\"ui_config\\": {\\"hide_complex_extensions\\": true, \\"placeholder\\": \\"Sample item answer\\"}}, \\"type\\": \\"list\\", \\"ui_config\\": {\\"add_element_text\\": \\"Add item for selection\\"}}, \\"name\\": \\"choices\\", \\"description\\": \\"Items for selection\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"SetOfHtmlString\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"ItemSelectionInput\\", \\"description\\": \\"Allows learners to select various options.\\"}, \\"GraphInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Graph Theory\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsIsomorphicTo\\": \\"is isomorphic to {{g|Graph}}, including matching labels\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": {\\"isWeighted\\": false, \\"isDirected\\": false, \\"edges\\": [{\\"src\\": 0, \\"dst\\": 1, \\"weight\\": 1}, {\\"src\\": 1, \\"dst\\": 2, \\"weight\\": 1}], \\"isLabeled\\": false, \\"vertices\\": [{\\"y\\": 50.0, \\"x\\": 150.0, \\"label\\": \\"\\"}, {\\"y\\": 50.0, \\"x\\": 200.0, \\"label\\": \\"\\"}, {\\"y\\": 100.0, \\"x\\": 150.0, \\"label\\": \\"\\"}]}, \\"schema\\": {\\"obj_type\\": \\"Graph\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"graph\\", \\"description\\": \\"Initial graph\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canAddVertex\\", \\"description\\": \\"Allow learner to add vertices\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canDeleteVertex\\", \\"description\\": \\"Allow learner to delete vertices\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canMoveVertex\\", \\"description\\": \\"Allow learner to move vertices\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canEditVertexLabel\\", \\"description\\": \\"Allow learner to edit vertex labels\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canAddEdge\\", \\"description\\": \\"Allow learner to add edges\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canDeleteEdge\\", \\"description\\": \\"Allow learner to delete edges\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"canEditEdgeWeight\\", \\"description\\": \\"Allow learner to edit edge weights\\"}], \\"narrow_instructions\\": \\"View graph\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"Graph\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Create a graph\\", \\"is_trainable\\": false, \\"id\\": \\"GraphInput\\", \\"description\\": \\"Allows learners to create and manipulate graphs.\\"}, \\"MathExpressionInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Math Expression Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsMathematicallyEquivalentTo\\": \\"is mathematically equivalent to (LaTeX) {{x|UnicodeString}}\\"}, \\"customization_arg_specs\\": [], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"MathExpression\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"MathExpressionInput\\", \\"description\\": \\"Allows learners to enter mathematical expressions.\\"}, \\"CodeRepl\\": {\\"is_terminal\\": false, \\"name\\": \\"Code Editor\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"CodeContains\\": \\"has code that contains {{x|CodeString}}\\", \\"OutputEquals\\": \\"has output equal to {{x|CodeString}}\\", \\"OutputContains\\": \\"has output that contains {{x|CodeString}}\\", \\"CodeEquals\\": \\"has code equal to {{x|CodeString}}\\", \\"CodeDoesNotContain\\": \\"has code that does not contain {{x|CodeString}}\\", \\"ResultsInError\\": \\"results in an error when run\\", \\"ErrorContains\\": \\"has error message that contains {{x|UnicodeString}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": \\"python\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"choices\\": [\\"python\\"]}, \\"name\\": \\"language\\", \\"description\\": \\"Programming language\\"}, {\\"default_value\\": \\"# Type your code here.\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"ui_config\\": {\\"coding_mode\\": \\"none\\"}}, \\"name\\": \\"placeholder\\", \\"description\\": \\"Initial code displayed\\"}, {\\"default_value\\": \\"\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"ui_config\\": {\\"coding_mode\\": \\"none\\"}}, \\"name\\": \\"preCode\\", \\"description\\": \\"Code to prepend to the learner\\\'s submission\\"}, {\\"default_value\\": \\"\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"ui_config\\": {\\"coding_mode\\": \\"none\\"}}, \\"name\\": \\"postCode\\", \\"description\\": \\"Code to append after the learner\\\'s submission\\"}], \\"narrow_instructions\\": \\"Go to code editor\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"CodeEvaluation\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Type code in the editor\\", \\"is_trainable\\": true, \\"id\\": \\"CodeRepl\\", \\"description\\": \\"Allows learners to enter code and get it evaluated.\\"}, \\"FractionInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Fraction Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsEquivalentToAndInSimplestForm\\": \\"is equivalent to {{f|Fraction}} and in simplest form\\", \\"HasIntegerPartEqualTo\\": \\"has integer part equal to {{x|Int}}\\", \\"IsLessThan\\": \\"is less than {{f|Fraction}}\\", \\"IsEquivalentTo\\": \\"is equivalent to {{f|Fraction}}\\", \\"HasDenominatorEqualTo\\": \\"has denominator equal to {{x|NonnegativeInt}}\\", \\"HasNumeratorEqualTo\\": \\"has numerator equal to {{x|Int}}\\", \\"HasNoFractionalPart\\": \\"has no fractional part\\", \\"HasFractionalPartExactlyEqualTo\\": \\"has fractional part exactly equal to {{f|Fraction}}\\", \\"IsGreaterThan\\": \\"is greater than {{f|Fraction}}\\", \\"IsExactlyEqualTo\\": \\"exactly matches {{f|Fraction}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"requireSimplestForm\\", \\"description\\": \\"Require the learner\\\'s answer to be in simplest form\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"allowImproperFraction\\", \\"description\\": \\"Allow improper fractions in the learner\\\'s answer\\"}, {\\"default_value\\": true, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"allowNonzeroIntegerPart\\", \\"description\\": \\"Allow the answer to contain an integer part\\"}, {\\"default_value\\": \\"\\", \\"schema\\": {\\"type\\": \\"unicode\\"}, \\"name\\": \\"customPlaceholder\\", \\"description\\": \\"Custom placeholder text (optional)\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"Fraction\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"FractionInput\\", \\"description\\": \\"Allows learners to enter integers and fractions.\\"}, \\"ImageClickInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Image Region\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsInRegion\\": \\"is in the region {{x|UnicodeString}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": {\\"labeledRegions\\": [], \\"imagePath\\": \\"\\"}, \\"schema\\": {\\"obj_type\\": \\"ImageWithRegions\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"imageAndRegions\\", \\"description\\": \\"Image\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"highlightRegionsOnHover\\", \\"description\\": \\"Highlight regions when the learner hovers over them\\"}], \\"narrow_instructions\\": \\"View image\\", \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"ClickOnImage\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Click on the image\\", \\"is_trainable\\": false, \\"id\\": \\"ImageClickInput\\", \\"description\\": \\"Allows learners to click on regions of an image.\\"}, \\"LogicProof\\": {\\"is_terminal\\": false, \\"name\\": \\"Logic Proof\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"NotCorrectByCategory\\": \\"is not correct due to {{c|LogicErrorCategory}}\\", \\"Correct\\": \\"is correct\\", \\"NotCorrect\\": \\"is not correct\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": {\\"assumptions\\": [{\\"arguments\\": [], \\"dummies\\": [], \\"top_kind_name\\": \\"variable\\", \\"top_operator_name\\": \\"p\\"}], \\"default_proof_string\\": \\"\\", \\"results\\": [{\\"arguments\\": [], \\"dummies\\": [], \\"top_kind_name\\": \\"variable\\", \\"top_operator_name\\": \\"p\\"}]}, \\"schema\\": {\\"obj_type\\": \\"LogicQuestion\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"question\\", \\"description\\": \\"Question to ask\\"}], \\"narrow_instructions\\": \\"Construct a proof\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"CheckedProof\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Construct a proof\\", \\"is_trainable\\": false, \\"id\\": \\"LogicProof\\", \\"description\\": \\"Allows learners to write proofs for simple logical statements.\\"}, \\"MultipleChoiceInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Multiple Choice\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"Equals\\": \\"is equal to {{x|NonnegativeInt}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": [\\"\\"], \\"schema\\": {\\"items\\": {\\"type\\": \\"html\\", \\"ui_config\\": {\\"hide_complex_extensions\\": true, \\"placeholder\\": \\"Enter an option for the learner to select\\"}}, \\"type\\": \\"list\\", \\"ui_config\\": {\\"add_element_text\\": \\"Add multiple choice option\\"}, \\"validators\\": [{\\"min_value\\": 1, \\"id\\": \\"has_length_at_least\\"}]}, \\"name\\": \\"choices\\", \\"description\\": \\"Multiple Choice options\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"NonnegativeInt\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"MultipleChoiceInput\\", \\"description\\": \\"Allows learners to select one of a list of multiple-choice options.\\"}, \\"DragAndDropSortInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Drag And Drop Sort\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsEqualToOrdering\\": \\"is equal to ordering {{x|ListOfSetsOfHtmlStrings}}\\", \\"HasElementXBeforeElementY\\": \\"has element {{x|DragAndDropHtmlString}} before element {{y|DragAndDropHtmlString}}\\", \\"IsEqualToOrderingWithOneItemAtIncorrectPosition\\": \\"is equal to ordering with one item at incorrect position {{x|ListOfSetsOfHtmlStrings}}\\", \\"HasElementXAtPositionY\\": \\"has element {{x|DragAndDropHtmlString}} at position {{y|DragAndDropPositiveInt}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": [\\"\\"], \\"schema\\": {\\"items\\": {\\"type\\": \\"html\\", \\"ui_config\\": {\\"hide_complex_extensions\\": true, \\"placeholder\\": \\"Enter an option for the learner to drag and drop.\\"}}, \\"type\\": \\"list\\", \\"ui_config\\": {\\"add_element_text\\": \\"Add a new item\\"}, \\"validators\\": [{\\"min_value\\": 1, \\"id\\": \\"has_length_at_least\\"}]}, \\"name\\": \\"choices\\", \\"description\\": \\"Items for drag and drop\\"}, {\\"default_value\\": false, \\"schema\\": {\\"type\\": \\"bool\\"}, \\"name\\": \\"allowMultipleItemsInSamePosition\\", \\"description\\": \\"Allow multiple sort items in the same position\\"}], \\"narrow_instructions\\": \\"Drag and drop items\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"ListOfSetsOfHtmlStrings\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Drag and drop items\\", \\"is_trainable\\": false, \\"id\\": \\"DragAndDropSortInput\\", \\"description\\": \\"Allows learners to drag and drop items for sorting.\\"}, \\"PencilCodeEditor\\": {\\"is_terminal\\": false, \\"name\\": \\"Pencil Code Editor\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"CodeContains\\": \\"has code that contains {{x|CodeString}}\\", \\"OutputEquals\\": \\"has output equal to {{x|CodeString}}\\", \\"CodeEquals\\": \\"has code equal to {{x|CodeString}}\\", \\"CodeDoesNotContain\\": \\"has code that does not contain {{x|CodeString}}\\", \\"ResultsInError\\": \\"results in an error when run\\", \\"ErrorContains\\": \\"has error message that contains {{x|UnicodeString}}\\", \\"OutputRoughlyEquals\\": \\"has output equal to {{x|CodeString}}, ignoring spacing and case\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": \\"# Add the initial code snippet here.\\", \\"schema\\": {\\"type\\": \\"unicode\\", \\"ui_config\\": {\\"coding_mode\\": \\"coffeescript\\"}}, \\"name\\": \\"initial_code\\", \\"description\\": \\"The initial code\\"}], \\"narrow_instructions\\": \\"Show code editor\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"CodeEvaluation\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Edit the code. Click \\\'Play\\\' to check it!\\", \\"is_trainable\\": false, \\"id\\": \\"PencilCodeEditor\\", \\"description\\": \\"Allows learners to edit code in Pencil Code.\\"}, \\"EndExploration\\": {\\"is_terminal\\": true, \\"name\\": \\"End Exploration\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {}, \\"customization_arg_specs\\": [{\\"default_value\\": [], \\"schema\\": {\\"items\\": {\\"type\\": \\"unicode\\"}, \\"type\\": \\"list\\", \\"ui_config\\": {\\"add_element_text\\": \\"Add exploration ID\\"}}, \\"name\\": \\"recommendedExplorationIds\\", \\"description\\": \\"IDs of explorations to recommend to the learner (at most 3 are shown). The ID of an exploration is the string of characters appearing after \\\'/explore/\\\' in the URL bar.\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": null, \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"EndExploration\\", \\"description\\": \\"Ends the exploration, and suggests recommendations for explorations to try next.\\"}, \\"InteractiveMap\\": {\\"is_terminal\\": false, \\"name\\": \\"World Map\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"Within\\": \\"is within {{d|Real}} km of {{p|CoordTwoDim}}\\", \\"NotWithin\\": \\"is not within {{d|Real}} km of {{p|CoordTwoDim}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": 0.0, \\"schema\\": {\\"type\\": \\"float\\", \\"validators\\": [{\\"min_value\\": -90.0, \\"id\\": \\"is_at_least\\"}, {\\"max_value\\": 90.0, \\"id\\": \\"is_at_most\\"}]}, \\"name\\": \\"latitude\\", \\"description\\": \\"Starting center latitude (-90 to 90)\\"}, {\\"default_value\\": 0.0, \\"schema\\": {\\"type\\": \\"float\\", \\"validators\\": [{\\"min_value\\": -180.0, \\"id\\": \\"is_at_least\\"}, {\\"max_value\\": 180.0, \\"id\\": \\"is_at_most\\"}]}, \\"name\\": \\"longitude\\", \\"description\\": \\"Starting center longitude (-180 to 180)\\"}, {\\"default_value\\": 0.0, \\"schema\\": {\\"type\\": \\"float\\"}, \\"name\\": \\"zoom\\", \\"description\\": \\"Starting zoom level (0 shows the entire earth)\\"}], \\"narrow_instructions\\": \\"View map\\", \\"can_have_solution\\": false, \\"needs_summary\\": true, \\"show_generic_submit_button\\": false, \\"answer_type\\": \\"CoordTwoDim\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Click on the map\\", \\"is_trainable\\": false, \\"id\\": \\"InteractiveMap\\", \\"description\\": \\"Allows learners to specify a position on a world map.\\"}, \\"Continue\\": {\\"is_terminal\\": false, \\"name\\": \\"Continue Button\\", \\"default_outcome_heading\\": \\"When the button is clicked\\", \\"rule_descriptions\\": {}, \\"customization_arg_specs\\": [{\\"default_value\\": \\"Continue\\", \\"schema\\": {\\"type\\": \\"unicode\\"}, \\"name\\": \\"buttonText\\", \\"description\\": \\"Button label\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": false, \\"needs_summary\\": false, \\"show_generic_submit_button\\": false, \\"answer_type\\": null, \\"display_mode\\": \\"inline\\", \\"is_linear\\": true, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"Continue\\", \\"description\\": \\"A simple \\\'go to next state\\\' button.\\"}, \\"SetInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Set Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsSubsetOf\\": \\"is a proper subset of {{x|SetOfUnicodeString}}\\", \\"IsDisjointFrom\\": \\"has no elements in common with {{x|SetOfUnicodeString}}\\", \\"Equals\\": \\"is equal to {{x|SetOfUnicodeString}}\\", \\"OmitsElementsIn\\": \\"omits some elements of {{x|SetOfUnicodeString}}\\", \\"IsSupersetOf\\": \\"is a proper superset of {{x|SetOfUnicodeString}}\\", \\"HasElementsIn\\": \\"has elements in common with {{x|SetOfUnicodeString}}\\", \\"HasElementsNotIn\\": \\"has elements not in {{x|SetOfUnicodeString}}\\"}, \\"customization_arg_specs\\": [], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"SetOfUnicodeString\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"SetInput\\", \\"description\\": \\"Allows learners to enter an unordered set of strings.\\"}, \\"TextInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Text Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"CaseSensitiveEquals\\": \\"is equal to {{x|NormalizedString}}, taking case into account\\", \\"StartsWith\\": \\"starts with {{x|NormalizedString}}\\", \\"Contains\\": \\"contains {{x|NormalizedString}}\\", \\"FuzzyEquals\\": \\"is equal to {{x|NormalizedString}}, misspelled by at most one character\\", \\"Equals\\": \\"is equal to {{x|NormalizedString}}\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": \\"\\", \\"schema\\": {\\"type\\": \\"unicode\\"}, \\"name\\": \\"placeholder\\", \\"description\\": \\"Placeholder text (optional)\\"}, {\\"default_value\\": 1, \\"schema\\": {\\"type\\": \\"int\\", \\"validators\\": [{\\"min_value\\": 1, \\"id\\": \\"is_at_least\\"}, {\\"max_value\\": 200, \\"id\\": \\"is_at_most\\"}]}, \\"name\\": \\"rows\\", \\"description\\": \\"Height (in rows)\\"}], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"NormalizedString\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": true, \\"id\\": \\"TextInput\\", \\"description\\": \\"Allows learners to enter arbitrary text strings.\\"}, \\"NumberWithUnits\\": {\\"is_terminal\\": false, \\"name\\": \\"Number With Units\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsEqualTo\\": \\"is equal to {{f|NumberWithUnits}}\\", \\"IsEquivalentTo\\": \\"is equivalent to {{f|NumberWithUnits}}\\"}, \\"customization_arg_specs\\": [], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"NumberWithUnits\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"NumberWithUnits\\", \\"description\\": \\"Allows learners to enter number with units.\\"}, \\"NumericInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Number Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsGreaterThanOrEqualTo\\": \\"is greater than or equal to {{x|Real}}\\", \\"IsLessThanOrEqualTo\\": \\"is less than or equal to {{x|Real}}\\", \\"Equals\\": \\"is equal to {{x|Real}}\\", \\"IsLessThan\\": \\"is less than {{x|Real}}\\", \\"IsGreaterThan\\": \\"is greater than {{x|Real}}\\", \\"IsWithinTolerance\\": \\"is within {{tol|Real}} of {{x|Real}}\\", \\"IsInclusivelyBetween\\": \\"is between {{a|Real}} and {{b|Real}}, inclusive\\"}, \\"customization_arg_specs\\": [], \\"narrow_instructions\\": null, \\"can_have_solution\\": true, \\"needs_summary\\": false, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"Real\\", \\"display_mode\\": \\"inline\\", \\"is_linear\\": false, \\"instructions\\": null, \\"is_trainable\\": false, \\"id\\": \\"NumericInput\\", \\"description\\": \\"Allows learners to enter integers and floating point numbers.\\"}, \\"MusicNotesInput\\": {\\"is_terminal\\": false, \\"name\\": \\"Music Notes Input\\", \\"default_outcome_heading\\": null, \\"rule_descriptions\\": {\\"IsTranspositionOf\\": \\"is a transposition of {{x|MusicPhrase}} by {{y|Int}} semitones\\", \\"HasLengthInclusivelyBetween\\": \\"has between {{a|NonnegativeInt}} and {{b|NonnegativeInt}} notes, inclusive\\", \\"Equals\\": \\"is equal to {{x|MusicPhrase}}\\", \\"IsEqualToExceptFor\\": \\"is equal to {{x|MusicPhrase}} except for {{k|NonnegativeInt}} notes\\", \\"IsTranspositionOfExceptFor\\": \\"is a transposition of {{x|MusicPhrase}} by {{y|Int}} semitones except for {{k|NonnegativeInt}} notes\\", \\"IsLongerThan\\": \\"has more than {{k|NonnegativeInt}} notes\\"}, \\"customization_arg_specs\\": [{\\"default_value\\": [], \\"schema\\": {\\"obj_type\\": \\"MusicPhrase\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"sequenceToGuess\\", \\"description\\": \\"Correct sequence of notes\\"}, {\\"default_value\\": [], \\"schema\\": {\\"obj_type\\": \\"MusicPhrase\\", \\"type\\": \\"custom\\"}, \\"name\\": \\"initialSequence\\", \\"description\\": \\"Starting notes on the staff\\"}], \\"narrow_instructions\\": \\"Show music staff\\", \\"can_have_solution\\": true, \\"needs_summary\\": true, \\"show_generic_submit_button\\": true, \\"answer_type\\": \\"MusicPhrase\\", \\"display_mode\\": \\"supplemental\\", \\"is_linear\\": false, \\"instructions\\": \\"Drag notes to the staff to form a sequence\\", \\"is_trainable\\": false, \\"id\\": \\"MusicNotesInput\\", \\"description\\": \\"Allows learners to drag and drop notes onto the lines of a music staff.\\"}}\');\n GLOBALS.INVALID_PARAMETER_NAMES = JSON.parse(\n \'[\\"answer\\", \\"choices\\", \\"abs\\", \\"all\\", \\"and\\", \\"any\\", \\"else\\", \\"floor\\", \\"if\\", \\"log\\", \\"or\\", \\"pow\\", \\"round\\", \\"then\\"]\');\n GLOBALS.SHOW_TRAINABLE_UNRESOLVED_ANSWERS = JSON.parse(\n \'false\');\n GLOBALS.TAG_REGEX = JSON.parse(\'\\"^[a-z ]+$\\"\');\n GLOBALS.canDelete = JSON.parse(\'false\');\n GLOBALS.canModifyRoles = JSON.parse(\'false\');\n GLOBALS.canReleaseOwnership = JSON.parse(\n \'false\');\n GLOBALS.canUnpublish = JSON.parse(\'false\');\n </script>\n\n <!-- Updated previous version to current version of google charts\n https://developers.google.com/chart/interactive/docs/basic_load_libs#update-library-loader-code -->\n <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>\n <script type="text/javascript">\n if (window.google && window.google.charts) {\n google.charts.load(\'current\', {packages: [\'corechart\']});\n } else {\n throw \'error: Could not load google visualization library. Are you offline?\';\n }\n </script>\n\n <style>\n html, body {\n background-color: #eee;\n }\n </style>\n\n\n\n \n </head>\n\n <body>\n <div ng-if="iframed">\n <div tabindex="0" aria-label="Oppia Main Content" id="oppia-main-content" class="protractor-test-main-content" ng-cloak>\n <div class="oppia-toast-container toast-top-center">\n <div ng-repeat="warning in (AlertsService.warnings | limitTo:5) track by $index" class="toast toast-warning oppia-toast">\n <button type="button" class="toast-close-button" ng-click="AlertsService.deleteWarning(warning)" role="button">×</button>\n <div class="toast-message">\n <[warning.content]>\n </div>\n </div>\n </div>\n\n <div>\n <div ng-repeat="message in AlertsService.messages track by $index">\n <alert-message message-object="message" message-index="$index"></alert-message>\n </div>\n </div>\n\n <div ng-show="loadingMessage" class="oppia-loading-fullpage">\n <div class="oppia-align-center">\n <span translate="<[loadingMessage]>"></span>\n <span class="oppia-loading-dot-one">.</span>\n <span class="oppia-loading-dot-two">.</span>\n <span class="oppia-loading-dot-three">.</span>\n </div>\n </div>\n <div ng-show="!loadingMessage">\n \n <div ng-controller="ExplorationEditor" ng-cloak>\n <div class="container-fluid oppia-editor-page-container" ng-joy-ride="tutorialInProgress" config="EDITOR_TUTORIAL_OPTIONS" on-finish="onFinishTutorial()" on-skip="onSkipTutorial()">\n <div class="row" ng-if="ExplorationRightsService.isCloned()">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div class="oppia-align-center uib-alert alert-warning" style="padding: 2px; width: 90%;">\n <strong>Note:</strong> This is a private, unpublishable copy of a\n <a ng-href="<[getExplorationUrl(ExplorationRightsService.clonedFrom())]>" target="_blank" rel="noopener">public exploration</a>.\n </div>\n </div>\n </div>\n\n <div ng-show="getActiveTabName() === \'main\'">\n <div class="row">\n <div class="col-lg-8 col-md-8 col-sm-8">\n <div ng-controller="ExplorationEditorTab" class="oppia-editor-cards-container">\n <div class="oppia-editor-header">\n <state-name-editor></state-name-editor>\n </div>\n\n <div ng-if="areParametersEnabled()">\n <state-param-changes-editor></state-param-changes-editor>\n </div>\n\n <state-editor on-save-state-content="saveStateContent"\n on-save-interaction-customization-args="saveInteractionCustomizationArgs"\n on-save-interaction-id="saveInteractionId"\n on-save-interaction-default-outcome="saveInteractionDefaultOutcome"\n on-save-interaction-answer-groups="saveInteractionAnswerGroups"\n on-save-solution="saveSolution"\n on-save-hints="saveHints"\n recompute-graph="recomputeGraph"\n show-mark-all-audio-as-needing-update-modal-if-required="showMarkAllAudioAsNeedingUpdateModalIfRequired"\n state-content-placeholder="getStateContentPlaceholder()"\n navigate-to-state="navigateToState"\n add-state="addState"\n refresh-warnings="refreshWarnings"\n interaction-is-shown="interactionIsShown">\n </state-editor>\n</div>\n </div>\n <div class="col-lg-4 col-md-4 col-sm-4">\n <div class="oppia-editor-sidebar hidden-xs hidden-sm">\n <div ng-controller="ExplorationGraph" ng-show="isGraphShown()" class="oppia-state-graph-animate-show">\n <span style="font-size: 16px;">\n <strong>Exploration Overview</strong>\n </span>\n\n <md-card style="background-color: white; margin: 20px 0px; padding: 8px;">\n <div class="oppia-state-graph-container protractor-test-exploration-graph">\n <div state-graph-visualization graph-data="getGraphData()" current-state-id="getActiveStateName()" on-click-function="onClickStateInMinimap" on-delete-function="deleteState" on-maximize-function="openStateGraphModal" allow-panning="true" center-at-current-state="true" style="height: 100%;" is-editable="isEditable()" show-warning-sign="true">\n </div>\n </div>\n </md-card>\n</div>\n <unresolved-answers-overview></unresolved-answers-overview>\n </div>\n </div>\n <attribution-guide></attribution-guide>\n</div>\n </div>\n\n <div ng-if="getActiveTabName() === \'translation\'">\n <translation-tab></translation-tab>\n </div>\n <!-- This is an ng-if, so that the preview loads the latest version of the exploration each time the tab is accessed. -->\n <div ng-if="getActiveTabName() === \'preview\'">\n <div ng-controller="PreviewTab">\n <div ng-if="isExplorationPopulated">\n <div ng-if="previewWarning">\n <div class="oppia-preview-state-warning"><[previewWarning]></div>\n </div>\n <conversation-skin></conversation-skin>\n <exploration-footer twitter-text=""></exploration-footer>\n\n </div>\n\n <div class="oppia-preview-bottom-right-container">\n <div class="oppia-parameter-summary" ng-if="showParameterSummary()">\n <strong>Parameters:</strong>\n <table>\n <tr ng-repeat="(paramName, paramValue) in allParams">\n <td style="padding: 1px 5px;"><[paramName]>:</td>\n <td style="padding: 1px 5px;">\n <[paramValue != "" ? paramValue : "[Not set]"]>\n </td>\n </tr>\n </table>\n </div>\n <button class="btn-lg" ng-click="resetPreview()">\n <i class="material-icons" style="margin-bottom: 2px;"></i>\n <span style="margin-left: 10px; padding-top: 20px;">Restart From Beginning</span>\n </button>\n </div>\n\n</div>\n\n<style>\n .oppia-preview-bottom-right-container {\n /* Fixed at bottom right corner (before footer) and appear on top of other div*/\n bottom: 10px;\n display: block;\n position: fixed;\n right: 0;\n padding-bottom: 2em;\n z-index: 1060;\n }\n\n .oppia-preview-bottom-right-container .oppia-parameter-summary {\n background-color: #fff;\n font-size: 16px;\n margin: 0px 0px 2px 0px;\n padding: 5px 0px 0px 5px;\n text-align: left;\n }\n\n .oppia-preview-bottom-right-container .btn-lg {\n background-color: #fff;\n border: none;\n border-radius: 0px;\n display: block;\n font-size: 20px;\n text-align: right;\n margin-top: 10px;\n padding-top: 10px;\n }\n\n .oppia-preview-state-warning {\n background-color: #fff;\n border: 1px solid #ccc;\n border-radius: 4px;\n display: block;\n font-size: 16px;\n font-weight: bold;\n left: 6px;\n max-width: 296px;\n padding: 3px;\n position: absolute;\n text-align: left;\n top: 63px;\n white-space: normal;\n z-index: 1060;\n }\n</style>\n </div>\n\n <div ng-show="getActiveTabName() === \'stats\'">\n <div ng-controller="StatisticsTab" ng-cloak>\n <md-card class="oppia-editor-card" ng-if="!loadingMessage">\n <div ng-if="explorationHasBeenVisited">\n <div class="oppia-statistics-display">\n <h3>Exploration Completion Rate</h3>\n <pie-chart data="pieChartData"\n options="COMPLETION_RATE_PIE_CHART_OPTIONS">\n </pie-chart>\n <p style="text-align: center;"><span ng-if="numPassersby" style="font-weight: bold;" class="protractor-test-num-passersby"><[numPassersby]></span><span ng-if="!numPassersby" style="font-weight: bold;">0</span> learners browsed this exploration. They left before reaching the second card.</p>\n\n <h3>Card statistics</h3>\n <div style="font-size: smaller" ng-if="lastUpdated">\n <em>Last updated: <[getLocaleAbbreviatedDatetimeString(lastUpdated)]></em>\n </div>\n <div class="container">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div state-graph-visualization graph-data="statsGraphData"\n node-fill="darkseagreen"\n highlight-states="highlightStates"\n state-stats="stateStats"\n on-click-function="onClickStateInStatsGraph">\n </div>\n </div>\n </div>\n <div class="container" ng-if="playthroughsAreAvailable">\n <playthrough-issues></playthrough-issues>\n </div>\n </div>\n </div>\n </div>\n <div ng-if="!explorationHasBeenVisited">\n <em>\n This exploration has not been visited by anyone yet, so there are no statistics to display.\n </em>\n </div>\n </md-card>\n</div>\n </div>\n\n <improvements-tab ng-if="getActiveTabName() === \'improvements\'">\n </improvements-tab>\n\n <div ng-show="getActiveTabName() === \'settings\'">\n <div ng-controller="SettingsTab">\n <md-card class="oppia-editor-card">\n <h3>Basic Settings</h3>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div ng-if="EditabilityService.isEditable()">\n <div role="form" class="form-horizontal">\n <exploration-title-editor label-text="Title"\n focus-label="<[::EXPLORATION_TITLE_INPUT_FOCUS_LABEL]>"\n form-style="<[::formStyle]>"\n on-input-field-blur="saveExplorationTitle()">\n </exploration-title-editor>\n <exploration-objective-editor label-text="Goal"\n form-style="<[::formStyle]>"\n on-input-field-blur="saveExplorationObjective()">\n </exploration-objective-editor>\n\n <div class="form-group" ng-class="{\'has-error\': !explorationCategoryService.displayed}">\n <label for="explorationCategory" class="col-lg-2 col-md-2 col-sm-2">Category</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <div ng-if="hasPageLoaded">\n <select2-dropdown id="explorationCategory"\n class="protractor-test-exploration-category-input"\n item="explorationCategoryService.displayed"\n choices="CATEGORY_LIST_FOR_SELECT2"\n placeholder="Choose or type new"\n new-choice-regex="^[A-Z a-z]+$"\n on-selection-change="saveExplorationCategory()"\n width="100%"\n invalid-search-term-message="Invalid category name">\n </select2-dropdown>\n </div>\n </div>\n </div>\n\n <div class="form-group">\n <label for="explorationLanguageCode" class="col-lg-2 col-md-2 col-sm-2">Language</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <select id="explorationLanguageCode" class="form-control protractor-test-exploration-language-select" ng-model="explorationLanguageCodeService.displayed" ng-change="saveExplorationLanguageCode()" ng-options="lc.code as lc.description for lc in explorationLanguageCodeService.getAllLanguageCodes()">\n </select>\n <span class="help-block" style="font-size: smaller">\n <em>\n Don\'t see the language you want? <a href="https://github.com/oppia/oppia/issues/new?title=Please%20add%20a%20new%20language%20choice%20to%20the%20exploration%20settings%20tab&body=Please%20add%20the%20language%20choice%20%7B%7BYOUR_LANGUAGE_HERE%7D%7D%20to%20the%20exploration%20settings%20tab.%0A%0AHere%20is%20a%20link%20to%20an%20exploration%20that%20uses%20it:%20%7B%7BINSERT_LINK_HERE%7D%7D" target="_blank" rel="noopener">Tell us.</a>\n </em>\n </span>\n </div>\n </div>\n <div class="form-group">\n <label for="explorationInitStateName" class="col-lg-2 col-md-2 col-sm-2">Name of first card</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <select id="explorationInitStateName" class="form-control protractor-test-initial-state-select" ng-model="explorationInitStateNameService.displayed" ng-change="saveExplorationInitStateName()" ng-options="name as name for name in stateNames track by name">\n </select>\n <span class="help-block" style="font-size: smaller">\n <em>This is the first card the learner sees when playing your exploration.</em>\n </span>\n </div>\n </div>\n <div class="form-group">\n <label for="explorationTags" class="col-lg-2 col-md-2 col-sm-2">Tags</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <div ng-if="hasPageLoaded">\n <select2-dropdown item="$parent.explorationTagsService.displayed"\n choices="$parent.explorationTagsService.displayed"\n allow-multiple-choices="true"\n invalid-search-term-message="Add a new tag (using lowercase letters and spaces)..."\n new-choice-regex="<[::TAG_REGEX]>"\n width="100%"\n placeholder="Skills, concepts, topics..."\n on-selection-change="saveExplorationTags()">\n </select2-dropdown>\n </div>\n <span class="help-block" style="font-size: smaller">\n <em>Tags help learners discover your exploration when searching.</em>\n </span>\n </div>\n </div>\n <div class="text-right">\n <button type="button" class="btn btn-default protractor-test-open-preview-summary-modal"\n ng-click="previewSummaryTile()"\n title="Preview this exploration\'s summary card">\n Preview Summary\n </button>\n </div>\n </div>\n </div>\n\n <div ng-if="!EditabilityService.isEditable()">\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationTitle">\n Title\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationTitle" type="text">\n <[explorationTitleService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationObjective">\n Goal\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationObjective" type="text">\n <[explorationObjectiveService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationCategory">\n Category\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationCategory" type="text">\n <[explorationCategoryService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationLanguageCode">Language</label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <[explorationLanguageCodeService.getCurrentLanguageDescription()]>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationInitStateName">First State</label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <[explorationInitStateNameService.displayed]>\n </div>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <h3>Advanced Features</h3>\n <div class="row">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableParameters" class="col-lg-10 col-md-10 col-sm-10">\n Parameters\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input span ng-if="areParametersEnabled()" type="checkbox" class="oppia-on-off-switch-checkbox" id="parameter-switch" checked disabled>\n <input span ng-if="!areParametersEnabled()" type="checkbox" class="oppia-on-off-switch-checkbox" id="parameter-switch" ng-click="enableParameters()">\n <label class="oppia-on-off-switch-label protractor-test-enable-parameters" for="parameter-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Parameters are values that change as the learner moves between cards (<a href="http://oppia.github.io/#/Parameters" target="_blank" rel="noopener">more info</a>).\n </span>\n </div>\n </div>\n </div>\n <hr>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableAutomaticTextToSpeech" class="col-lg-10 col-md-10 col-sm-10">\n Automatic Text-to-speech\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input type="checkbox" ng-if="isAutomaticTextToSpeechEnabled()" class="oppia-on-off-switch-checkbox" id="text-speech-switch" ng-click="toggleAutomaticTextToSpeech()" checked>\n <input type="checkbox" ng-if="!isAutomaticTextToSpeechEnabled()" class="oppia-on-off-switch-checkbox" id="text-speech-switch" ng-click="toggleAutomaticTextToSpeech()">\n <label class="oppia-on-off-switch-label" for="text-speech-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Automatic text-to-speech generates audio from your content for learners to listen to. It is recommended that you disable this feature if creating an exploration whose content consists of multiple languages.\n </span>\n </div>\n </div>\n </div>\n <hr>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableCorrectnessFeedback" class="col-lg-10 col-md-10 col-sm-10">\n Correctness Feedback\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input type="checkbox" ng-if="!isCorrectnessFeedbackEnabled()" class="oppia-on-off-switch-checkbox" id="correctness-switch" ng-click="toggleCorrectnessFeedback()">\n <input type="checkbox" ng-if="isCorrectnessFeedbackEnabled()" class="oppia-on-off-switch-checkbox" id="correctness-switch" ng-click="toggleCorrectnessFeedback()" checked>\n <label class="oppia-on-off-switch-label" for="correctness-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Correctness feedback allows the user to categorise answer groups as correct or incorrect.\n </span>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card">\n <div ng-if="ExplorationRightsService.ownerNames.length > 0 && !ExplorationRightsService.isCloned()">\n <div class="row">\n <div class="col-lg-5 col-md-5 col-sm-5">\n <h3>Roles</h3>\n <div ng-show="ExplorationRightsService.ownerNames.length > 0">\n <strong>Managers</strong>\n <ul>\n <li ng-repeat="ownerName in ExplorationRightsService.ownerNames track by $index">\n <[ownerName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.editorNames.length > 0">\n <strong>Collaborators</strong>\n <ul>\n <li ng-repeat="editorName in ExplorationRightsService.editorNames track by $index">\n <[editorName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.voiceArtistNames.length > 0">\n <strong>Voice Artists</strong>\n <ul>\n <li ng-repeat="voiceArtistName in ExplorationRightsService.voiceArtistNames track by $index">\n <[voiceArtistName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.viewerNames.length > 0">\n <strong>Playtesters</strong>\n <ul>\n <li ng-repeat="viewerName in ExplorationRightsService.viewerNames track by $index">\n <[viewerName]>\n </li>\n </ul>\n </div>\n\n\n <div ng-if="canModifyRoles" ng-hide="isRolesFormOpen">\n <button type="button" class="btn btn-default protractor-test-edit-roles" ng-click="openEditRolesForm()">\n Edit Roles\n </button>\n </div>\n\n <div ng-if="canModifyRoles" ng-show="isRolesFormOpen">\n <strong>Add or Change Role</strong>\n <div class="form-group">\n <form ng-submit="editRole(newMemberUsername, newMemberRole.value)">\n <label for="newMemberUsername">Username of invited user</label>\n <div>\n <input type="text" id="newMemberUsername" class="form-control protractor-test-role-username" ng-model="newMemberUsername" placeholder="editor">\n </div>\n <br>\n <label for="newMemberRole">Role of invited user</label>\n <div>\n <select ng-model="newMemberRole" class="form-control protractor-test-role-select" ng-options="r.name for r in ROLES" style="width: 250px;">\n </select>\n <span class="help-block">\n Note that managers also have the permissions of collaborators, collaborators also have the permissions of voice artists, and voice artists also have the permissions of viewers. Please note that assigning roles is irreversible (though you can always assign somebody to a higher role).\n </span>\n </div>\n\n <input type="submit" class="btn btn-default protractor-test-save-role" value="Save" ng-disabled="!isTitlePresent()">\n <button type="button" class="btn btn-default" ng-click="closeEditRolesForm()" ng-show="isRolesFormOpen">\n Cancel\n </button>\n <p ng-show="!isTitlePresent()" class="text-danger protractor-test-title-warning">Please provide a title before inviting.</p>\n </form>\n </div>\n </div>\n </div>\n\n <div class="col-lg-7 col-md-7 col-sm-7">\n <h3>Permissions</h3>\n <p ng-if="ExplorationRightsService.isPrivate() && ExplorationRightsService.viewableIfPrivate()">\n This exploration is <strong>private</strong>. Anyone with the link can access it.\n </p>\n <p ng-if="ExplorationRightsService.isPrivate() && !ExplorationRightsService.viewableIfPrivate()">\n This exploration is <strong>private</strong>. Only invited users, moderators and site admins can\n access it.\n </p>\n <p ng-if="!ExplorationRightsService.isPrivate()">\n This exploration is <strong>public</strong>: anyone can access it.\n </p>\n\n <p ng-if="!ExplorationRightsService.isPrivate() || ExplorationRightsService.viewableIfPrivate()">\n <em>Link to share:</em>\n <input class="form-control" type="text" value="<[getExplorePageUrl(explorationId)]>" readonly="readonly" onClick="this.select();">\n </p>\n\n <br>\n\n <p ng-if="ExplorationRightsService.isPrivate()">\n It is <strong>not shown</strong> in the Oppia library.\n </p>\n <p ng-if="!ExplorationRightsService.isPrivate()">\n It is <strong>available</strong> in the Oppia library.\n </p>\n </div>\n </div>\n </div>\n\n <div ng-if="ExplorationRightsService.ownerNames.length === 0 && !ExplorationRightsService.isCloned()">\n <h3>Permissions</h3>\n <div>\n This exploration is <strong>public</strong> and <strong>community-editable</strong>.\n <p ng-if="!ExplorationRightsService.isPrivate()">\n It is <strong>available</strong> in the Oppia library.\n </p>\n </div>\n </div>\n\n <div ng-if="ExplorationRightsService.isCloned()">\n <h3>Status</h3>\n <div>\n This exploration was <strong>cloned</strong> from another exploration.\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <h3>Feedback/Suggestion Email Preferences</h3>\n <div class="row">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="FeedbackNotifications" class="col-lg-3 col-md-3 col-sm-3">\n Feedback emails\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="muteFeedbackNotifications()" ng-if="!UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n Mute\n </button>\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="unmuteFeedbackNotifications()" ng-if="UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n Unmute\n </button>\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="!UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n You are currently receiving notifications of new feedback for this exploration.\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n You have muted feedback notifications for this exploration. You will not receive an email when new feedback is submitted.\n </span>\n </div>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="SuggestionNotifications" class="col-lg-3 col-md-3 col-sm-3">\n Suggestion emails\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="muteSuggestionNotifications()" ng-if="!UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n Mute\n </button>\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="unmuteSuggestionNotifications()" ng-if="UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n Unmute\n </button>\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="!UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n You are currently receiving notifications of new suggestions for this exploration.\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n You have muted suggestion notifications for this exploration. You will not receive an email when new suggestion is submitted.\n </span>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <div class="row">\n <div class="col-lg-6 col-md-6 col-sm-6">\n <h3>Controls</h3>\n\n <p ng-if="canReleaseOwnership" class="oppia-exploration-ctrl" ng-hide="ExplorationRightsService.isCommunityOwned()">\n <button type="button" class="btn btn-default" ng-click="showTransferExplorationOwnershipModal()" ng-disabled="isExplorationLockedForEditing()">\n Transfer ownership to the community\n </button>\n <span ng-if="isExplorationLockedForEditing()">\n <br>\n Please save your changes first.\n </span>\n </p>\n\n <p ng-if="canDelete" class="oppia-exploration-ctrl">\n <button type="button" ng-if="ExplorationRightsService.isPrivate()"\n class="btn btn-danger" ng-click="deleteExploration()"\n title="Delete this exploration">\n Delete Exploration\n </button>\n </p>\n </div>\n\n <div class="col-lg-6 col-md-6 col-sm-6" ng-if="currentUserIsAdmin || currentUserIsModerator">\n <h3>Admin Controls</h3>\n\n <p ng-if="canUnpublish" class="oppia-exploration-ctrl oppia-exploration-ctrl-admin" ng-show="ExplorationRightsService.isPublic()">\n <button type="button" class="btn btn-default" ng-click="unpublishExplorationAsModerator()" ng-disabled="isExplorationLockedForEditing()">\n Unpublish\n <span ng-if="currentUserIsAdmin">(as admin)</span>\n <span ng-if="!currentUserIsAdmin && currentUserIsModerator">(as moderator)</span>\n </button>\n </p>\n\n <p class="oppia-exploration-ctrl oppia-exploration-ctrl-admin" ng-if="ExplorationRightsService.isPublic() && (currentUserIsAdmin || currentUserIsModerator)">\n <button type="button" class="btn btn-danger protractor-test-delete-exploration-button"\n ng-click="deleteExploration()">\n Delete Exploration\n <span ng-if="currentUserIsAdmin">(as admin)</span>\n <span ng-if="!currentUserIsAdmin && currentUserIsModerator">(as moderator)</span>\n </button>\n </p>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="areParametersEnabled()">\n <h3>Parameters used in this exploration</h3>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div ng-show="isEmpty(explorationParamSpecsService.savedMemento.getParamDict())">\n <em>No parameters used.</em>\n </div>\n <ol>\n <li ng-repeat="(paramName, paramSpec) in explorationParamSpecsService.savedMemento.getParamDict()">\n <b><[paramName]></b> (<[paramSpec.getType().getName()]>)\n </li>\n </ol>\n </div>\n </div>\n\n <h3>\n Initial parameter changes\n <i class="material-icons md-18" uib-tooltip="These changes are applied before the learner begins the exploration."\n tooltip-placement="right" style="padding-left: 4px; vertical-align: text-top;">\n \n </i>\n </h3>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12 protractor-test-exploration-edit-param-changes">\n <param-changes-editor param-changes-service="explorationParamChangesService"\n post-save-hook="postSaveParamChangesHook"\n currently-in-settings-tab="true">\n </param-changes-editor>\n </div>\n </div>\n </md-card>\n</div>\n </div>\n\n <div ng-show="getActiveTabName() === \'history\'">\n <div ng-controller="HistoryTab" class="container-fluid" style="word-wrap: break-word;">\n <md-card class="oppia-editor-card">\n <h3>List of Changes</h3>\n <div ng-repeat="versionNumber in versionNumbersToDisplay" class="row">\n <div class="col-sm-4 col-md-4 col-lg-4">\n <input type="checkbox" name="compareVer" ng-model="versionCheckboxArray[versionNumber].selected" ng-init="init()" ng-click="changeSelectedVersions($event, versionNumber)" ng-disabled="isCheckboxDisabled(versionNumber)" ng-hide="comparisonsAreDisabled" class="protractor-test-history-checkbox-selector">\n [<[versionNumber]>]\n <strong><profile-link-text username="explorationVersionMetadata[versionNumber].committerId"></profile-link-text></strong>\n </div>\n <div class="col-sm-4 col-md-4 col-lg-4">\n <[explorationVersionMetadata[versionNumber].commitMessage]>\n </div>\n <div class="col-sm-4 col-md-4 col-lg-4">\n <span>\n <em><[explorationVersionMetadata[versionNumber].createdOnStr]></em>\n <span ng-if="versionNumber !== currentVersion && EditabilityService.isEditable()">\n | <a href="#" class="protractor-test-revert-version" ng-click="showRevertExplorationModal(versionNumber)">Revert</a>\n </span>\n <span>\n | <a href="#" ng-click="downloadExplorationWithVersion(versionNumber)" title="Download exploration as a zip file.">Download</a>\n </span>\n </span>\n </div>\n </div>\n\n <br>\n\n <div ng-hide="!explorationVersionMetadata || compareVersionsButtonIsHidden">\n <button class="btn protractor-test-show-history-graph" ng-class="{\'btn-success\': areCompareVersionsSelected(), \'btn-default\': !areCompareVersionsSelected()}" ng-click="compareSelectedVersions()" ng-disabled="!areCompareVersionsSelected()">Compare selected revisions</button>\n <div class="version-count-prompt">\n <[versionCountPrompt]>\n </div>\n </div>\n\n <div ng-show="versionCheckboxArray.length > VERSIONS_PER_PAGE" style="margin-top: 30px" uib-pagination boundary-links="true" class="pagination-sm" max-size="5" items-per-page="VERSIONS_PER_PAGE" total-items="versionCheckboxArray.length" ng-model="displayedCurrentPageNumber" ng-change="computeVersionsToDisplay()"></div>\n </md-card>\n\n <md-card class="oppia-editor-card" style="position: relative;"\n ng-if="diffData && !hideHistoryGraph && explorationVersionMetadata">\n <h3>\n Changes from version <[compareVersionMetadata.earlierVersion.versionNumber]>\n to version <[compareVersionMetadata.laterVersion.versionNumber]>\n </h3>\n\n <version-diff-visualization diff-data="diffData"\n earlier-version-header="earlierVersionHeader"\n later-version-header="laterVersionHeader">\n </version-diff-visualization>\n </md-card>\n</div>\n </div>\n\n <div ng-show="getActiveTabName() === \'feedback\'">\n <md-card class="oppia-editor-card oppia-feedback-card" ng-controller="FeedbackTab">\n <div ng-if="!activeThread">\n <div ng-if="threadData.suggestionThreads.length > 0">\n <h2>Suggestions from Learners</h2>\n <thread-table threads="threadData.suggestionThreads"\n on-click-row="setActiveThread">\n </thread-table>\n <br>\n </div>\n\n <div class="pull-right">\n <button ng-if="userIsLoggedIn" class="btn btn-success pull-right" ng-click="showCreateThreadModal()">\n Start new thread\n </button>\n </div>\n\n <h2>Exploration Feedback</h2>\n\n <div style="clear: both;"></div>\n\n <div ng-if="threadData.feedbackThreads.length === 0">\n <em>No feedback has been given for this exploration yet.</em>\n </div>\n\n <thread-table threads="threadData.feedbackThreads"\n on-click-row="setActiveThread">\n </thread-table>\n\n <em ng-if="!userIsLoggedIn">To create a new feedback thread, please log in.</em>\n </div>\n\n <div ng-if="activeThread">\n <div class="row">\n <div class="col-lg-9 col-md-9 col-sm-9">\n <span class="oppia-back-arrow">\n <button type="button" class="btn btn-default btn-xs protractor-test-oppia-feedback-back-button" ng-click="onBackButtonClicked()">\n <i class="material-icons oppia-vcenter" title="Return to list of feedback threads"></i>\n </button>\n </span>\n <span style="font-size: larger" ng-show="!activeThread.isSuggestionThread()">Feedback Thread: <[activeThread.subject]></span>\n <span style="font-size: larger" ng-show="activeThread.isSuggestionThread()">Suggestion Thread: <[activeThread.subject]></span>\n </div>\n\n <div style="float: right;" class="col-lg-5 col-md-5 col-sm-5">\n <div class="pull-right">\n <span ng-if="activeThread.stateName" class="label label-info">\n state: <[activeThread.stateName]>\n </span>\n <span ng-class="getLabelClass(activeThread.status)">\n <[getHumanReadableStatus(activeThread.status)]>\n </span>\n </div>\n </div>\n </div>\n\n <div class="row" ng-if="activeThread.messages">\n <div class="col-lg-12 col-md-12 col-sm-12 activeThreadView">\n <table class="table">\n <tr ng-repeat="m in activeThread.messages|orderBy:\'message_id\'">\n <td>\n <div class="row">\n <div class="col-lg-5 col-md-5 col-sm-5">\n <span ng-if="$index !== 0">#<[m.message_id]></span>\n <span ng-if="m.author_username">by <strong><[m.author_username]></strong></span>\n <span ng-if="!m.author_username">(anonymously submitted)</span>\n </div>\n\n <div class="col-lg-4 col-md-4 col-sm-4">\n <span ng-if="m.message_id !== 0">\n <span ng-if="m.updated_status">\n <em>Status changed to \'<[getHumanReadableStatus(m.updated_status)]>\'</em>\n </span>\n <span ng-if="m.updated_subject">\n <em>Subject changed to \'<[m.updated_subject]>\'</em>\n </span>\n </span>\n </div>\n\n <div class="col-lg-3 col-md-3 col-sm-3">\n <span><[getLocaleAbbreviatedDatetimeString(m.created_on)]></span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div style="white-space: pre-wrap;" class="protractor-test-exploration-feedback"><[m.text]></div>\n <div ng-if="activeThread.isSuggestionThread() && $index == 0">\n <button class="btn btn-<[getSuggestionButtonType()]> protractor-test-view-suggestion-btn" style="margin-top: 6px; margin-bottom: 6px" ng-click="showSuggestionModal()">\n View Suggestion\n </button>\n </div>\n </div>\n </div>\n </td>\n </tr>\n </table>\n </div>\n </div>\n\n\n <hr>\n\n <div class="row" ng-if="userIsLoggedIn">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div>\n <label for="tmpMessageText">\n Add new message\n <span ng-if="EditabilityService.isEditable() && !activeThread.isSuggestionThread()">(and/or change status)</span>\n </label>\n <textarea class="form-control protractor-test-feedback-response-textarea" ng-model="tmpMessage.text"\n id="tmpMessageText" rows="6"\n ng-disabled="messageSendingInProgress">\n </textarea>\n </div>\n\n <div>\n <span ng-show="EditabilityService.isEditable() && !activeThread.isSuggestionThread()">\n Change status (optional):\n <select ng-model="tmpMessage.status"\n ng-options="choice.id as choice.text for choice in STATUS_CHOICES"\n ng-disabled="messageSendingInProgress">\n </select>\n <div style="color:#ff0000; margin-top: 7px;" ng-if="!tmpMessage.text && (tmpMessage.status === \'ignored\' || tmpMessage.status === \'not_actionable\')">\n <i class="material-icons"></i>\n <span>Please specify a reason for setting the status to <[getHumanReadableStatus(tmpMessage.status)]>.</span>\n </div>\n </span>\n </div>\n\n <div>\n <button class="btn btn-success protractor-test-oppia-feedback-response-send-btn" style="margin-top: 10px;"\n ng-click="addNewMessage(activeThread.threadId, tmpMessage.text, tmpMessage.status)"\n ng-disabled="messageSendingInProgress || (!tmpMessage.text && activeThread.status === tmpMessage.status) || (!tmpMessage.text && (tmpMessage.status === \'ignored\' || tmpMessage.status === \'not_actionable\'))">\n <span ng-if="messageSendingInProgress">Sending...</span>\n <span ng-if="!messageSendingInProgress">Send</span>\n </button>\n </div>\n </div>\n </div>\n <em ng-if="!userIsLoggedIn">To respond to a feedback thread, please log in.</em>\n </div>\n</md-card>\n\n\n<style>\n /* Overwrite the default "success" color to a darker shade of green in order\n to prevent this overshadowing the active action buttons (like "Create New\n Thread"). */\n .oppia-feedback-card span.label.label-success {\n background-color: #038603;\n }\n .activeThreadView {\n margin-top: 10px;\n word-wrap: break-word;\n }\n</style>\n </div>\n </div>\n </div>\n\n <!-- These definitions must be included exactly once on the page for the graph SVGs to work in Firefox. -->\n <svg width="0" height="0">\n <defs>\n <marker id="arrowhead" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="grey"></path>\n </marker>\n <marker id="arrowhead-green" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="#1F7D1F"></path>\n </marker>\n <marker id="arrowhead-red" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="#B22222"></path>\n </marker>\n <linearGradient id="nodegradient" x1="0%" x2="100%" y1="0%" y2="0%">\n <stop offset="0%" style="stop-opacity: 1; stop-color: darkseagreen;"></stop>\n <stop offset="100%" style="stop-opacity: 0.1; stop-color: darkseagreen;"></stop>\n </linearGradient>\n </defs>\n </svg>\n\n\n \n \n </div>\n </div>\n </div>\n <div ng-if="!iframed">\n <div role="button" tabindex="0" ng-click="skipToMainContent()" class="oppia-skip-to-content protractor-test-skip-link">Skip to Main Content</div>\n <promo-bar>\n </promo-bar>\n <div ng-if="isBackgroundMaskActive()" class="ng-cloak oppia-background-mask">\n </div>\n\n <div class="oppia-base-container" ng-class="{\'oppia-sidebar-menu-open\': isSidebarShown(), \'oppia-sidebar-menu-closed\': !isSidebarShown()}" ng-swipe-left="closeSidebarOnSwipe()" ng-swipe-disable-mouse="false">\n <div class="oppia-content-container">\n <div id="wrapper">\n <div class="oppia-main-body">\n <nav class="navbar navbar-default oppia-navbar oppia-prevent-selection" role="navigation" headroom tolerance="0" offset="0">\n <div class="navbar-container">\n <top-navigation-bar></top-navigation-bar>\n <div class="collapse navbar-collapse oppia-navbar-collapse ng-cloak">\n \n <editor-navbar-breadcrumb></editor-navbar-breadcrumb>\n\n\n \n <editor-navigation></editor-navigation>\n\n <exploration-save-and-publish-buttons></exploration-save-and-publish-buttons>\n\n </div>\n </div>\n </nav>\n\n <div class="oppia-top-of-page-padding">\n </div>\n\n <div tabindex="0" aria-label="Oppia Main Content" id="oppia-main-content" class="protractor-test-main-content" ng-cloak>\n <div class="oppia-toast-container toast-top-center">\n <div ng-repeat="warning in (AlertsService.warnings | limitTo:5) track by $index" class="toast toast-warning oppia-toast">\n <button type="button" class="toast-close-button" ng-click="AlertsService.deleteWarning(warning)" role="button">×</button>\n <div class="toast-message">\n <[warning.content]>\n </div>\n </div>\n </div>\n\n <div>\n <div ng-repeat="message in AlertsService.messages track by $index">\n <alert-message message-object="message" message-index="$index"></alert-message>\n </div>\n </div>\n\n <div ng-show="loadingMessage" class="oppia-loading-fullpage">\n <div class="oppia-align-center">\n <span translate="<[loadingMessage]>"></span>\n <span class="oppia-loading-dot-one">.</span>\n <span class="oppia-loading-dot-two">.</span>\n <span class="oppia-loading-dot-three">.</span>\n </div>\n </div>\n <div ng-show="!loadingMessage">\n \n <div ng-controller="ExplorationEditor" ng-cloak>\n <div class="container-fluid oppia-editor-page-container" ng-joy-ride="tutorialInProgress" config="EDITOR_TUTORIAL_OPTIONS" on-finish="onFinishTutorial()" on-skip="onSkipTutorial()">\n <div class="row" ng-if="ExplorationRightsService.isCloned()">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div class="oppia-align-center uib-alert alert-warning" style="padding: 2px; width: 90%;">\n <strong>Note:</strong> This is a private, unpublishable copy of a\n <a ng-href="<[getExplorationUrl(ExplorationRightsService.clonedFrom())]>" target="_blank" rel="noopener">public exploration</a>.\n </div>\n </div>\n </div>\n\n <div ng-show="getActiveTabName() === \'main\'">\n <div class="row">\n <div class="col-lg-8 col-md-8 col-sm-8">\n <div ng-controller="ExplorationEditorTab" class="oppia-editor-cards-container">\n <div class="oppia-editor-header">\n <state-name-editor></state-name-editor>\n </div>\n\n <div ng-if="areParametersEnabled()">\n <state-param-changes-editor></state-param-changes-editor>\n </div>\n\n <state-editor on-save-state-content="saveStateContent"\n on-save-interaction-customization-args="saveInteractionCustomizationArgs"\n on-save-interaction-id="saveInteractionId"\n on-save-interaction-default-outcome="saveInteractionDefaultOutcome"\n on-save-interaction-answer-groups="saveInteractionAnswerGroups"\n on-save-solution="saveSolution"\n on-save-hints="saveHints"\n recompute-graph="recomputeGraph"\n show-mark-all-audio-as-needing-update-modal-if-required="showMarkAllAudioAsNeedingUpdateModalIfRequired"\n state-content-placeholder="getStateContentPlaceholder()"\n navigate-to-state="navigateToState"\n add-state="addState"\n refresh-warnings="refreshWarnings"\n interaction-is-shown="interactionIsShown">\n </state-editor>\n</div>\n </div>\n <div class="col-lg-4 col-md-4 col-sm-4">\n <div class="oppia-editor-sidebar hidden-xs hidden-sm">\n <div ng-controller="ExplorationGraph" ng-show="isGraphShown()" class="oppia-state-graph-animate-show">\n <span style="font-size: 16px;">\n <strong>Exploration Overview</strong>\n </span>\n\n <md-card style="background-color: white; margin: 20px 0px; padding: 8px;">\n <div class="oppia-state-graph-container protractor-test-exploration-graph">\n <div state-graph-visualization graph-data="getGraphData()" current-state-id="getActiveStateName()" on-click-function="onClickStateInMinimap" on-delete-function="deleteState" on-maximize-function="openStateGraphModal" allow-panning="true" center-at-current-state="true" style="height: 100%;" is-editable="isEditable()" show-warning-sign="true">\n </div>\n </div>\n </md-card>\n</div>\n <unresolved-answers-overview></unresolved-answers-overview>\n </div>\n </div>\n <attribution-guide></attribution-guide>\n</div>\n </div>\n\n <div ng-if="getActiveTabName() === \'translation\'">\n <translation-tab></translation-tab>\n </div>\n <!-- This is an ng-if, so that the preview loads the latest version of the exploration each time the tab is accessed. -->\n <div ng-if="getActiveTabName() === \'preview\'">\n <div ng-controller="PreviewTab">\n <div ng-if="isExplorationPopulated">\n <div ng-if="previewWarning">\n <div class="oppia-preview-state-warning"><[previewWarning]></div>\n </div>\n <conversation-skin></conversation-skin>\n <exploration-footer twitter-text=""></exploration-footer>\n\n </div>\n\n <div class="oppia-preview-bottom-right-container">\n <div class="oppia-parameter-summary" ng-if="showParameterSummary()">\n <strong>Parameters:</strong>\n <table>\n <tr ng-repeat="(paramName, paramValue) in allParams">\n <td style="padding: 1px 5px;"><[paramName]>:</td>\n <td style="padding: 1px 5px;">\n <[paramValue != "" ? paramValue : "[Not set]"]>\n </td>\n </tr>\n </table>\n </div>\n <button class="btn-lg" ng-click="resetPreview()">\n <i class="material-icons" style="margin-bottom: 2px;"></i>\n <span style="margin-left: 10px; padding-top: 20px;">Restart From Beginning</span>\n </button>\n </div>\n\n</div>\n\n<style>\n .oppia-preview-bottom-right-container {\n /* Fixed at bottom right corner (before footer) and appear on top of other div*/\n bottom: 10px;\n display: block;\n position: fixed;\n right: 0;\n padding-bottom: 2em;\n z-index: 1060;\n }\n\n .oppia-preview-bottom-right-container .oppia-parameter-summary {\n background-color: #fff;\n font-size: 16px;\n margin: 0px 0px 2px 0px;\n padding: 5px 0px 0px 5px;\n text-align: left;\n }\n\n .oppia-preview-bottom-right-container .btn-lg {\n background-color: #fff;\n border: none;\n border-radius: 0px;\n display: block;\n font-size: 20px;\n text-align: right;\n margin-top: 10px;\n padding-top: 10px;\n }\n\n .oppia-preview-state-warning {\n background-color: #fff;\n border: 1px solid #ccc;\n border-radius: 4px;\n display: block;\n font-size: 16px;\n font-weight: bold;\n left: 6px;\n max-width: 296px;\n padding: 3px;\n position: absolute;\n text-align: left;\n top: 63px;\n white-space: normal;\n z-index: 1060;\n }\n</style>\n </div>\n\n <div ng-show="getActiveTabName() === \'stats\'">\n <div ng-controller="StatisticsTab" ng-cloak>\n <md-card class="oppia-editor-card" ng-if="!loadingMessage">\n <div ng-if="explorationHasBeenVisited">\n <div class="oppia-statistics-display">\n <h3>Exploration Completion Rate</h3>\n <pie-chart data="pieChartData"\n options="COMPLETION_RATE_PIE_CHART_OPTIONS">\n </pie-chart>\n <p style="text-align: center;"><span ng-if="numPassersby" style="font-weight: bold;" class="protractor-test-num-passersby"><[numPassersby]></span><span ng-if="!numPassersby" style="font-weight: bold;">0</span> learners browsed this exploration. They left before reaching the second card.</p>\n\n <h3>Card statistics</h3>\n <div style="font-size: smaller" ng-if="lastUpdated">\n <em>Last updated: <[getLocaleAbbreviatedDatetimeString(lastUpdated)]></em>\n </div>\n <div class="container">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div state-graph-visualization graph-data="statsGraphData"\n node-fill="darkseagreen"\n highlight-states="highlightStates"\n state-stats="stateStats"\n on-click-function="onClickStateInStatsGraph">\n </div>\n </div>\n </div>\n <div class="container" ng-if="playthroughsAreAvailable">\n <playthrough-issues></playthrough-issues>\n </div>\n </div>\n </div>\n </div>\n <div ng-if="!explorationHasBeenVisited">\n <em>\n This exploration has not been visited by anyone yet, so there are no statistics to display.\n </em>\n </div>\n </md-card>\n</div>\n </div>\n\n <improvements-tab ng-if="getActiveTabName() === \'improvements\'">\n </improvements-tab>\n\n <div ng-show="getActiveTabName() === \'settings\'">\n <div ng-controller="SettingsTab">\n <md-card class="oppia-editor-card">\n <h3>Basic Settings</h3>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div ng-if="EditabilityService.isEditable()">\n <div role="form" class="form-horizontal">\n <exploration-title-editor label-text="Title"\n focus-label="<[::EXPLORATION_TITLE_INPUT_FOCUS_LABEL]>"\n form-style="<[::formStyle]>"\n on-input-field-blur="saveExplorationTitle()">\n </exploration-title-editor>\n <exploration-objective-editor label-text="Goal"\n form-style="<[::formStyle]>"\n on-input-field-blur="saveExplorationObjective()">\n </exploration-objective-editor>\n\n <div class="form-group" ng-class="{\'has-error\': !explorationCategoryService.displayed}">\n <label for="explorationCategory" class="col-lg-2 col-md-2 col-sm-2">Category</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <div ng-if="hasPageLoaded">\n <select2-dropdown id="explorationCategory"\n class="protractor-test-exploration-category-input"\n item="explorationCategoryService.displayed"\n choices="CATEGORY_LIST_FOR_SELECT2"\n placeholder="Choose or type new"\n new-choice-regex="^[A-Z a-z]+$"\n on-selection-change="saveExplorationCategory()"\n width="100%"\n invalid-search-term-message="Invalid category name">\n </select2-dropdown>\n </div>\n </div>\n </div>\n\n <div class="form-group">\n <label for="explorationLanguageCode" class="col-lg-2 col-md-2 col-sm-2">Language</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <select id="explorationLanguageCode" class="form-control protractor-test-exploration-language-select" ng-model="explorationLanguageCodeService.displayed" ng-change="saveExplorationLanguageCode()" ng-options="lc.code as lc.description for lc in explorationLanguageCodeService.getAllLanguageCodes()">\n </select>\n <span class="help-block" style="font-size: smaller">\n <em>\n Don\'t see the language you want? <a href="https://github.com/oppia/oppia/issues/new?title=Please%20add%20a%20new%20language%20choice%20to%20the%20exploration%20settings%20tab&body=Please%20add%20the%20language%20choice%20%7B%7BYOUR_LANGUAGE_HERE%7D%7D%20to%20the%20exploration%20settings%20tab.%0A%0AHere%20is%20a%20link%20to%20an%20exploration%20that%20uses%20it:%20%7B%7BINSERT_LINK_HERE%7D%7D" target="_blank" rel="noopener">Tell us.</a>\n </em>\n </span>\n </div>\n </div>\n <div class="form-group">\n <label for="explorationInitStateName" class="col-lg-2 col-md-2 col-sm-2">Name of first card</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <select id="explorationInitStateName" class="form-control protractor-test-initial-state-select" ng-model="explorationInitStateNameService.displayed" ng-change="saveExplorationInitStateName()" ng-options="name as name for name in stateNames track by name">\n </select>\n <span class="help-block" style="font-size: smaller">\n <em>This is the first card the learner sees when playing your exploration.</em>\n </span>\n </div>\n </div>\n <div class="form-group">\n <label for="explorationTags" class="col-lg-2 col-md-2 col-sm-2">Tags</label>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <div ng-if="hasPageLoaded">\n <select2-dropdown item="$parent.explorationTagsService.displayed"\n choices="$parent.explorationTagsService.displayed"\n allow-multiple-choices="true"\n invalid-search-term-message="Add a new tag (using lowercase letters and spaces)..."\n new-choice-regex="<[::TAG_REGEX]>"\n width="100%"\n placeholder="Skills, concepts, topics..."\n on-selection-change="saveExplorationTags()">\n </select2-dropdown>\n </div>\n <span class="help-block" style="font-size: smaller">\n <em>Tags help learners discover your exploration when searching.</em>\n </span>\n </div>\n </div>\n <div class="text-right">\n <button type="button" class="btn btn-default protractor-test-open-preview-summary-modal"\n ng-click="previewSummaryTile()"\n title="Preview this exploration\'s summary card">\n Preview Summary\n </button>\n </div>\n </div>\n </div>\n\n <div ng-if="!EditabilityService.isEditable()">\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationTitle">\n Title\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationTitle" type="text">\n <[explorationTitleService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationObjective">\n Goal\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationObjective" type="text">\n <[explorationObjectiveService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationCategory">\n Category\n </label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <span id="explorationCategory" type="text">\n <[explorationCategoryService.displayed]>\n </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationLanguageCode">Language</label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <[explorationLanguageCodeService.getCurrentLanguageDescription()]>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-2 col-md-2 col-sm-2">\n <label for="explorationInitStateName">First State</label>\n </div>\n <div class="col-lg-10 col-md-10 col-sm-10">\n <[explorationInitStateNameService.displayed]>\n </div>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <h3>Advanced Features</h3>\n <div class="row">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableParameters" class="col-lg-10 col-md-10 col-sm-10">\n Parameters\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input span ng-if="areParametersEnabled()" type="checkbox" class="oppia-on-off-switch-checkbox" id="parameter-switch" checked disabled>\n <input span ng-if="!areParametersEnabled()" type="checkbox" class="oppia-on-off-switch-checkbox" id="parameter-switch" ng-click="enableParameters()">\n <label class="oppia-on-off-switch-label protractor-test-enable-parameters" for="parameter-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Parameters are values that change as the learner moves between cards (<a href="http://oppia.github.io/#/Parameters" target="_blank" rel="noopener">more info</a>).\n </span>\n </div>\n </div>\n </div>\n <hr>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableAutomaticTextToSpeech" class="col-lg-10 col-md-10 col-sm-10">\n Automatic Text-to-speech\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input type="checkbox" ng-if="isAutomaticTextToSpeechEnabled()" class="oppia-on-off-switch-checkbox" id="text-speech-switch" ng-click="toggleAutomaticTextToSpeech()" checked>\n <input type="checkbox" ng-if="!isAutomaticTextToSpeechEnabled()" class="oppia-on-off-switch-checkbox" id="text-speech-switch" ng-click="toggleAutomaticTextToSpeech()">\n <label class="oppia-on-off-switch-label" for="text-speech-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Automatic text-to-speech generates audio from your content for learners to listen to. It is recommended that you disable this feature if creating an exploration whose content consists of multiple languages.\n </span>\n </div>\n </div>\n </div>\n <hr>\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="enableCorrectnessFeedback" class="col-lg-10 col-md-10 col-sm-10">\n Correctness Feedback\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <div class="oppia-on-off-switch">\n <input type="checkbox" ng-if="!isCorrectnessFeedbackEnabled()" class="oppia-on-off-switch-checkbox" id="correctness-switch" ng-click="toggleCorrectnessFeedback()">\n <input type="checkbox" ng-if="isCorrectnessFeedbackEnabled()" class="oppia-on-off-switch-checkbox" id="correctness-switch" ng-click="toggleCorrectnessFeedback()" checked>\n <label class="oppia-on-off-switch-label" for="correctness-switch">\n <span class="oppia-on-off-switch-inner"></span>\n <span class="oppia-on-off-switch-main"></span>\n </label>\n </div>\n </span>\n <span class="col-lg-12 col-md-12 col-sm-12 help-block" style="font-size: smaller;">\n Correctness feedback allows the user to categorise answer groups as correct or incorrect.\n </span>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card">\n <div ng-if="ExplorationRightsService.ownerNames.length > 0 && !ExplorationRightsService.isCloned()">\n <div class="row">\n <div class="col-lg-5 col-md-5 col-sm-5">\n <h3>Roles</h3>\n <div ng-show="ExplorationRightsService.ownerNames.length > 0">\n <strong>Managers</strong>\n <ul>\n <li ng-repeat="ownerName in ExplorationRightsService.ownerNames track by $index">\n <[ownerName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.editorNames.length > 0">\n <strong>Collaborators</strong>\n <ul>\n <li ng-repeat="editorName in ExplorationRightsService.editorNames track by $index">\n <[editorName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.voiceArtistNames.length > 0">\n <strong>Voice Artists</strong>\n <ul>\n <li ng-repeat="voiceArtistName in ExplorationRightsService.voiceArtistNames track by $index">\n <[voiceArtistName]>\n </li>\n </ul>\n </div>\n\n <div ng-show="ExplorationRightsService.viewerNames.length > 0">\n <strong>Playtesters</strong>\n <ul>\n <li ng-repeat="viewerName in ExplorationRightsService.viewerNames track by $index">\n <[viewerName]>\n </li>\n </ul>\n </div>\n\n\n <div ng-if="canModifyRoles" ng-hide="isRolesFormOpen">\n <button type="button" class="btn btn-default protractor-test-edit-roles" ng-click="openEditRolesForm()">\n Edit Roles\n </button>\n </div>\n\n <div ng-if="canModifyRoles" ng-show="isRolesFormOpen">\n <strong>Add or Change Role</strong>\n <div class="form-group">\n <form ng-submit="editRole(newMemberUsername, newMemberRole.value)">\n <label for="newMemberUsername">Username of invited user</label>\n <div>\n <input type="text" id="newMemberUsername" class="form-control protractor-test-role-username" ng-model="newMemberUsername" placeholder="editor">\n </div>\n <br>\n <label for="newMemberRole">Role of invited user</label>\n <div>\n <select ng-model="newMemberRole" class="form-control protractor-test-role-select" ng-options="r.name for r in ROLES" style="width: 250px;">\n </select>\n <span class="help-block">\n Note that managers also have the permissions of collaborators, collaborators also have the permissions of voice artists, and voice artists also have the permissions of viewers. Please note that assigning roles is irreversible (though you can always assign somebody to a higher role).\n </span>\n </div>\n\n <input type="submit" class="btn btn-default protractor-test-save-role" value="Save" ng-disabled="!isTitlePresent()">\n <button type="button" class="btn btn-default" ng-click="closeEditRolesForm()" ng-show="isRolesFormOpen">\n Cancel\n </button>\n <p ng-show="!isTitlePresent()" class="text-danger protractor-test-title-warning">Please provide a title before inviting.</p>\n </form>\n </div>\n </div>\n </div>\n\n <div class="col-lg-7 col-md-7 col-sm-7">\n <h3>Permissions</h3>\n <p ng-if="ExplorationRightsService.isPrivate() && ExplorationRightsService.viewableIfPrivate()">\n This exploration is <strong>private</strong>. Anyone with the link can access it.\n </p>\n <p ng-if="ExplorationRightsService.isPrivate() && !ExplorationRightsService.viewableIfPrivate()">\n This exploration is <strong>private</strong>. Only invited users, moderators and site admins can\n access it.\n </p>\n <p ng-if="!ExplorationRightsService.isPrivate()">\n This exploration is <strong>public</strong>: anyone can access it.\n </p>\n\n <p ng-if="!ExplorationRightsService.isPrivate() || ExplorationRightsService.viewableIfPrivate()">\n <em>Link to share:</em>\n <input class="form-control" type="text" value="<[getExplorePageUrl(explorationId)]>" readonly="readonly" onClick="this.select();">\n </p>\n\n <br>\n\n <p ng-if="ExplorationRightsService.isPrivate()">\n It is <strong>not shown</strong> in the Oppia library.\n </p>\n <p ng-if="!ExplorationRightsService.isPrivate()">\n It is <strong>available</strong> in the Oppia library.\n </p>\n </div>\n </div>\n </div>\n\n <div ng-if="ExplorationRightsService.ownerNames.length === 0 && !ExplorationRightsService.isCloned()">\n <h3>Permissions</h3>\n <div>\n This exploration is <strong>public</strong> and <strong>community-editable</strong>.\n <p ng-if="!ExplorationRightsService.isPrivate()">\n It is <strong>available</strong> in the Oppia library.\n </p>\n </div>\n </div>\n\n <div ng-if="ExplorationRightsService.isCloned()">\n <h3>Status</h3>\n <div>\n This exploration was <strong>cloned</strong> from another exploration.\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <h3>Feedback/Suggestion Email Preferences</h3>\n <div class="row">\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="FeedbackNotifications" class="col-lg-3 col-md-3 col-sm-3">\n Feedback emails\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="muteFeedbackNotifications()" ng-if="!UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n Mute\n </button>\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="unmuteFeedbackNotifications()" ng-if="UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n Unmute\n </button>\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="!UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n You are currently receiving notifications of new feedback for this exploration.\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="UserEmailPreferencesService.areFeedbackNotificationsMuted()">\n You have muted feedback notifications for this exploration. You will not receive an email when new feedback is submitted.\n </span>\n </div>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div role="form" class="form-horizontal">\n <label for="SuggestionNotifications" class="col-lg-3 col-md-3 col-sm-3">\n Suggestion emails\n </label>\n <span class="col-lg-2 col-md-2 col-sm-2">\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="muteSuggestionNotifications()" ng-if="!UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n Mute\n </button>\n <button type="button" class="btn btn-default protractor-test-enable-fallbacks"\n ng-click="unmuteSuggestionNotifications()" ng-if="UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n Unmute\n </button>\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="!UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n You are currently receiving notifications of new suggestions for this exploration.\n </span>\n <span class="col-lg-7 col-md-7 col-sm-7 help-block" style="font-size: smaller;"\n ng-if="UserEmailPreferencesService.areSuggestionNotificationsMuted()">\n You have muted suggestion notifications for this exploration. You will not receive an email when new suggestion is submitted.\n </span>\n </div>\n </div>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="EditabilityService.isEditable()">\n <div class="row">\n <div class="col-lg-6 col-md-6 col-sm-6">\n <h3>Controls</h3>\n\n <p ng-if="canReleaseOwnership" class="oppia-exploration-ctrl" ng-hide="ExplorationRightsService.isCommunityOwned()">\n <button type="button" class="btn btn-default" ng-click="showTransferExplorationOwnershipModal()" ng-disabled="isExplorationLockedForEditing()">\n Transfer ownership to the community\n </button>\n <span ng-if="isExplorationLockedForEditing()">\n <br>\n Please save your changes first.\n </span>\n </p>\n\n <p ng-if="canDelete" class="oppia-exploration-ctrl">\n <button type="button" ng-if="ExplorationRightsService.isPrivate()"\n class="btn btn-danger" ng-click="deleteExploration()"\n title="Delete this exploration">\n Delete Exploration\n </button>\n </p>\n </div>\n\n <div class="col-lg-6 col-md-6 col-sm-6" ng-if="currentUserIsAdmin || currentUserIsModerator">\n <h3>Admin Controls</h3>\n\n <p ng-if="canUnpublish" class="oppia-exploration-ctrl oppia-exploration-ctrl-admin" ng-show="ExplorationRightsService.isPublic()">\n <button type="button" class="btn btn-default" ng-click="unpublishExplorationAsModerator()" ng-disabled="isExplorationLockedForEditing()">\n Unpublish\n <span ng-if="currentUserIsAdmin">(as admin)</span>\n <span ng-if="!currentUserIsAdmin && currentUserIsModerator">(as moderator)</span>\n </button>\n </p>\n\n <p class="oppia-exploration-ctrl oppia-exploration-ctrl-admin" ng-if="ExplorationRightsService.isPublic() && (currentUserIsAdmin || currentUserIsModerator)">\n <button type="button" class="btn btn-danger protractor-test-delete-exploration-button"\n ng-click="deleteExploration()">\n Delete Exploration\n <span ng-if="currentUserIsAdmin">(as admin)</span>\n <span ng-if="!currentUserIsAdmin && currentUserIsModerator">(as moderator)</span>\n </button>\n </p>\n </div>\n </div>\n </md-card>\n\n <md-card class="oppia-editor-card" ng-if="areParametersEnabled()">\n <h3>Parameters used in this exploration</h3>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div ng-show="isEmpty(explorationParamSpecsService.savedMemento.getParamDict())">\n <em>No parameters used.</em>\n </div>\n <ol>\n <li ng-repeat="(paramName, paramSpec) in explorationParamSpecsService.savedMemento.getParamDict()">\n <b><[paramName]></b> (<[paramSpec.getType().getName()]>)\n </li>\n </ol>\n </div>\n </div>\n\n <h3>\n Initial parameter changes\n <i class="material-icons md-18" uib-tooltip="These changes are applied before the learner begins the exploration."\n tooltip-placement="right" style="padding-left: 4px; vertical-align: text-top;">\n \n </i>\n </h3>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12 protractor-test-exploration-edit-param-changes">\n <param-changes-editor param-changes-service="explorationParamChangesService"\n post-save-hook="postSaveParamChangesHook"\n currently-in-settings-tab="true">\n </param-changes-editor>\n </div>\n </div>\n </md-card>\n</div>\n </div>\n\n <div ng-show="getActiveTabName() === \'history\'">\n <div ng-controller="HistoryTab" class="container-fluid" style="word-wrap: break-word;">\n <md-card class="oppia-editor-card">\n <h3>List of Changes</h3>\n <div ng-repeat="versionNumber in versionNumbersToDisplay" class="row">\n <div class="col-sm-4 col-md-4 col-lg-4">\n <input type="checkbox" name="compareVer" ng-model="versionCheckboxArray[versionNumber].selected" ng-init="init()" ng-click="changeSelectedVersions($event, versionNumber)" ng-disabled="isCheckboxDisabled(versionNumber)" ng-hide="comparisonsAreDisabled" class="protractor-test-history-checkbox-selector">\n [<[versionNumber]>]\n <strong><profile-link-text username="explorationVersionMetadata[versionNumber].committerId"></profile-link-text></strong>\n </div>\n <div class="col-sm-4 col-md-4 col-lg-4">\n <[explorationVersionMetadata[versionNumber].commitMessage]>\n </div>\n <div class="col-sm-4 col-md-4 col-lg-4">\n <span>\n <em><[explorationVersionMetadata[versionNumber].createdOnStr]></em>\n <span ng-if="versionNumber !== currentVersion && EditabilityService.isEditable()">\n | <a href="#" class="protractor-test-revert-version" ng-click="showRevertExplorationModal(versionNumber)">Revert</a>\n </span>\n <span>\n | <a href="#" ng-click="downloadExplorationWithVersion(versionNumber)" title="Download exploration as a zip file.">Download</a>\n </span>\n </span>\n </div>\n </div>\n\n <br>\n\n <div ng-hide="!explorationVersionMetadata || compareVersionsButtonIsHidden">\n <button class="btn protractor-test-show-history-graph" ng-class="{\'btn-success\': areCompareVersionsSelected(), \'btn-default\': !areCompareVersionsSelected()}" ng-click="compareSelectedVersions()" ng-disabled="!areCompareVersionsSelected()">Compare selected revisions</button>\n <div class="version-count-prompt">\n <[versionCountPrompt]>\n </div>\n </div>\n\n <div ng-show="versionCheckboxArray.length > VERSIONS_PER_PAGE" style="margin-top: 30px" uib-pagination boundary-links="true" class="pagination-sm" max-size="5" items-per-page="VERSIONS_PER_PAGE" total-items="versionCheckboxArray.length" ng-model="displayedCurrentPageNumber" ng-change="computeVersionsToDisplay()"></div>\n </md-card>\n\n <md-card class="oppia-editor-card" style="position: relative;"\n ng-if="diffData && !hideHistoryGraph && explorationVersionMetadata">\n <h3>\n Changes from version <[compareVersionMetadata.earlierVersion.versionNumber]>\n to version <[compareVersionMetadata.laterVersion.versionNumber]>\n </h3>\n\n <version-diff-visualization diff-data="diffData"\n earlier-version-header="earlierVersionHeader"\n later-version-header="laterVersionHeader">\n </version-diff-visualization>\n </md-card>\n</div>\n </div>\n\n <div ng-show="getActiveTabName() === \'feedback\'">\n <md-card class="oppia-editor-card oppia-feedback-card" ng-controller="FeedbackTab">\n <div ng-if="!activeThread">\n <div ng-if="threadData.suggestionThreads.length > 0">\n <h2>Suggestions from Learners</h2>\n <thread-table threads="threadData.suggestionThreads"\n on-click-row="setActiveThread">\n </thread-table>\n <br>\n </div>\n\n <div class="pull-right">\n <button ng-if="userIsLoggedIn" class="btn btn-success pull-right" ng-click="showCreateThreadModal()">\n Start new thread\n </button>\n </div>\n\n <h2>Exploration Feedback</h2>\n\n <div style="clear: both;"></div>\n\n <div ng-if="threadData.feedbackThreads.length === 0">\n <em>No feedback has been given for this exploration yet.</em>\n </div>\n\n <thread-table threads="threadData.feedbackThreads"\n on-click-row="setActiveThread">\n </thread-table>\n\n <em ng-if="!userIsLoggedIn">To create a new feedback thread, please log in.</em>\n </div>\n\n <div ng-if="activeThread">\n <div class="row">\n <div class="col-lg-9 col-md-9 col-sm-9">\n <span class="oppia-back-arrow">\n <button type="button" class="btn btn-default btn-xs protractor-test-oppia-feedback-back-button" ng-click="onBackButtonClicked()">\n <i class="material-icons oppia-vcenter" title="Return to list of feedback threads"></i>\n </button>\n </span>\n <span style="font-size: larger" ng-show="!activeThread.isSuggestionThread()">Feedback Thread: <[activeThread.subject]></span>\n <span style="font-size: larger" ng-show="activeThread.isSuggestionThread()">Suggestion Thread: <[activeThread.subject]></span>\n </div>\n\n <div style="float: right;" class="col-lg-5 col-md-5 col-sm-5">\n <div class="pull-right">\n <span ng-if="activeThread.stateName" class="label label-info">\n state: <[activeThread.stateName]>\n </span>\n <span ng-class="getLabelClass(activeThread.status)">\n <[getHumanReadableStatus(activeThread.status)]>\n </span>\n </div>\n </div>\n </div>\n\n <div class="row" ng-if="activeThread.messages">\n <div class="col-lg-12 col-md-12 col-sm-12 activeThreadView">\n <table class="table">\n <tr ng-repeat="m in activeThread.messages|orderBy:\'message_id\'">\n <td>\n <div class="row">\n <div class="col-lg-5 col-md-5 col-sm-5">\n <span ng-if="$index !== 0">#<[m.message_id]></span>\n <span ng-if="m.author_username">by <strong><[m.author_username]></strong></span>\n <span ng-if="!m.author_username">(anonymously submitted)</span>\n </div>\n\n <div class="col-lg-4 col-md-4 col-sm-4">\n <span ng-if="m.message_id !== 0">\n <span ng-if="m.updated_status">\n <em>Status changed to \'<[getHumanReadableStatus(m.updated_status)]>\'</em>\n </span>\n <span ng-if="m.updated_subject">\n <em>Subject changed to \'<[m.updated_subject]>\'</em>\n </span>\n </span>\n </div>\n\n <div class="col-lg-3 col-md-3 col-sm-3">\n <span><[getLocaleAbbreviatedDatetimeString(m.created_on)]></span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div style="white-space: pre-wrap;" class="protractor-test-exploration-feedback"><[m.text]></div>\n <div ng-if="activeThread.isSuggestionThread() && $index == 0">\n <button class="btn btn-<[getSuggestionButtonType()]> protractor-test-view-suggestion-btn" style="margin-top: 6px; margin-bottom: 6px" ng-click="showSuggestionModal()">\n View Suggestion\n </button>\n </div>\n </div>\n </div>\n </td>\n </tr>\n </table>\n </div>\n </div>\n\n\n <hr>\n\n <div class="row" ng-if="userIsLoggedIn">\n <div class="col-lg-12 col-md-12 col-sm-12">\n <div>\n <label for="tmpMessageText">\n Add new message\n <span ng-if="EditabilityService.isEditable() && !activeThread.isSuggestionThread()">(and/or change status)</span>\n </label>\n <textarea class="form-control protractor-test-feedback-response-textarea" ng-model="tmpMessage.text"\n id="tmpMessageText" rows="6"\n ng-disabled="messageSendingInProgress">\n </textarea>\n </div>\n\n <div>\n <span ng-show="EditabilityService.isEditable() && !activeThread.isSuggestionThread()">\n Change status (optional):\n <select ng-model="tmpMessage.status"\n ng-options="choice.id as choice.text for choice in STATUS_CHOICES"\n ng-disabled="messageSendingInProgress">\n </select>\n <div style="color:#ff0000; margin-top: 7px;" ng-if="!tmpMessage.text && (tmpMessage.status === \'ignored\' || tmpMessage.status === \'not_actionable\')">\n <i class="material-icons"></i>\n <span>Please specify a reason for setting the status to <[getHumanReadableStatus(tmpMessage.status)]>.</span>\n </div>\n </span>\n </div>\n\n <div>\n <button class="btn btn-success protractor-test-oppia-feedback-response-send-btn" style="margin-top: 10px;"\n ng-click="addNewMessage(activeThread.threadId, tmpMessage.text, tmpMessage.status)"\n ng-disabled="messageSendingInProgress || (!tmpMessage.text && activeThread.status === tmpMessage.status) || (!tmpMessage.text && (tmpMessage.status === \'ignored\' || tmpMessage.status === \'not_actionable\'))">\n <span ng-if="messageSendingInProgress">Sending...</span>\n <span ng-if="!messageSendingInProgress">Send</span>\n </button>\n </div>\n </div>\n </div>\n <em ng-if="!userIsLoggedIn">To respond to a feedback thread, please log in.</em>\n </div>\n</md-card>\n\n\n<style>\n /* Overwrite the default "success" color to a darker shade of green in order\n to prevent this overshadowing the active action buttons (like "Create New\n Thread"). */\n .oppia-feedback-card span.label.label-success {\n background-color: #038603;\n }\n .activeThreadView {\n margin-top: 10px;\n word-wrap: break-word;\n }\n</style>\n </div>\n </div>\n </div>\n\n <!-- These definitions must be included exactly once on the page for the graph SVGs to work in Firefox. -->\n <svg width="0" height="0">\n <defs>\n <marker id="arrowhead" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="grey"></path>\n </marker>\n <marker id="arrowhead-green" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="#1F7D1F"></path>\n </marker>\n <marker id="arrowhead-red" viewBox="0 0 18 18" refX="10" refY="3" markerWidth="10" markerHeight="6" orient="auto">\n <path d="M 0 0 L 10 4 L 0 8 z" fill="#B22222"></path>\n </marker>\n <linearGradient id="nodegradient" x1="0%" x2="100%" y1="0%" y2="0%">\n <stop offset="0%" style="stop-opacity: 1; stop-color: darkseagreen;"></stop>\n <stop offset="100%" style="stop-opacity: 0.1; stop-color: darkseagreen;"></stop>\n </linearGradient>\n </defs>\n </svg>\n\n\n \n \n </div>\n </div>\n </div>\n\n <noscript>\n <div class="oppia-page-cards-container">\n <div class="md-default-theme oppia-page-card oppia-long-text">\n <!-- Note to developers: We replicate the translated text inline because, without JavaScript enabled, the translation engine doesn\'t kick in.-->\n <h2>\n <span translate="I18N_SPLASH_JAVASCRIPT_ERROR_TITLE">We Need JavaScript in Your Browser</span>\n <i class="material-icons"></i>\n </h2>\n <p translate="I18N_SPLASH_JAVASCRIPT_ERROR_DESCRIPTION" translate-values="{hrefUrl: \'http://www.enable-javascript.com/\'}">\n Oppia is a free, open-source learning platform full of interactive activities called \'explorations\'. Sadly, Oppia requires JavaScript to be enabled in your web browser in order to function properly and your web browser has JavaScript disabled. If you need help enabling JavaScript, <a href="http://www.enable-javascript.com">click here.</a>\n </p>\n <p translate="I18N_SPLASH_JAVASCRIPT_ERROR_THANKS">Thank you.</p>\n </div>\n </div>\n </noscript>\n\n <side-navigation-bar></side-navigation-bar>\n </div>\n </div>\n </div>\n\n <div ng-if="DEV_MODE" class="oppia-dev-mode" ng-cloak>\n Dev Mode\n </div>\n\n <a ng-if="siteFeedbackFormUrl" ng-href="<[siteFeedbackFormUrl]>" target="_blank" rel="noopener" class="oppia-site-feedback oppia-transition-200">\n <i class="material-icons md-18"></i>\n <span translate="I18N_SPLASH_SITE_FEEDBACK"></span>\n </a>\n </div>\n\n \n <script src="/third_party/generated/js/third_party.js"></script>\n\n <script src="/templates/dev/head/AppInit.js"></script>\n <!-- This code is used for inserting webpack bundles\n https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates -->\n \n \n <script src="/build/templates/head/dist/about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/app~library.3bd713e5f19772d7b250.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/app.3a832a81c9290cfe0045.bundle.js"></script>\n \n \n\n \n \n \n <script src="/third_party/static/ckeditor-4.9.2/ckeditor.js"></script>\n <script src="/third_party/static/d3js-3.4.11/d3.min.js"></script>\n <script src="/templates/dev/head/mathjaxConfig.js"></script>\n <script src="/third_party/static/MathJax-2.6.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>\n <script>\n // Copyright 2014 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for copier value generator.\n */\n// TODO(sll): Remove this directive (as well as the whole of the value\n// generators framework).\noppia.directive(\'copier\', [\'$compile\', function ($compile) {\n return {\n link: function (scope, element) {\n scope.getTemplateUrl = function () {\n return \'/value_generator_handler/\' + scope.generatorId;\n };\n $compile(element.contents())(scope);\n },\n restrict: \'E\',\n scope: {\n customizationArgs: \'=\',\n getGeneratorId: \'&\',\n getInitArgs: \'&\',\n getObjType: \'&\',\n },\n template: \'<span ng-include="getTemplateUrl()"></span>\',\n controller: function ($scope) {\n $scope.generatorId = $scope.getGeneratorId();\n $scope.initArgs = $scope.getInitArgs();\n $scope.objType = $scope.getObjType();\n $scope.$watch(\'initArgs\', function () {\n $scope.initArgs = $scope.getInitArgs();\n }, true);\n $scope.$watch(\'objType\', function () {\n $scope.objType = $scope.getObjType();\n }, true);\n }\n };\n }]);\n// Copyright 2014 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for random selector value generator.\n */\noppia.directive(\'randomSelector\', [\'$compile\', function ($compile) {\n return {\n link: function (scope, element) {\n scope.getTemplateUrl = function () {\n return \'/value_generator_handler/\' + scope.generatorId;\n };\n $compile(element.contents())(scope);\n },\n restrict: \'E\',\n scope: {\n customizationArgs: \'=\',\n getGeneratorId: \'&\'\n },\n template: \'<div ng-include="getTemplateUrl()"></div>\',\n controller: function ($scope) {\n $scope.SCHEMA = {\n type: \'list\',\n items: {\n type: \'unicode\'\n },\n ui_config: {\n add_element_text: \'Add New Choice\'\n }\n };\n $scope.generatorId = $scope.getGeneratorId();\n if (!$scope.customizationArgs.list_of_values) {\n $scope.customizationArgs.list_of_values = [];\n }\n }\n };\n }]);\n\n </script>\n\n <script src="/extensions/objects/templates/BooleanEditorDirective.js"></script>\n <script src="/extensions/objects/templates/CodeStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/CoordTwoDimEditorDirective.js"></script>\n <script src="/extensions/objects/templates/DragAndDropHtmlStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/DragAndDropPositiveIntEditorDirective.js"></script>\n <script src="/extensions/objects/templates/FilepathEditorDirective.js"></script>\n <script src="/extensions/objects/templates/FractionEditorDirective.js"></script>\n <script src="/extensions/objects/templates/GraphEditorDirective.js"></script>\n <script src="/extensions/objects/templates/GraphPropertyEditorDirective.js"></script>\n <script src="/extensions/objects/templates/HtmlEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ImageWithRegionsEditorDirective.js"></script>\n <script src="/extensions/objects/templates/IntEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ListOfSetsOfHtmlStringsEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ListOfTabsEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ListOfUnicodeStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/LogicErrorCategoryEditorDirective.js"></script>\n <script src="/extensions/objects/templates/LogicQuestionEditorDirective.js"></script>\n <script src="/extensions/objects/templates/MathLatexStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/MusicPhraseEditorDirective.js"></script>\n <script src="/extensions/objects/templates/NonnegativeIntEditorDirective.js"></script>\n <script src="/extensions/objects/templates/NormalizedStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/NumberWithUnitsEditorDirective.js"></script>\n <script src="/extensions/objects/templates/ParameterNameEditorDirective.js"></script>\n <script src="/extensions/objects/templates/RealEditorDirective.js"></script>\n <script src="/extensions/objects/templates/SanitizedUrlEditorDirective.js"></script>\n <script src="/extensions/objects/templates/SetOfHtmlStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/SetOfUnicodeStringEditorDirective.js"></script>\n <script src="/extensions/objects/templates/UnicodeStringEditorDirective.js"></script>\n\n <script src="/extensions/interactions/baseInteractionValidationService.js"></script>\n\n <!-- This code is used for inserting webpack bundles\n https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates -->\n \n \n <script src="/build/templates/head/dist/about~admin~app~collection_editor~collection_player~contact~creator_dashboard~donate~email_dashboard~c1e50cc0.577e9d4b52edf0a81471.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/admin~creator_dashboard~exploration_editor~exploration_player~moderator~practice_session~skill_edito~2604f963.344ff131911e19f3b08a.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/app~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill~30a14829.a1fdc78f21681cfee170.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/collection_editor~creator_dashboard~exploration_editor~exploration_player~library~practice_session~p~0a5a1736.74f4f43c8018a6328d35.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/admin~collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~ski~e373245a.41bd0bd54c1db7e16330.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/collection_player~creator_dashboard~exploration_editor~exploration_player~learner_dashboard~library~~88219965.516b3a1af3556eaa1947.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/collection_editor~creator_dashboard~exploration_editor~exploration_player~practice_session~skill_edi~d050381b.607458ea41489493809e.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/creator_dashboard~exploration_editor~exploration_player~practice_session~skill_editor~story_editor~t~74590fc1.45e7960f1c98a4190401.bundle.js"></script>\n \n \n \n <script src="/build/templates/head/dist/exploration_editor.07de01208fc08d5292d7.bundle.js"></script>\n \n \n <script src="/extensions/rich_text_components/Collapsible/directives/OppiaNoninteractiveCollapsibleDirective.js"></script>\n<script src="/extensions/rich_text_components/Image/directives/OppiaNoninteractiveImageDirective.js"></script>\n<script src="/extensions/rich_text_components/Link/directives/OppiaNoninteractiveLinkDirective.js"></script>\n<script src="/extensions/rich_text_components/Math/directives/OppiaNoninteractiveMathDirective.js"></script>\n<script src="/extensions/rich_text_components/Tabs/directives/OppiaNoninteractiveTabsDirective.js"></script>\n<script src="/extensions/rich_text_components/Video/directives/OppiaNoninteractiveVideoDirective.js"></script>\n <script src="/extensions/interactions/Continue/directives/OppiaInteractiveContinueDirective.js"></script>\n<script src="/extensions/interactions/Continue/directives/OppiaResponseContinueDirective.js"></script>\n<script src="/extensions/interactions/Continue/directives/OppiaShortResponseContinueDirective.js"></script>\n<script src="/extensions/interactions/Continue/directives/ContinueRulesService.js"></script>\n<script src="/extensions/interactions/Continue/directives/ContinueValidationService.js"></script>\n \n<script src="/extensions/interactions/EndExploration/directives/OppiaInteractiveEndExplorationDirective.js"></script>\n<script src="/extensions/interactions/EndExploration/directives/OppiaResponseEndExplorationDirective.js"></script>\n<script src="/extensions/interactions/EndExploration/directives/OppiaShortResponseEndExplorationDirective.js"></script>\n<script src="/extensions/interactions/EndExploration/directives/EndExplorationRulesService.js"></script>\n<script src="/extensions/interactions/EndExploration/directives/EndExplorationValidationService.js"></script>\n \n<script src="/extensions/interactions/ImageClickInput/directives/ImageClickInputRulesService.js"></script>\n<script src="/extensions/interactions/ImageClickInput/directives/ImageClickInputValidationService.js"></script>\n<script src="/extensions/interactions/ImageClickInput/directives/OppiaInteractiveImageClickInputDirective.js"></script>\n<script src="/extensions/interactions/ImageClickInput/directives/OppiaResponseImageClickInputDirective.js"></script>\n<script src="/extensions/interactions/ImageClickInput/directives/OppiaShortResponseImageClickInputDirective.js"></script>\n \n<link rel="stylesheet" type="text/css" href="/extensions/interactions/ItemSelectionInput/static/item_selection_input.css">\n\n<script src="/extensions/interactions/ItemSelectionInput/directives/ItemSelectionInputRulesService.js"></script>\n<script src="/extensions/interactions/ItemSelectionInput/directives/ItemSelectionInputValidationService.js"></script>\n<script src="/extensions/interactions/ItemSelectionInput/directives/OppiaInteractiveItemSelectionInputDirective.js"></script>\n<script src="/extensions/interactions/ItemSelectionInput/directives/OppiaResponseItemSelectionInputDirective.js"></script>\n<script src="/extensions/interactions/ItemSelectionInput/directives/OppiaShortResponseItemSelectionInputDirective.js"></script>\n \n<link rel="stylesheet" type="text/css" href="/extensions/interactions/MultipleChoiceInput/static/multiple_choice_input.css">\n\n<script src="/templates/dev/head/filters/ConvertToPlainTextFilter.js"></script>\n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/OppiaInteractiveMultipleChoiceInputDirective.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/OppiaResponseMultipleChoiceInputDirective.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/OppiaShortResponseMultipleChoiceInputDirective.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/MultipleChoiceInputRulesService.js"></script>\n<script src="/extensions/interactions/MultipleChoiceInput/directives/MultipleChoiceInputValidationService.js"></script>\n \n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/TextInput/directives/OppiaInteractiveTextInputDirective.js"></script>\n<script src="/extensions/interactions/TextInput/directives/OppiaResponseTextInputDirective.js"></script>\n<script src="/extensions/interactions/TextInput/directives/OppiaShortResponseTextInputDirective.js"></script>\n<script src="/extensions/interactions/TextInput/directives/TextInputRulesService.js"></script>\n<script src="/extensions/interactions/TextInput/directives/TextInputValidationService.js"></script>\n \n<script src="/extensions/interactions/DragAndDropSortInput/directives/DragAndDropSortInputRulesService.js"></script>\n<script src="/extensions/interactions/DragAndDropSortInput/directives/DragAndDropSortInputValidationService.js"></script>\n<script src="/extensions/interactions/DragAndDropSortInput/directives/OppiaInteractiveDragAndDropSortInputDirective.js"></script>\n<script src="/extensions/interactions/DragAndDropSortInput/directives/OppiaResponseDragAndDropSortInputDirective.js"></script>\n<script src="/extensions/interactions/DragAndDropSortInput/directives/OppiaShortResponseDragAndDropSortInputDirective.js"></script>\n \n<script src="/extensions/interactions/FractionInput/directives/OppiaInteractiveFractionInputDirective.js"></script>\n<script src="/extensions/interactions/FractionInput/directives/OppiaResponseFractionInputDirective.js"></script>\n<script src="/extensions/interactions/FractionInput/directives/OppiaShortResponseFractionInputDirective.js"></script>\n<script src="/extensions/interactions/FractionInput/directives/FractionInputRulesService.js"></script>\n<script src="/extensions/interactions/FractionInput/directives/FractionInputValidationService.js"></script>\n \n<script src="/extensions/interactions/GraphInput/directives/OppiaInteractiveGraphInputDirective.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/OppiaResponseGraphInputDirective.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/OppiaShortResponseGraphInputDirective.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphVizDirective.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphInputRulesService.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphDetailService.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphUtilsService.js"></script>\n<script src="/extensions/interactions/GraphInput/directives/GraphInputValidationService.js"></script>\n \n<link rel="stylesheet" href="/extensions/interactions/LogicProof/static/logic_proof.css">\n\n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/OppiaInteractiveLogicProofDirective.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/OppiaResponseLogicProofDirective.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/OppiaShortResponseLogicProofDirective.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/LogicProofRulesService.js"></script>\n<script src="/extensions/interactions/LogicProof/directives/LogicProofValidationService.js"></script>\n \n<script src="/extensions/interactions/NumericInput/directives/OppiaInteractiveNumericInputDirective.js"></script>\n<script src="/extensions/interactions/NumericInput/directives/OppiaResponseNumericInputDirective.js"></script>\n<script src="/extensions/interactions/NumericInput/directives/OppiaShortResponseNumericInputDirective.js"></script>\n<script src="/extensions/interactions/NumericInput/directives/NumericInputRulesService.js"></script>\n<script src="/extensions/interactions/NumericInput/directives/NumericInputValidationService.js"></script>\n \n<script src="/extensions/interactions/SetInput/directives/OppiaInteractiveSetInputDirective.js"></script>\n<script src="/extensions/interactions/SetInput/directives/OppiaShortResponseSetInputDirective.js"></script>\n<script src="/extensions/interactions/SetInput/directives/OppiaResponseSetInputDirective.js"></script>\n<script src="/extensions/interactions/SetInput/directives/SetInputRulesService.js"></script>\n<script src="/extensions/interactions/SetInput/directives/SetInputValidationService.js"></script>\n \n<script src="/extensions/interactions/MathExpressionInput/directives/OppiaInteractiveMathExpressionInputDirective.js"></script>\n<script src="/extensions/interactions/MathExpressionInput/directives/OppiaResponseMathExpressionInputDirective.js"></script>\n<script src="/extensions/interactions/MathExpressionInput/directives/OppiaShortResponseMathExpressionInputDirective.js"></script>\n<script src="/extensions/interactions/MathExpressionInput/directives/MathExpressionInputRulesService.js"></script>\n<script src="/extensions/interactions/MathExpressionInput/directives/MathExpressionInputValidationService.js"></script>\n \n<script src="/extensions/interactions/NumberWithUnits/directives/OppiaInteractiveNumberWithUnitsDirective.js"></script>\n<script src="/extensions/interactions/NumberWithUnits/directives/OppiaResponseNumberWithUnitsDirective.js"></script>\n<script src="/extensions/interactions/NumberWithUnits/directives/OppiaShortResponseNumberWithUnitsDirective.js"></script>\n<script src="/extensions/interactions/NumberWithUnits/directives/NumberWithUnitsRulesService.js"></script>\n<script src="/extensions/interactions/NumberWithUnits/directives/NumberWithUnitsValidationService.js"></script>\n \n<link rel="stylesheet" type="text/css" href="/extensions/interactions/CodeRepl/static/code_repl.css">\n\n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/OppiaInteractiveCodeReplDirective.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/OppiaResponseCodeReplDirective.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/OppiaShortResponseCodeReplDirective.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/CodeReplRulesService.js"></script>\n<script src="/extensions/interactions/CodeRepl/directives/CodeReplValidationService.js"></script>\n \n<script src="/templates/dev/head/filters/TruncateAtFirstLineFilter.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/OppiaInteractivePencilCodeEditorDirective.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/OppiaShortResponsePencilCodeEditorDirective.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/OppiaResponsePencilCodeEditorDirective.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/PencilCodeEditorRulesService.js"></script>\n<script src="/extensions/interactions/PencilCodeEditor/directives/PencilCodeEditorValidationService.js"></script>\n \n<link rel="stylesheet" type="text/css" href="/extensions/interactions/MusicNotesInput/static/music_notes_input.css">\n\n<script src="/extensions/interactions/MusicNotesInput/directives/OppiaInteractiveMusicNotesInputDirective.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/OppiaResponseMusicNotesInputDirective.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/OppiaShortResponseMusicNotesInputDirective.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/MusicPhrasePlayerService.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/MusicNotesInputRulesService.js"></script>\n<script src="/extensions/interactions/MusicNotesInput/directives/MusicNotesInputValidationService.js"></script>\n \n<script src="/extensions/interactions/InteractiveMap/directives/OppiaInteractiveInteractiveMapDirective.js"></script>\n<script src="/extensions/interactions/InteractiveMap/directives/OppiaResponseInteractiveMapDirective.js"></script>\n<script src="/extensions/interactions/InteractiveMap/directives/OppiaShortResponseInteractiveMapDirective.js"></script>\n<script src="/extensions/interactions/InteractiveMap/directives/InteractiveMapRulesService.js"></script>\n<script src="/extensions/interactions/InteractiveMap/directives/InteractiveMapValidationService.js"></script>\n\n <script>// Copyright 2019 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for "enumerated frequency table" visualization.\n */\n// Each visualization receives three variables: \'data\', \'options\', and\n// \'isAddressed\'. The exact format for each of these is specific to the\n// particular visualization.\noppia.directive(\'oppiaVisualizationEnumeratedFrequencyTable\', [\n \'UrlInterpolationService\', function (UrlInterpolationService) {\n return {\n restrict: \'E\',\n scope: {},\n bindToController: {},\n templateUrl: UrlInterpolationService.getExtensionResourceUrl(\'/visualizations/enumerated_frequency_table_directive.html\'),\n controllerAs: \'$ctrl\',\n controller: [\n \'$attrs\', \'HtmlEscaperService\',\n function ($attrs, HtmlEscaperService) {\n var ctrl = this;\n ctrl.data = HtmlEscaperService.escapedJsonToObj($attrs.escapedData);\n ctrl.options =\n HtmlEscaperService.escapedJsonToObj($attrs.escapedOptions);\n ctrl.addressedInfoIsSupported = $attrs.addressedInfoIsSupported;\n ctrl.answerVisible = ctrl.data.map(function (_, i) {\n // First element is shown while all others are hidden by default.\n return i === 0;\n });\n ctrl.toggleAnswerVisibility = function (i) {\n ctrl.answerVisible[i] = !ctrl.answerVisible[i];\n };\n }\n ]\n };\n }\n]);\n// Copyright 2014 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for "bar chart" visualization.\n */\n// Each visualization receives three variables: \'data\', \'options\', and\n// \'isAddressed\'. The exact format for each of these is specific to the\n// particular visualization.\noppia.directive(\'oppiaVisualizationBarChart\', [function () {\n return {\n restrict: \'E\',\n scope: {},\n bindToController: {},\n template: \'\',\n controllerAs: \'$ctrl\',\n controller: [\n \'$attrs\', \'$element\', \'HtmlEscaperService\',\n function ($attrs, $element, HtmlEscaperService) {\n var ctrl = this;\n ctrl.data = HtmlEscaperService.escapedJsonToObj($attrs.escapedData);\n ctrl.options =\n HtmlEscaperService.escapedJsonToObj($attrs.escapedOptions);\n var dataArray = [[\'Answers\', \'\']];\n for (var i = 0; i < ctrl.data.length; i++) {\n dataArray.push([\n String(ctrl.data[i].answer), ctrl.data[i].frequency\n ]);\n }\n var data = google.visualization.arrayToDataTable(dataArray);\n var options = {\n chartArea: {\n width: \'60%\'\n },\n hAxis: {\n title: \'Number of times answer was submitted\',\n minValue: 0\n },\n legend: null,\n vAxis: {\n title: \'Answer choice\'\n }\n };\n var chart = new google.visualization.BarChart($element[0]);\n chart.draw(data, options);\n }\n ]\n };\n }]);\n// Copyright 2019 The Oppia Authors. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the "License");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an "AS-IS" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * @fileoverview Directive for the "frequency table" visualization.\n */\n// Each visualization receives three variables: \'data\', \'options\', and\n// \'isAddressed\'. The exact format for each of these is specific to the\n// particular visualization.\noppia.directive(\'oppiaVisualizationFrequencyTable\', [\n \'UrlInterpolationService\', function (UrlInterpolationService) {\n return {\n restrict: \'E\',\n scope: {},\n bindToController: {},\n templateUrl: UrlInterpolationService.getExtensionResourceUrl(\'/visualizations/frequency_table_directive.html\'),\n controllerAs: \'$ctrl\',\n controller: [\n \'$attrs\', \'HtmlEscaperService\',\n function ($attrs, HtmlEscaperService) {\n var ctrl = this;\n ctrl.data = HtmlEscaperService.escapedJsonToObj($attrs.escapedData);\n ctrl.options =\n HtmlEscaperService.escapedJsonToObj($attrs.escapedOptions);\n ctrl.addressedInfoIsSupported = $attrs.addressedInfoIsSupported;\n }\n ]\n };\n }\n]);\n</script>\n\n <script src="https://pencilcode.net/lib/pencilcodeembed.js"></script>\n\n<script src="/third_party/static/math-expressions-1.7.0/math-expressions.js"></script>\n\n<script src="/third_party/static/code-mirror-3.19.0/lib/codemirror.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/coffeescript/coffeescript.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/javascript/javascript.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/lua/lua.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/python/python.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/ruby/ruby.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/scheme/scheme.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/mode/yaml/yaml.js"></script>\n<script src="/third_party/static/ui-codemirror-0.1.2/src/ui-codemirror.js"></script>\n\n<script src="/third_party/static/code-mirror-3.19.0/addon/merge/dep/diff_match_patch.js"></script>\n<script src="/third_party/static/code-mirror-3.19.0/addon/merge/merge.js"></script>\n\n<script src="/extensions/interactions/LogicProof/static/js/shared.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/student.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/teacher.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/data.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/generatedDefaultData.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/generatedParser.js"></script>\n<script src="/extensions/interactions/LogicProof/static/js/conversion.js"></script>\n\n<script src="/third_party/static/skulpt-0.10.0/skulpt.min.js">\n</script>\n<script src="/third_party/static/skulpt-0.10.0/skulpt-stdlib.js">\n</script>\n\n<script src="/templates/dev/head/domain/classifier/PredictionResultObjectFactory.js"></script>\n<script src="/extensions/interactions/CodeRepl/CodeReplPredictionService.js"></script>\n<script src="/extensions/classifiers/PythonProgramTokenizer.js"></script>\n<script src="/extensions/classifiers/SVMPredictionService.js"></script>\n<script src="/extensions/classifiers/CountVectorizerService.js"></script>\n<script src="/extensions/classifiers/WinnowingPreprocessingService.js"></script>\n\n<script src="/templates/dev/head/domain/classifier/PredictionResultObjectFactory.js"></script>\n<script src="/extensions/interactions/TextInput/TextInputPredictionService.js"></script>\n<script src="/extensions/classifiers/SVMPredictionService.js"></script>\n<script src="/extensions/classifiers/TextInputTokenizer.js"></script>\n<script src="/extensions/classifiers/CountVectorizerService.js"></script>\n\n<link rel="stylesheet" href="/third_party/static/leaflet-1.4.0/leaflet.css">\n<script src="/third_party/static/leaflet-1.4.0/leaflet.js"></script>\n<script src="/third_party/static/angular-ui-leaflet-1.0.3/ui-leaflet.min.no-header.js"></script>\n<!-- The angular-simple-logger is a dependency in ui-leaflet angular plugin. -->\n<script src="/third_party/static/angular-simple-logger-0.1.7/angular-simple-logger.min.js"></script>\n\n<link rel="stylesheet" href="/third_party/static/guppy-b5055b/build/guppy-default.min.css">\n<script type="text/javascript" src="/third_party/static/guppy-b5055b/build/guppy.min.js"></script>\n\n<script type="text/javascript">\n Guppy.init({\n "path": "/third_party/static/guppy-b5055b/build"\n });\n</script>\n\n<style>\n .guppy_active {\n border: 1px solid rgba(81, 203, 238, 1);\n }\n\n .guppy_inactive {\n background: #ffffff;\n border: 1px solid black;\n }\n\n .guppy_active .main_cursor {\n animation: guppy-blink-animation 1s steps(2, start) infinite;\n -webkit-animation: guppy-blink-animation 1s steps(2, start) infinite;\n /* Overrides the inline styling and sets the cursor color to black. */\n color: black !important;\n }\n\n @keyframes guppy-blink-animation {\n to { visibility: hidden; }\n }\n\n @-webkit-keyframes guppy-blink-animation {\n to { visibility: hidden; }\n }\n</style>\n\n<script src="/third_party/static/midi-js-2ef687/build/MIDI.js"></script>\n<!-- This is needed for MIDI.js to work. -->\n<script src="/third_party/static/midi-js-2ef687/inc/base64binary.js"></script>\n<script>\n $(document).ready(function() {\n MIDI.loadPlugin({\n soundfontUrl: \'/third_party/static/midi-js-2ef687/soundfont/\',\n instrument: \'acoustic_grand_piano\',\n callback: function() {}\n });\n });\n</script>\n\n\n </body>\n</html>'
405
406---------------------------------------------------------------------
407FAILED core.controllers.editor_test.EditorTests: 0 errors, 1 failures
408
409Ran 4 tests in 1 test class.
410(0 ERRORS, 1 FAILURES)