rapid-router 5.4.1__py2.py3-none-any.whl → 7.6.8__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. example_project/rapid_router_test_settings.py +164 -0
  2. example_project/settings.py +152 -0
  3. example_project/urls.py +15 -0
  4. example_project/{example_project/wsgi.py → wsgi.py} +2 -1
  5. game/__init__.py +1 -1
  6. game/admin.py +43 -4
  7. game/app_settings.py +3 -7
  8. game/character.py +26 -18
  9. game/decor.py +172 -97
  10. game/end_to_end_tests/base_game_test.py +44 -33
  11. game/end_to_end_tests/editor_page.py +17 -2
  12. game/end_to_end_tests/game_page.py +127 -45
  13. game/end_to_end_tests/selenium_test_case.py +1 -20
  14. game/end_to_end_tests/test_cow_crashes.py +3 -5
  15. game/end_to_end_tests/test_language_dropdown.py +14 -0
  16. game/end_to_end_tests/test_level_editor.py +290 -0
  17. game/end_to_end_tests/test_level_failures.py +1 -1
  18. game/end_to_end_tests/test_level_selection.py +79 -0
  19. game/end_to_end_tests/test_play_through.py +240 -102
  20. game/end_to_end_tests/test_python_levels.py +44 -13
  21. game/end_to_end_tests/test_saving_workspace.py +22 -0
  22. game/forms.py +9 -2
  23. game/level_management.py +38 -29
  24. game/messages.py +1218 -203
  25. game/migrations/0001_squashed_0025_levels_ordering_pt1.py +19 -1
  26. game/migrations/0026_levels_pt2.py +13 -2
  27. game/migrations/0032_cannot_turn_left_level.py +13 -2
  28. game/migrations/0033_recursion_level.py +13 -2
  29. game/migrations/0034_joes_level.py +13 -2
  30. game/migrations/0035_disable_route_score_level_70.py +0 -2
  31. game/migrations/0036_level_score_73.py +0 -2
  32. game/migrations/0037_level_score_79.py +0 -2
  33. game/migrations/0038_level_score_40.py +0 -1
  34. game/migrations/0042_level_score_73.py +0 -2
  35. game/migrations/0048_add_cow_field_and_blocks.py +0 -2
  36. game/migrations/0049_level_score_34.py +0 -2
  37. game/migrations/0050_level_score_40.py +0 -2
  38. game/migrations/0051_level_score_49.py +0 -1
  39. game/migrations/0076_level_locked_for_class.py +19 -0
  40. game/migrations/0077_alter_level_next_level.py +52 -0
  41. game/migrations/0078_add_block_types.py +23 -0
  42. game/migrations/0079_populate_block_type_add_cow_blocks.py +60 -0
  43. game/migrations/0080_level_disable_algorithm_score.py +18 -0
  44. game/migrations/0081_first_12_levels_no_algo_score.py +29 -0
  45. game/migrations/0082_level_43_solution.py +16 -0
  46. game/migrations/0083_add_cows_to_existing_levels.py +195 -0
  47. game/migrations/0084_alter_block_block_type.py +18 -0
  48. game/migrations/0085_add_new_blocks.py +53 -0
  49. game/migrations/0086_loop_levels.py +482 -0
  50. game/migrations/0087_workspace_python_view_enabled.py +18 -0
  51. game/migrations/0088_rename_episodes.py +35 -0
  52. game/migrations/0089_episodes_in_development.py +30 -0
  53. game/migrations/0090_add_missing_model_solutions.py +144 -0
  54. game/migrations/0091_disable_algo_score_if_no_model_solution.py +46 -0
  55. game/migrations/0092_disable_algo_score_in_custom_levels.py +28 -0
  56. game/migrations/0093_alter_level_character_name.py +18 -0
  57. game/migrations/0094_add_hint_lesson_subtitle_to_levels.py +28 -0
  58. game/migrations/0095_level_commands.py +18 -0
  59. game/migrations/0096_alter_level_commands.py +18 -0
  60. game/migrations/0097_add_python_den_levels.py +1515 -0
  61. game/migrations/0098_add_episode_link_fields.py +44 -0
  62. game/migrations/0099_python_episodes_links.py +103 -0
  63. game/migrations/0100_reorder_python_levels.py +179 -0
  64. game/migrations/0101_rename_episodes.py +45 -0
  65. game/migrations/0102_reoder_episodes_13_14.py +136 -0
  66. game/migrations/0103_level_1015_solution.py +26 -0
  67. game/migrations/0104_remove_level_direct_drive.py +17 -0
  68. game/migrations/0105_delete_invalid_attempts.py +18 -0
  69. game/migrations/0106_fields_to_snake_case.py +48 -0
  70. game/migrations/0107_rename_worksheet_link_episode_student_worksheet_link.py +18 -0
  71. game/migrations/0108_episode_indy_worksheet_link.py +18 -0
  72. game/migrations/0109_create_episodes_23_and_24.py +99 -0
  73. game/migrations/0110_remove_episode_indy_worksheet_link_and_more.py +100 -0
  74. game/migrations/0111_create_worksheets.py +149 -0
  75. game/migrations/0112_worksheet_locked_classes.py +21 -0
  76. game/migrations/0113_level_needs_approval.py +18 -0
  77. game/migrations/0114_default_and_non_student_levels_no_approval.py +31 -0
  78. game/migrations/0115_level_level__default_does_not_need_approval.py +22 -0
  79. game/migrations/0116_update_worksheet_video_links.py +68 -0
  80. game/migrations/0117_update_solutions_to_if_else.py +61 -0
  81. game/models.py +157 -16
  82. game/permissions.py +34 -19
  83. game/python_den_urls.py +26 -0
  84. game/random_road.py +43 -127
  85. game/serializers.py +12 -17
  86. game/static/django_reverse_js/js/reverse.js +171 -0
  87. game/static/game/css/LilitaOne-Regular.ttf +0 -0
  88. game/static/game/css/backgrounds.css +14 -10
  89. game/static/game/css/dataTables.custom.css +4 -2
  90. game/static/game/css/dataTables.jqueryui.css +561 -320
  91. game/static/game/css/editor.css +47 -0
  92. game/static/game/css/game.css +43 -49
  93. game/static/game/css/game_screen.css +116 -53
  94. game/static/game/css/jquery.dataTables.css +455 -251
  95. game/static/game/css/level_editor.css +10 -1
  96. game/static/game/css/level_selection.css +32 -3
  97. game/static/game/css/level_share.css +6 -5
  98. game/static/game/css/skulpt/codemirror.css +1 -0
  99. game/static/game/image/Python_Den_hero_student.png +0 -0
  100. game/static/game/image/Python_levels_page.svg +1954 -0
  101. game/static/game/image/characters/front_view/Electric_van.svg +448 -0
  102. game/static/game/image/characters/top_view/Electric_van.svg +448 -0
  103. game/static/game/image/characters/top_view/Sleigh.svg +436 -0
  104. game/static/game/image/decor/city/solar_panel.svg +1200 -0
  105. game/static/game/image/decor/farm/solar_panel.svg +86 -0
  106. game/static/game/image/decor/grass/solar_panel.svg +86 -0
  107. game/static/game/image/decor/snow/barn.svg +1788 -0
  108. game/static/game/image/decor/snow/cfc.svg +1050 -147
  109. game/static/game/image/decor/snow/crops.svg +7370 -0
  110. game/static/game/image/decor/snow/hospital.svg +1220 -0
  111. game/static/game/image/decor/snow/house1.svg +971 -0
  112. game/static/game/image/decor/snow/house2.svg +1574 -0
  113. game/static/game/image/decor/snow/school.svg +1071 -0
  114. game/static/game/image/decor/snow/shop.svg +3211 -0
  115. game/static/game/image/decor/snow/solar_panel.svg +173 -0
  116. game/static/game/image/electric_van.svg +448 -0
  117. game/static/game/image/icons/add_house.svg +26 -0
  118. game/static/game/image/icons/delete_house.svg +26 -0
  119. game/static/game/image/icons/description.svg +1 -0
  120. game/static/game/image/icons/hint.svg +1 -0
  121. game/static/game/image/icons/if_else.svg +3 -0
  122. game/static/game/image/icons/python.svg +1 -1
  123. game/static/game/image/if_else_example.png +0 -0
  124. game/static/game/image/pigeon.svg +684 -0
  125. game/static/game/image/python_den_header.svg +19 -0
  126. game/static/game/js/animation.js +84 -28
  127. game/static/game/js/blockly/msg/js/bg.js +52 -1
  128. game/static/game/js/blockly/msg/js/ca.js +52 -1
  129. game/static/game/js/blockly/msg/js/en-gb.js +52 -1
  130. game/static/game/js/blockly/msg/js/en.js +52 -1
  131. game/static/game/js/blockly/msg/js/es.js +52 -1
  132. game/static/game/js/blockly/msg/js/fr.js +52 -1
  133. game/static/game/js/blockly/msg/js/hi.js +52 -1
  134. game/static/game/js/blockly/msg/js/it.js +52 -1
  135. game/static/game/js/blockly/msg/js/pl.js +52 -1
  136. game/static/game/js/blockly/msg/js/pt-br.js +52 -1
  137. game/static/game/js/blockly/msg/js/ru.js +52 -1
  138. game/static/game/js/blockly/msg/js/ur.js +52 -1
  139. game/static/game/js/blocklyCompiler.js +550 -392
  140. game/static/game/js/blocklyControl.js +335 -302
  141. game/static/game/js/blocklyCustomBlocks.js +691 -458
  142. game/static/game/js/blocklyCustomisations.js +3 -1
  143. game/static/game/js/button.js +12 -0
  144. game/static/game/js/cow.js +15 -130
  145. game/static/game/js/drawing.js +313 -201
  146. game/static/game/js/editor.js +23 -0
  147. game/static/game/js/game.js +148 -139
  148. game/static/game/js/jquery.dataTables.min.js +3 -159
  149. game/static/game/js/level_editor.js +823 -448
  150. game/static/game/js/level_moderation.js +33 -2
  151. game/static/game/js/level_selection.js +62 -25
  152. game/static/game/js/loadLanguages.js +21 -0
  153. game/static/game/js/map.js +106 -36
  154. game/static/game/js/model.js +55 -107
  155. game/static/game/js/pathFinder.js +73 -72
  156. game/static/game/js/program.js +184 -193
  157. game/static/game/js/pythonControl.js +14 -1
  158. game/static/game/js/scoreboard.js +0 -37
  159. game/static/game/js/scoreboardSharedLevels.js +48 -0
  160. game/static/game/js/sharing.js +22 -10
  161. game/static/game/js/skulpt/codemirror.js +5 -4
  162. game/static/game/js/skulpt/skulpt-stdlib.js +1 -1
  163. game/static/game/js/sound.js +52 -5
  164. game/static/game/js/van.js +0 -7
  165. game/static/game/raphael_image/characters/top_view/Electric_van.svg +448 -0
  166. game/static/game/raphael_image/characters/top_view/Sleigh.svg +436 -0
  167. game/static/game/raphael_image/decor/city/solar_panel.svg +1200 -0
  168. game/static/game/raphael_image/decor/farm/solar_panel.svg +86 -0
  169. game/static/game/raphael_image/decor/grass/solar_panel.svg +86 -0
  170. game/static/game/raphael_image/decor/snow/barn.svg +1788 -0
  171. game/static/game/raphael_image/decor/snow/cfc.svg +1050 -147
  172. game/static/game/raphael_image/decor/snow/crops.svg +7370 -0
  173. game/static/game/raphael_image/decor/snow/hospital.svg +1220 -0
  174. game/static/game/raphael_image/decor/snow/house1.svg +971 -0
  175. game/static/game/raphael_image/decor/snow/house2.svg +1574 -0
  176. game/static/game/raphael_image/decor/snow/school.svg +1071 -0
  177. game/static/game/raphael_image/decor/snow/shop.svg +3211 -0
  178. game/static/game/raphael_image/decor/snow/solar_panel.svg +173 -0
  179. game/static/game/raphael_image/pigeon.svg +685 -0
  180. game/static/game/raphael_image/sleigh_wreckage.svg +430 -0
  181. game/static/game/sass/game.scss +22 -6
  182. game/static/game/sound/clown_horn.mp3 +0 -0
  183. game/static/game/sound/clown_horn.ogg +0 -0
  184. game/static/game/sound/electric_van_starting.mp3 +0 -0
  185. game/static/game/sound/electric_van_starting.ogg +0 -0
  186. game/static/game/sound/pigeon.mp3 +0 -0
  187. game/static/game/sound/pigeon.ogg +0 -0
  188. game/static/game/sound/sleigh_bells.mp3 +0 -0
  189. game/static/game/sound/sleigh_bells.ogg +0 -0
  190. game/static/game/sound/sleigh_crash.mp3 +0 -0
  191. game/static/game/sound/sleigh_crash.ogg +0 -0
  192. game/templates/game/base.html +35 -15
  193. game/templates/game/basenonav.html +23 -17
  194. game/templates/game/game.html +236 -111
  195. game/templates/game/level_editor.html +353 -275
  196. game/templates/game/level_moderation.html +19 -6
  197. game/templates/game/level_selection.html +75 -62
  198. game/templates/game/python_den_level_selection.html +291 -0
  199. game/templates/game/python_den_worksheet.html +101 -0
  200. game/templates/game/scoreboard.html +88 -65
  201. game/tests/test_level_editor.py +210 -35
  202. game/tests/test_level_moderation.py +6 -20
  203. game/tests/test_level_selection.py +332 -11
  204. game/tests/test_python_den_worksheet.py +85 -0
  205. game/tests/test_scoreboard.py +258 -66
  206. game/tests/utils/level.py +43 -3
  207. game/tests/utils/teacher.py +2 -2
  208. game/theme.py +21 -21
  209. game/urls.py +125 -78
  210. game/views/language_code_conversions.py +90 -0
  211. game/views/level.py +201 -63
  212. game/views/level_editor.py +109 -48
  213. game/views/level_moderation.py +29 -6
  214. game/views/level_selection.py +179 -56
  215. game/views/level_solutions.py +600 -106
  216. game/views/scoreboard.py +181 -66
  217. game/views/worksheet.py +25 -0
  218. rapid_router-7.6.8.dist-info/METADATA +174 -0
  219. {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/RECORD +222 -242
  220. {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/WHEEL +1 -1
  221. rapid_router-7.6.8.dist-info/licenses/LICENSE.md +3 -0
  222. example_project/example_project/__init__.py +0 -1
  223. example_project/example_project/settings.py +0 -54
  224. example_project/example_project/urls.py +0 -16
  225. example_project/manage.py +0 -10
  226. game/autoconfig.py +0 -59
  227. game/csp_config.py +0 -23
  228. game/locale/ar_SA/LC_MESSAGES/django.mo +0 -0
  229. game/locale/ar_SA/LC_MESSAGES/django.po +0 -405
  230. game/locale/ar_SA/LC_MESSAGES/djangojs.mo +0 -0
  231. game/locale/ar_SA/LC_MESSAGES/djangojs.po +0 -743
  232. game/locale/bg_BG/LC_MESSAGES/django.mo +0 -0
  233. game/locale/bg_BG/LC_MESSAGES/django.po +0 -405
  234. game/locale/bg_BG/LC_MESSAGES/djangojs.mo +0 -0
  235. game/locale/bg_BG/LC_MESSAGES/djangojs.po +0 -739
  236. game/locale/ca_ES/LC_MESSAGES/django.mo +0 -0
  237. game/locale/ca_ES/LC_MESSAGES/django.po +0 -405
  238. game/locale/ca_ES/LC_MESSAGES/djangojs.mo +0 -0
  239. game/locale/ca_ES/LC_MESSAGES/djangojs.po +0 -740
  240. game/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  241. game/locale/cs_CZ/LC_MESSAGES/django.po +0 -405
  242. game/locale/cs_CZ/LC_MESSAGES/djangojs.mo +0 -0
  243. game/locale/cs_CZ/LC_MESSAGES/djangojs.po +0 -741
  244. game/locale/cy_GB/LC_MESSAGES/django.mo +0 -0
  245. game/locale/cy_GB/LC_MESSAGES/django.po +0 -405
  246. game/locale/cy_GB/LC_MESSAGES/djangojs.mo +0 -0
  247. game/locale/cy_GB/LC_MESSAGES/djangojs.po +0 -743
  248. game/locale/de_DE/LC_MESSAGES/django.mo +0 -0
  249. game/locale/de_DE/LC_MESSAGES/django.po +0 -405
  250. game/locale/de_DE/LC_MESSAGES/djangojs.mo +0 -0
  251. game/locale/de_DE/LC_MESSAGES/djangojs.po +0 -739
  252. game/locale/el_GR/LC_MESSAGES/django.mo +0 -0
  253. game/locale/el_GR/LC_MESSAGES/django.po +0 -405
  254. game/locale/el_GR/LC_MESSAGES/djangojs.mo +0 -0
  255. game/locale/el_GR/LC_MESSAGES/djangojs.po +0 -739
  256. game/locale/en_GB/LC_MESSAGES/django.mo +0 -0
  257. game/locale/en_GB/LC_MESSAGES/django.po +0 -405
  258. game/locale/en_GB/LC_MESSAGES/djangojs.mo +0 -0
  259. game/locale/en_GB/LC_MESSAGES/djangojs.po +0 -739
  260. game/locale/es_ES/LC_MESSAGES/django.mo +0 -0
  261. game/locale/es_ES/LC_MESSAGES/django.po +0 -405
  262. game/locale/es_ES/LC_MESSAGES/djangojs.mo +0 -0
  263. game/locale/es_ES/LC_MESSAGES/djangojs.po +0 -739
  264. game/locale/fi_FI/LC_MESSAGES/django.mo +0 -0
  265. game/locale/fi_FI/LC_MESSAGES/django.po +0 -405
  266. game/locale/fi_FI/LC_MESSAGES/djangojs.mo +0 -0
  267. game/locale/fi_FI/LC_MESSAGES/djangojs.po +0 -739
  268. game/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
  269. game/locale/fr_FR/LC_MESSAGES/django.po +0 -405
  270. game/locale/fr_FR/LC_MESSAGES/djangojs.mo +0 -0
  271. game/locale/fr_FR/LC_MESSAGES/djangojs.po +0 -739
  272. game/locale/gu_IN/LC_MESSAGES/django.mo +0 -0
  273. game/locale/gu_IN/LC_MESSAGES/django.po +0 -405
  274. game/locale/gu_IN/LC_MESSAGES/djangojs.mo +0 -0
  275. game/locale/gu_IN/LC_MESSAGES/djangojs.po +0 -739
  276. game/locale/hi_IN/LC_MESSAGES/django.mo +0 -0
  277. game/locale/hi_IN/LC_MESSAGES/django.po +0 -405
  278. game/locale/hi_IN/LC_MESSAGES/djangojs.mo +0 -0
  279. game/locale/hi_IN/LC_MESSAGES/djangojs.po +0 -739
  280. game/locale/id_ID/LC_MESSAGES/django.mo +0 -0
  281. game/locale/id_ID/LC_MESSAGES/django.po +0 -405
  282. game/locale/id_ID/LC_MESSAGES/djangojs.mo +0 -0
  283. game/locale/id_ID/LC_MESSAGES/djangojs.po +0 -738
  284. game/locale/it_IT/LC_MESSAGES/django.mo +0 -0
  285. game/locale/it_IT/LC_MESSAGES/django.po +0 -405
  286. game/locale/it_IT/LC_MESSAGES/djangojs.mo +0 -0
  287. game/locale/it_IT/LC_MESSAGES/djangojs.po +0 -739
  288. game/locale/ja_JP/LC_MESSAGES/django.mo +0 -0
  289. game/locale/ja_JP/LC_MESSAGES/django.po +0 -405
  290. game/locale/ja_JP/LC_MESSAGES/djangojs.mo +0 -0
  291. game/locale/ja_JP/LC_MESSAGES/djangojs.po +0 -738
  292. game/locale/lol_US/LC_MESSAGES/django.mo +0 -0
  293. game/locale/lol_US/LC_MESSAGES/django.po +0 -405
  294. game/locale/lol_US/LC_MESSAGES/djangojs.mo +0 -0
  295. game/locale/lol_US/LC_MESSAGES/djangojs.po +0 -739
  296. game/locale/nb_NO/LC_MESSAGES/django.mo +0 -0
  297. game/locale/nb_NO/LC_MESSAGES/django.po +0 -405
  298. game/locale/nb_NO/LC_MESSAGES/djangojs.mo +0 -0
  299. game/locale/nb_NO/LC_MESSAGES/djangojs.po +0 -739
  300. game/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
  301. game/locale/nl_NL/LC_MESSAGES/django.po +0 -405
  302. game/locale/nl_NL/LC_MESSAGES/djangojs.mo +0 -0
  303. game/locale/nl_NL/LC_MESSAGES/djangojs.po +0 -739
  304. game/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
  305. game/locale/pl_PL/LC_MESSAGES/django.po +0 -405
  306. game/locale/pl_PL/LC_MESSAGES/djangojs.mo +0 -0
  307. game/locale/pl_PL/LC_MESSAGES/djangojs.po +0 -741
  308. game/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  309. game/locale/pt_BR/LC_MESSAGES/django.po +0 -405
  310. game/locale/pt_BR/LC_MESSAGES/djangojs.mo +0 -0
  311. game/locale/pt_BR/LC_MESSAGES/djangojs.po +0 -739
  312. game/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  313. game/locale/pt_PT/LC_MESSAGES/django.po +0 -405
  314. game/locale/pt_PT/LC_MESSAGES/djangojs.mo +0 -0
  315. game/locale/pt_PT/LC_MESSAGES/djangojs.po +0 -739
  316. game/locale/ro_RO/LC_MESSAGES/django.mo +0 -0
  317. game/locale/ro_RO/LC_MESSAGES/django.po +0 -405
  318. game/locale/ro_RO/LC_MESSAGES/djangojs.mo +0 -0
  319. game/locale/ro_RO/LC_MESSAGES/djangojs.po +0 -740
  320. game/locale/ru_RU/LC_MESSAGES/django.mo +0 -0
  321. game/locale/ru_RU/LC_MESSAGES/django.po +0 -405
  322. game/locale/ru_RU/LC_MESSAGES/djangojs.mo +0 -0
  323. game/locale/ru_RU/LC_MESSAGES/djangojs.po +0 -741
  324. game/locale/sv_SE/LC_MESSAGES/django.mo +0 -0
  325. game/locale/sv_SE/LC_MESSAGES/django.po +0 -405
  326. game/locale/sv_SE/LC_MESSAGES/djangojs.mo +0 -0
  327. game/locale/sv_SE/LC_MESSAGES/djangojs.po +0 -739
  328. game/locale/tl_PH/LC_MESSAGES/django.mo +0 -0
  329. game/locale/tl_PH/LC_MESSAGES/django.po +0 -405
  330. game/locale/tl_PH/LC_MESSAGES/djangojs.mo +0 -0
  331. game/locale/tl_PH/LC_MESSAGES/djangojs.po +0 -739
  332. game/locale/tlh_AA/LC_MESSAGES/django.mo +0 -0
  333. game/locale/tlh_AA/LC_MESSAGES/django.po +0 -405
  334. game/locale/tlh_AA/LC_MESSAGES/djangojs.mo +0 -0
  335. game/locale/tlh_AA/LC_MESSAGES/djangojs.po +0 -739
  336. game/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
  337. game/locale/tr_TR/LC_MESSAGES/django.po +0 -405
  338. game/locale/tr_TR/LC_MESSAGES/djangojs.mo +0 -0
  339. game/locale/tr_TR/LC_MESSAGES/djangojs.po +0 -740
  340. game/locale/ur_IN/LC_MESSAGES/django.mo +0 -0
  341. game/locale/ur_IN/LC_MESSAGES/django.po +0 -405
  342. game/locale/ur_IN/LC_MESSAGES/djangojs.mo +0 -0
  343. game/locale/ur_IN/LC_MESSAGES/djangojs.po +0 -739
  344. game/locale/ur_PK/LC_MESSAGES/django.mo +0 -0
  345. game/locale/ur_PK/LC_MESSAGES/django.po +0 -405
  346. game/locale/ur_PK/LC_MESSAGES/djangojs.mo +0 -0
  347. game/locale/ur_PK/LC_MESSAGES/djangojs.po +0 -739
  348. game/static/game/image/actions/go.svg +0 -18
  349. game/static/game/image/icons/destination.svg +0 -9
  350. game/static/game/js/pqselect.min.js +0 -9
  351. game/static/game/js/widget-scroller.js +0 -906
  352. rapid_router-5.4.1.dist-info/LICENSE.md +0 -577
  353. rapid_router-5.4.1.dist-info/METADATA +0 -24
  354. {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/top_level.txt +0 -0
game/random_road.py CHANGED
@@ -1,20 +1,15 @@
1
1
  from __future__ import absolute_import
2
- from __future__ import division
3
- from builtins import range
4
- from past.utils import old_div
5
- from django.core.cache import cache
2
+
6
3
  import json
7
4
  import math
8
5
  import random
9
-
10
- from . import level_management
11
-
6
+ from builtins import range
12
7
  from collections import defaultdict, namedtuple
13
- from .models import Level, Block
14
8
 
15
9
  from game.decor import get_decor_element
16
10
  from game.theme import get_theme
17
-
11
+ from . import level_management
12
+ from .models import Level, Block
18
13
 
19
14
  Node = namedtuple("Node", ["x", "y"])
20
15
 
@@ -53,12 +48,7 @@ def decor_data():
53
48
 
54
49
  def decor_sum():
55
50
  data = decor_data()
56
- return (
57
- data["bush"]["ratio"]
58
- + data["pond"]["ratio"]
59
- + data["tree1"]["ratio"]
60
- + data["tree2"]["ratio"]
61
- )
51
+ return data["bush"]["ratio"] + data["pond"]["ratio"] + data["tree1"]["ratio"] + data["tree2"]["ratio"]
62
52
 
63
53
 
64
54
  def create(episode=None):
@@ -68,22 +58,18 @@ def create(episode=None):
68
58
  loopiness = episode.r_loopiness if episode else DEFAULT_LOOPINESS
69
59
  curviness = episode.r_curviness if episode else DEFAULT_CURVINESS
70
60
  blocks = episode.r_blocks.all() if episode else Block.objects.all()
71
- traffic_lights = episode.r_trafficLights if episode else DEFAULT_TRAFFIC_LIGHTS
61
+ traffic_lights = episode.r_traffic_lights if episode else DEFAULT_TRAFFIC_LIGHTS
72
62
  cows = episode.r_cows if episode else DEFAULT_TRAFFIC_LIGHTS
73
63
  decor = DEFAULT_DECOR
74
64
 
75
- level_data = generate_random_map_data(
76
- num_tiles, branchiness, loopiness, curviness, traffic_lights, cows, decor
77
- )
65
+ level_data = generate_random_map_data(num_tiles, branchiness, loopiness, curviness, traffic_lights, cows, decor)
78
66
 
79
67
  level_data["max_fuel"] = DEFAULT_MAX_FUEL
80
68
  level_data["theme"] = 1
81
- level_data["name"] = (
82
- ("Random level for " + episode.name) if episode else "Default random level"
83
- )
69
+ level_data["name"] = ("Random level for " + episode.name) if episode else "Default random level"
84
70
  level_data["character"] = 1
85
- level_data["blocklyEnabled"] = episode.r_blocklyEnabled if episode else True
86
- level_data["pythonEnabled"] = episode.r_pythonEnabled if episode else False
71
+ level_data["blockly_enabled"] = episode.r_blockly_enabled if episode else True
72
+ level_data["python_enabled"] = episode.r_python_enabled if episode else False
87
73
  level_data["blocks"] = [{"type": block.type} for block in blocks]
88
74
 
89
75
  level = Level(default=False, anonymous=True)
@@ -93,13 +79,7 @@ def create(episode=None):
93
79
 
94
80
 
95
81
  def generate_random_map_data(
96
- num_tiles,
97
- branchiness,
98
- loopiness,
99
- curviness,
100
- traffic_lights_enabled,
101
- decor_enabled,
102
- cows_enabled,
82
+ num_tiles, branchiness, loopiness, curviness, traffic_lights_enabled, decor_enabled, cows_enabled
103
83
  ):
104
84
  path = generate_random_path(num_tiles, branchiness, loopiness, curviness)
105
85
  traffic_lights = generate_traffic_lights(path) if traffic_lights_enabled else []
@@ -118,9 +98,7 @@ def generate_random_map_data(
118
98
  }
119
99
 
120
100
 
121
- def generate_random_path(
122
- num_road_tiles, branchiness_factor, loopiness_factor, curviness_factor
123
- ):
101
+ def generate_random_path(num_road_tiles, branchiness_factor, loopiness_factor, curviness_factor):
124
102
  def pick_adjacent_node(nodes, connections, branchiness_factor, curviness_factor):
125
103
  for attempts in range(5):
126
104
  origin = pick_origin_node(nodes, connections, branchiness_factor)
@@ -134,12 +112,7 @@ def generate_random_path(
134
112
  possibles.append(node)
135
113
 
136
114
  if possibles:
137
- return (
138
- origin,
139
- pick_destination_node(
140
- nodes, connections, origin, possibles, curviness_factor
141
- ),
142
- )
115
+ return (origin, pick_destination_node(nodes, connections, origin, possibles, curviness_factor))
143
116
 
144
117
  return None, None
145
118
 
@@ -150,22 +123,13 @@ def generate_random_path(
150
123
  return nodes[-1]
151
124
 
152
125
  def pick_destination_node(nodes, connections, origin, possibles, curviness_factor):
153
- existing_connections = [
154
- nodes[nodeIndex] for nodeIndex in connections[nodes.index(origin)]
155
- ]
156
- existing_connection_directions = [
157
- (node.x - origin.x, node.y - origin.y) for node in existing_connections
158
- ]
126
+ existing_connections = [nodes[nodeIndex] for nodeIndex in connections[nodes.index(origin)]]
127
+ existing_connection_directions = [(node.x - origin.x, node.y - origin.y) for node in existing_connections]
159
128
  linear = [
160
- node
161
- for node in possibles
162
- if (origin.x - node.x, origin.y - node.y) in existing_connection_directions
129
+ node for node in possibles if (origin.x - node.x, origin.y - node.y) in existing_connection_directions
163
130
  ]
164
131
  curved = [
165
- node
166
- for node in possibles
167
- if (origin.x - node.x, origin.y - node.y)
168
- not in existing_connection_directions
132
+ node for node in possibles if (origin.x - node.x, origin.y - node.y) not in existing_connection_directions
169
133
  ]
170
134
 
171
135
  if linear and curved:
@@ -179,9 +143,7 @@ def generate_random_path(
179
143
  return random.choice(pick_from)
180
144
 
181
145
  def join_up_loops(nodes, connections, loopiness_factor):
182
- nodes_by_location = {
183
- (node.x, node.y): (index, node) for index, node in enumerate(nodes)
184
- }
146
+ nodes_by_location = {(node.x, node.y): (index, node) for index, node in enumerate(nodes)}
185
147
  n = len(nodes)
186
148
 
187
149
  # Floyd-Warshall algorithm to find distances between all nodes
@@ -211,10 +173,7 @@ def generate_random_path(
211
173
  for location in get_neighbouring_locations(node):
212
174
  if location in nodes_by_location:
213
175
  adjacent_node_index, adjacent_node = nodes_by_location[location]
214
- if (
215
- adjacent_node_index > node_index
216
- and adjacent_node != nodes[0]
217
- ):
176
+ if adjacent_node_index > node_index and adjacent_node != nodes[0]:
218
177
  if adjacent_node_index not in connections[node_index]:
219
178
  possible_loops.append((node_index, adjacent_node_index))
220
179
 
@@ -227,7 +186,7 @@ def generate_random_path(
227
186
  # Now join up loops (does not dynamically update distances, but still get required effect)
228
187
  max_loop_distance = max([distances[s][d] for s, d in possible_loops])
229
188
  for origin, destination in possible_loops:
230
- distance_factor = old_div(distances[origin][destination], max_loop_distance)
189
+ distance_factor = distances[origin][destination] // max_loop_distance
231
190
  adjusted_loopiness_factor = loopiness_factor * (
232
191
  (1 - loopiness_deviation) + loopiness_deviation * distance_factor
233
192
  )
@@ -251,9 +210,7 @@ def generate_random_path(
251
210
  return math.atan2(node_2.y - node_1.y, node_2.x - node_1.x)
252
211
 
253
212
  def is_possible(node, nodes):
254
- return (
255
- (node not in nodes) and 0 < node.x < WIDTH - 1 and 0 < node.y < HEIGHT - 1
256
- )
213
+ return (node not in nodes) and 0 < node.x < WIDTH - 1 and 0 < node.y < HEIGHT - 1
257
214
 
258
215
  def get_neighbouring_locations(node):
259
216
  squares = []
@@ -270,15 +227,11 @@ def generate_random_path(
270
227
  connections = defaultdict(list)
271
228
 
272
229
  for _ in range(num_road_tiles - 1):
273
- (previous_node, new_node) = pick_adjacent_node(
274
- nodes, connections, branchiness_factor, curviness_factor
275
- )
230
+ (previous_node, new_node) = pick_adjacent_node(nodes, connections, branchiness_factor, curviness_factor)
276
231
  if new_node:
277
232
  nodes.append(new_node)
278
233
  index_by_node[new_node] = len(nodes) - 1
279
- connections = add_new_connections(
280
- connections, len(nodes) - 1, index_by_node[previous_node]
281
- )
234
+ connections = add_new_connections(connections, len(nodes) - 1, index_by_node[previous_node])
282
235
 
283
236
  connections = join_up_loops(nodes, connections, loopiness_factor)
284
237
  result = []
@@ -287,9 +240,7 @@ def generate_random_path(
287
240
  {
288
241
  "coordinate": node,
289
242
  "connectedNodes": sorted(
290
- connections[index],
291
- key=lambda conn: calculate_node_angle(node, nodes[conn]),
292
- reverse=True,
243
+ connections[index], key=lambda conn: calculate_node_angle(node, nodes[conn]), reverse=True
293
244
  ),
294
245
  }
295
246
  )
@@ -301,10 +252,7 @@ def get_origin(path):
301
252
  node = path[1]
302
253
  neighbour = path[0]
303
254
  direction = get_direction(node, neighbour)
304
- return {
305
- "coordinate": [neighbour["coordinate"].x, neighbour["coordinate"].y],
306
- "direction": direction,
307
- }
255
+ return {"coordinate": [neighbour["coordinate"].x, neighbour["coordinate"].y], "direction": direction}
308
256
 
309
257
 
310
258
  def generate_traffic_lights(path):
@@ -323,15 +271,12 @@ def generate_traffic_lights(path):
323
271
  else:
324
272
  candidateNodes = degree2Nodes
325
273
 
326
- numberOfJunctions = max(
327
- int(len(candidateNodes) * PERCENTAGE_OF_JUNCTIONS_WITH_TRAFFIC_LIGHTS / 100.0),
328
- 1,
329
- )
274
+ numberOfJunctions = max(int(len(candidateNodes) * PERCENTAGE_OF_JUNCTIONS_WITH_TRAFFIC_LIGHTS / 100.0), 1)
330
275
 
331
276
  random.shuffle(candidateNodes)
332
277
  nodesSelected = candidateNodes[:numberOfJunctions]
333
278
 
334
- trafficLights = []
279
+ traffic_lights = []
335
280
  for node in nodesSelected:
336
281
 
337
282
  controlledNeighbours = []
@@ -346,12 +291,9 @@ def generate_traffic_lights(path):
346
291
 
347
292
  direction = get_direction(node, neighbour)
348
293
 
349
- trafficLights.append(
294
+ traffic_lights.append(
350
295
  {
351
- "sourceCoordinate": {
352
- "x": neighbour["coordinate"].x,
353
- "y": neighbour["coordinate"].y,
354
- },
296
+ "sourceCoordinate": {"x": neighbour["coordinate"].x, "y": neighbour["coordinate"].y},
355
297
  "direction": direction,
356
298
  "startTime": 0 if counter == 0 else 2 * (counter - 1),
357
299
  "startingState": "GREEN" if counter == 0 else "RED",
@@ -361,7 +303,7 @@ def generate_traffic_lights(path):
361
303
  )
362
304
  counter += 1
363
305
 
364
- return trafficLights
306
+ return traffic_lights
365
307
 
366
308
 
367
309
  def generate_cows(path):
@@ -388,11 +330,7 @@ def generate_decor(path, num_tiles):
388
330
  def find_node_by_coordinate(x, y, dec, nodes):
389
331
  for node in nodes:
390
332
  coord = node["coordinate"]
391
- if (
392
- coord.x == x
393
- and coord.y == y
394
- or (dec == "pond" and coord.x == x + 1 and coord.y == y)
395
- ):
333
+ if coord.x == x and coord.y == y or (dec == "pond" and coord.x == x + 1 and coord.y == y):
396
334
  return True
397
335
  return False
398
336
 
@@ -402,21 +340,13 @@ def generate_decor(path, num_tiles):
402
340
 
403
341
  # if there is a decor occupying this grid or neighbouring one in case of the pond
404
342
  if (
405
- old_div(coord["x"], GRID_SIZE) == x
406
- and old_div(coord["y"], GRID_SIZE) == y
343
+ coord["x"] // GRID_SIZE == x
344
+ and coord["y"] // GRID_SIZE == y
407
345
  or (
408
346
  elem == "pond"
409
- and (
410
- old_div(coord["x"], GRID_SIZE) == x + 1
411
- and old_div(coord["y"], GRID_SIZE) == y
412
- or x + 1 < WIDTH
413
- )
414
- )
415
- or (
416
- dec["decorName"] == "pond"
417
- and old_div(coord["x"], GRID_SIZE) + 1 == x
418
- and old_div(coord["y"], GRID_SIZE) == y
347
+ and (coord["x"] // GRID_SIZE == x + 1 and coord["y"] // GRID_SIZE == y or x + 1 < WIDTH)
419
348
  )
349
+ or (dec["decor_name"] == "pond" and coord["x"] // GRID_SIZE + 1 == x and coord["y"] // GRID_SIZE == y)
420
350
  ):
421
351
  return True
422
352
 
@@ -438,13 +368,7 @@ def generate_decor(path, num_tiles):
438
368
  x = x * GRID_SIZE + int((GRID_SIZE - decor_object.width) * 0.5 * (1 - dx))
439
369
  y = y * GRID_SIZE + int((GRID_SIZE - decor_object.height) * 0.5 * (1 - dy))
440
370
 
441
- decor.append(
442
- {
443
- "coordinate": {"x": x, "y": y},
444
- "decorName": dec,
445
- "height": decor_object.height,
446
- }
447
- )
371
+ decor.append({"coordinate": {"x": x, "y": y}, "decor_name": dec, "height": decor_object.height})
448
372
 
449
373
  def place_near_road(elem, decor, path):
450
374
  for i in range(1, len(path) - 1):
@@ -452,33 +376,25 @@ def generate_decor(path, num_tiles):
452
376
  for (dx, dy) in DIRECTIONS:
453
377
  x = node["coordinate"].x + dx
454
378
  y = node["coordinate"].y + dy
455
- if not (
456
- find_decor_by_coordinate(x, y, elem, decor)
457
- or find_node_by_coordinate(x, y, dec, path)
458
- ):
379
+ if not (find_decor_by_coordinate(x, y, elem, decor) or find_node_by_coordinate(x, y, dec, path)):
459
380
  return append_decor(decor, x, y, elem, dx, dy)
460
381
 
461
382
  def place_randomly(dec, decor):
462
383
  x = random.randint(0, 9)
463
384
  y = random.randint(0, 7)
464
385
 
465
- if not (
466
- find_decor_by_coordinate(x, y, dec, decor)
467
- or find_node_by_coordinate(x, y, dec, path)
468
- ):
386
+ if not (find_decor_by_coordinate(x, y, dec, decor) or find_node_by_coordinate(x, y, dec, path)):
469
387
  return append_decor(decor, x, y, dec)
470
388
 
471
389
  def place_bush(elem, decor, nodes):
472
390
  bush_exists = False
473
391
  for dec in decor:
474
- if dec["decorName"] == elem:
392
+ if dec["decor_name"] == elem:
475
393
  bush_exists = True
476
394
  for (dx, dy) in DIRECTIONS:
477
- x = old_div(dec["coordinate"]["x"], GRID_SIZE) + dx
478
- y = old_div(dec["coordinate"]["y"], GRID_SIZE) + dy
479
- if near_road(x, y, nodes) and not find_decor_by_coordinate(
480
- x, y, elem, decor
481
- ):
395
+ x = dec["coordinate"]["x"] // GRID_SIZE + dx
396
+ y = dec["coordinate"]["y"] // GRID_SIZE + dy
397
+ if near_road(x, y, nodes) and not find_decor_by_coordinate(x, y, elem, decor):
482
398
  return append_decor(decor, x, y, elem, dx, dy)
483
399
 
484
400
  if not bush_exists:
@@ -487,7 +403,7 @@ def generate_decor(path, num_tiles):
487
403
  decor = []
488
404
  decor_count = 0
489
405
  for dec in DECOR_DATA:
490
- for i in range(0, old_div(DECOR_DATA[dec]["ratio"] * num_tiles, DECOR_SUM)):
406
+ for i in range(0, DECOR_DATA[dec]["ratio"] * num_tiles // DECOR_SUM):
491
407
  if decor_count + num_tiles < WIDTH * HEIGHT:
492
408
  if dec == "bush":
493
409
  place_bush(dec, decor, path)
game/serializers.py CHANGED
@@ -5,7 +5,6 @@ from builtins import object
5
5
  from rest_framework import serializers
6
6
 
7
7
  from game import messages
8
- from game.messages import description_level_default, hint_level_default
9
8
  from game.theme import get_theme, get_themes_url
10
9
  from .models import Workspace, Level, Episode, LevelDecor, LevelBlock, Block
11
10
 
@@ -27,8 +26,8 @@ class LevelListSerializer(serializers.HyperlinkedModelSerializer):
27
26
  "name",
28
27
  "title",
29
28
  "default",
30
- "blocklyEnabled",
31
- "pythonEnabled",
29
+ "blockly_enabled",
30
+ "python_enabled",
32
31
  )
33
32
 
34
33
  def get_title(self, obj):
@@ -43,6 +42,7 @@ class LevelDetailSerializer(serializers.HyperlinkedModelSerializer):
43
42
  title = serializers.SerializerMethodField()
44
43
  description = serializers.SerializerMethodField()
45
44
  hint = serializers.SerializerMethodField()
45
+ commands = serializers.SerializerMethodField()
46
46
  levelblock_set = serializers.HyperlinkedIdentityField(
47
47
  view_name="levelblock-for-level", read_only=True
48
48
  )
@@ -67,9 +67,9 @@ class LevelDetailSerializer(serializers.HyperlinkedModelSerializer):
67
67
  "levelblock_set",
68
68
  "map",
69
69
  "mode",
70
- "blocklyEnabled",
71
- "pythonEnabled",
72
- "pythonViewEnabled",
70
+ "blockly_enabled",
71
+ "python_enabled",
72
+ "python_view_enabled",
73
73
  )
74
74
 
75
75
  def get_title(self, obj):
@@ -80,18 +80,13 @@ class LevelDetailSerializer(serializers.HyperlinkedModelSerializer):
80
80
  return "Custom Level"
81
81
 
82
82
  def get_description(self, obj):
83
- if obj.default:
84
- description = getattr(messages, "description_level" + obj.name)()
85
- return description
86
- else:
87
- return description_level_default()
83
+ return getattr(messages, "description_level" + obj.name)() if obj.default else obj.description
88
84
 
89
85
  def get_hint(self, obj):
90
- if obj.default:
91
- hint = getattr(messages, "hint_level" + obj.name)()
92
- return hint
93
- else:
94
- return hint_level_default()
86
+ return getattr(messages, "hint_level" + obj.name)() if obj.default else obj.hint
87
+
88
+ def get_commands(self, obj):
89
+ return getattr(messages, "commands_level" + obj.name)() if obj.default else obj.commands
95
90
 
96
91
  def get_leveldecor_set(self, obj):
97
92
  leveldecors = LevelDecor.objects.filter(level__id=obj.id)
@@ -106,7 +101,7 @@ class LevelDetailSerializer(serializers.HyperlinkedModelSerializer):
106
101
  class LevelModeSerializer(serializers.HyperlinkedModelSerializer):
107
102
  class Meta(object):
108
103
  model = Level
109
- fields = ("blocklyEnabled", "pythonEnabled", "pythonViewEnabled")
104
+ fields = ("blockly_enabled", "python_enabled", "python_view_enabled")
110
105
 
111
106
 
112
107
  class LevelMapListSerializer(serializers.HyperlinkedModelSerializer):
@@ -0,0 +1,171 @@
1
+ this.Urls = (function () {
2
+ var data = {"urls": [["about", [["about", []]]], ["admin:app_list", [["administration/%(app_label)s/", ["app_label"]]]], ["admin:auth_group_add", [["administration/auth/group/add/", []]]], ["admin:auth_group_change", [["administration/auth/group/%(object_id)s/change/", ["object_id"]]]], ["admin:auth_group_changelist", [["administration/auth/group/", []]]], ["admin:auth_group_delete", [["administration/auth/group/%(object_id)s/delete/", ["object_id"]]]], ["admin:auth_group_history", [["administration/auth/group/%(object_id)s/history/", ["object_id"]]]], ["admin:auth_user_add", [["administration/auth/user/add/", []]]], ["admin:auth_user_change", [["administration/auth/user/%(object_id)s/change/", ["object_id"]]]], ["admin:auth_user_changelist", [["administration/auth/user/", []]]], ["admin:auth_user_delete", [["administration/auth/user/%(object_id)s/delete/", ["object_id"]]]], ["admin:auth_user_history", [["administration/auth/user/%(object_id)s/history/", ["object_id"]]]], ["admin:auth_user_password_change", [["administration/auth/user/%(id)s/password/", ["id"]]]], ["admin:autocomplete", [["administration/autocomplete/", []]]], ["admin:common_class_add", [["administration/common/class/add/", []]]], ["admin:common_class_change", [["administration/common/class/%(object_id)s/change/", ["object_id"]]]], ["admin:common_class_changelist", [["administration/common/class/", []]]], ["admin:common_class_delete", [["administration/common/class/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_class_history", [["administration/common/class/%(object_id)s/history/", ["object_id"]]]], ["admin:common_dailyactivity_add", [["administration/common/dailyactivity/add/", []]]], ["admin:common_dailyactivity_change", [["administration/common/dailyactivity/%(object_id)s/change/", ["object_id"]]]], ["admin:common_dailyactivity_changelist", [["administration/common/dailyactivity/", []]]], ["admin:common_dailyactivity_delete", [["administration/common/dailyactivity/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_dailyactivity_history", [["administration/common/dailyactivity/%(object_id)s/history/", ["object_id"]]]], ["admin:common_dynamicelement_add", [["administration/common/dynamicelement/add/", []]]], ["admin:common_dynamicelement_change", [["administration/common/dynamicelement/%(object_id)s/change/", ["object_id"]]]], ["admin:common_dynamicelement_changelist", [["administration/common/dynamicelement/", []]]], ["admin:common_dynamicelement_delete", [["administration/common/dynamicelement/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_dynamicelement_history", [["administration/common/dynamicelement/%(object_id)s/history/", ["object_id"]]]], ["admin:common_school_add", [["administration/common/school/add/", []]]], ["admin:common_school_change", [["administration/common/school/%(object_id)s/change/", ["object_id"]]]], ["admin:common_school_changelist", [["administration/common/school/", []]]], ["admin:common_school_delete", [["administration/common/school/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_school_history", [["administration/common/school/%(object_id)s/history/", ["object_id"]]]], ["admin:common_schoolteacherinvitation_add", [["administration/common/schoolteacherinvitation/add/", []]]], ["admin:common_schoolteacherinvitation_change", [["administration/common/schoolteacherinvitation/%(object_id)s/change/", ["object_id"]]]], ["admin:common_schoolteacherinvitation_changelist", [["administration/common/schoolteacherinvitation/", []]]], ["admin:common_schoolteacherinvitation_delete", [["administration/common/schoolteacherinvitation/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_schoolteacherinvitation_history", [["administration/common/schoolteacherinvitation/%(object_id)s/history/", ["object_id"]]]], ["admin:common_student_add", [["administration/common/student/add/", []]]], ["admin:common_student_change", [["administration/common/student/%(object_id)s/change/", ["object_id"]]]], ["admin:common_student_changelist", [["administration/common/student/", []]]], ["admin:common_student_delete", [["administration/common/student/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_student_history", [["administration/common/student/%(object_id)s/history/", ["object_id"]]]], ["admin:common_teacher_add", [["administration/common/teacher/add/", []]]], ["admin:common_teacher_change", [["administration/common/teacher/%(object_id)s/change/", ["object_id"]]]], ["admin:common_teacher_changelist", [["administration/common/teacher/", []]]], ["admin:common_teacher_delete", [["administration/common/teacher/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_teacher_history", [["administration/common/teacher/%(object_id)s/history/", ["object_id"]]]], ["admin:common_totalactivity_add", [["administration/common/totalactivity/add/", []]]], ["admin:common_totalactivity_change", [["administration/common/totalactivity/%(object_id)s/change/", ["object_id"]]]], ["admin:common_totalactivity_changelist", [["administration/common/totalactivity/", []]]], ["admin:common_totalactivity_delete", [["administration/common/totalactivity/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_totalactivity_history", [["administration/common/totalactivity/%(object_id)s/history/", ["object_id"]]]], ["admin:common_userprofile_add", [["administration/common/userprofile/add/", []]]], ["admin:common_userprofile_change", [["administration/common/userprofile/%(object_id)s/change/", ["object_id"]]]], ["admin:common_userprofile_changelist", [["administration/common/userprofile/", []]]], ["admin:common_userprofile_delete", [["administration/common/userprofile/%(object_id)s/delete/", ["object_id"]]]], ["admin:common_userprofile_history", [["administration/common/userprofile/%(object_id)s/history/", ["object_id"]]]], ["admin:game_attempt_add", [["administration/game/attempt/add/", []]]], ["admin:game_attempt_change", [["administration/game/attempt/%(object_id)s/change/", ["object_id"]]]], ["admin:game_attempt_changelist", [["administration/game/attempt/", []]]], ["admin:game_attempt_delete", [["administration/game/attempt/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_attempt_history", [["administration/game/attempt/%(object_id)s/history/", ["object_id"]]]], ["admin:game_block_add", [["administration/game/block/add/", []]]], ["admin:game_block_change", [["administration/game/block/%(object_id)s/change/", ["object_id"]]]], ["admin:game_block_changelist", [["administration/game/block/", []]]], ["admin:game_block_delete", [["administration/game/block/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_block_history", [["administration/game/block/%(object_id)s/history/", ["object_id"]]]], ["admin:game_episode_add", [["administration/game/episode/add/", []]]], ["admin:game_episode_change", [["administration/game/episode/%(object_id)s/change/", ["object_id"]]]], ["admin:game_episode_changelist", [["administration/game/episode/", []]]], ["admin:game_episode_delete", [["administration/game/episode/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_episode_history", [["administration/game/episode/%(object_id)s/history/", ["object_id"]]]], ["admin:game_level_add", [["administration/game/level/add/", []]]], ["admin:game_level_change", [["administration/game/level/%(object_id)s/change/", ["object_id"]]]], ["admin:game_level_changelist", [["administration/game/level/", []]]], ["admin:game_level_delete", [["administration/game/level/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_level_history", [["administration/game/level/%(object_id)s/history/", ["object_id"]]]], ["admin:game_leveldecor_add", [["administration/game/leveldecor/add/", []]]], ["admin:game_leveldecor_change", [["administration/game/leveldecor/%(object_id)s/change/", ["object_id"]]]], ["admin:game_leveldecor_changelist", [["administration/game/leveldecor/", []]]], ["admin:game_leveldecor_delete", [["administration/game/leveldecor/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_leveldecor_history", [["administration/game/leveldecor/%(object_id)s/history/", ["object_id"]]]], ["admin:game_workspace_add", [["administration/game/workspace/add/", []]]], ["admin:game_workspace_change", [["administration/game/workspace/%(object_id)s/change/", ["object_id"]]]], ["admin:game_workspace_changelist", [["administration/game/workspace/", []]]], ["admin:game_workspace_delete", [["administration/game/workspace/%(object_id)s/delete/", ["object_id"]]]], ["admin:game_workspace_history", [["administration/game/workspace/%(object_id)s/history/", ["object_id"]]]], ["admin:index", [["administration/", []]]], ["admin:jsi18n", [["administration/jsi18n/", []]]], ["admin:login", [["administration/login/", []]]], ["admin:logout", [["administration/logout/", []]]], ["admin:otp_static_staticdevice_add", [["administration/otp_static/staticdevice/add/", []]]], ["admin:otp_static_staticdevice_change", [["administration/otp_static/staticdevice/%(object_id)s/change/", ["object_id"]]]], ["admin:otp_static_staticdevice_changelist", [["administration/otp_static/staticdevice/", []]]], ["admin:otp_static_staticdevice_delete", [["administration/otp_static/staticdevice/%(object_id)s/delete/", ["object_id"]]]], ["admin:otp_static_staticdevice_history", [["administration/otp_static/staticdevice/%(object_id)s/history/", ["object_id"]]]], ["admin:otp_totp_totpdevice_add", [["administration/otp_totp/totpdevice/add/", []]]], ["admin:otp_totp_totpdevice_change", [["administration/otp_totp/totpdevice/%(object_id)s/change/", ["object_id"]]]], ["admin:otp_totp_totpdevice_changelist", [["administration/otp_totp/totpdevice/", []]]], ["admin:otp_totp_totpdevice_config", [["administration/otp_totp/totpdevice/%(pk)s/config/", ["pk"]]]], ["admin:otp_totp_totpdevice_delete", [["administration/otp_totp/totpdevice/%(object_id)s/delete/", ["object_id"]]]], ["admin:otp_totp_totpdevice_history", [["administration/otp_totp/totpdevice/%(object_id)s/history/", ["object_id"]]]], ["admin:otp_totp_totpdevice_qrcode", [["administration/otp_totp/totpdevice/%(pk)s/qrcode/", ["pk"]]]], ["admin:password_change", [["administration/password_change/", []]]], ["admin:password_change_done", [["administration/password_change/done/", []]]], ["admin:view_on_site", [["administration/r/%(content_type_id)s/%(object_id)s/", ["content_type_id", "object_id"]]]], ["administration_password_change", [["administration/password_change/", []]]], ["administration_password_change_done", [["administration/password_change_done/", []]]], ["anonymise-unverified-accounts", [["cron/user/unverified/delete/", []]]], ["anonymise_orphan_schools", [["schools/anonymise/%(start_id)s/", ["start_id"]]]], ["approve_level", [["rapidrouter/level_moderation/approve/%(levelID)s/", ["levelID"]]]], ["block-detail", [["rapidrouter/api/blocks/%(pk)s/", ["pk"]]]], ["block-list", [["rapidrouter/api/blocks/", []]]], ["celebrate", [["celebrate/", []]]], ["character-detail", [["rapidrouter/api/characters/%(pk)s/", ["pk"]]]], ["character-list", [["rapidrouter/api/characters/", []]]], ["codingClub", [["codingClub/", []]]], ["consent_form", [["consent_form/", []]]], ["contribute", [["contribute", []]]], ["dashboard", [["teach/dashboard/", []]]], ["decor-detail", [["rapidrouter/api/decors/%(pk)s/", ["pk"]]]], ["decor-list", [["rapidrouter/api/decors/", []]]], ["delete_account", [["delete/account/", []]]], ["delete_level", [["rapidrouter/level_moderation/delete/%(levelID)s/", ["levelID"]]]], ["delete_level_for_editor", [["rapidrouter/level_editor/delete/%(levelId)s/", ["levelId"]]]], ["delete_teacher_invite", [["teach/dashboard/delete_teacher_invite/%(token)s", ["token"]]]], ["delete_workspace", [["rapidrouter/workspace/delete/%(workspaceID)s/", ["workspaceID"]]]], ["email_verification", [["verify_email/", []]]], ["episode-detail", [["rapidrouter/api/episodes/%(pk)s/", ["pk"]]]], ["episode-list", [["rapidrouter/api/episodes/", []]]], ["final-inactivity-reminder", [["cron/user/inactive/send-final-reminder/", []]]], ["first-inactivity-reminder", [["cron/user/inactive/send-first-reminder/", []]]], ["first-verify-email-reminder", [["cron/user/unverified/send-first-reminder/", []]]], ["generate_random_map_for_editor", [["rapidrouter/level_editor/random/", []]]], ["get_sharing_information_for_editor", [["rapidrouter/level_editor/get_sharing_information/%(levelID)s/", ["levelID"]]]], ["getinvolved", [["getinvolved", []]]], ["home", [["", []]]], ["home-learning", [["home-learning", []]]], ["inactive_users", [["users/inactive/", []]]], ["independent_edit_account", [["play/account/independent/", []]]], ["independent_student_details", [["play/details/independent", []]]], ["independent_student_login", [["login/independent/", []]]], ["invite_toggle_admin", [["teach/dashboard/toggle_admin_invite/%(invite_id)s/", ["invite_id"]]]], ["invited_teacher", [["invited_teacher/%(token)s/", ["token"]]]], ["js-reverse", [["rapidrouter/reverse.js", []]]], ["last-connected-since", [["api/lastconnectedsince/%(year)s/%(month)s/%(day)s/", ["year", "month", "day"]]]], ["level-detail", [["rapidrouter/api/levels/%(pk)s/", ["pk"]]]], ["level-for-episode", [["rapidrouter/api/episodes/%(pk)s/levels/", ["pk"]]]], ["level-list", [["rapidrouter/api/levels/", []]]], ["level_editor", [["rapidrouter/level_editor/", []]]], ["level_editor_chosen_level", [["rapidrouter/level_editor/%(levelId)s/", ["levelId"]]]], ["level_moderation", [["rapidrouter/level_moderation/", []]]], ["levelblock-detail", [["rapidrouter/api/levelblocks/%(pk)s/", ["pk"]]]], ["levelblock-for-level", [["rapidrouter/api/levels/%(pk)s/blocks/", ["pk"]]]], ["leveldecor-detail", [["rapidrouter/api/leveldecors/%(pk)s/", ["pk"]]]], ["leveldecor-for-level", [["rapidrouter/api/levels/%(pk)s/decors/", ["pk"]]]], ["levels", [["rapidrouter/", []]]], ["load_level_for_editor", [["rapidrouter/level_editor/get/%(levelID)s/", ["levelID"]]]], ["load_list_of_workspaces", [["rapidrouter/workspace/load_list/", []]]], ["load_workspace", [["rapidrouter/workspace/load/%(workspaceID)s/", ["workspaceID"]]]], ["load_workspace_solution", [["rapidrouter/workspace/solution/%(level_name)s/", ["level_name"]]]], ["locked_out", [["locked_out/", []]]], ["logout_view", [["logout/", []]]], ["maintenance", [["maintenance/", []]]], ["map-for-level", [["rapidrouter/api/levels/%(pk)s/map/", ["pk"]]]], ["map-list", [["rapidrouter/api/maps/", []]]], ["mode-for-level", [["rapidrouter/api/levels/%(pk)s/mode/", ["pk"]]]], ["number_users_per_country", [["api/userspercountry/%(country)s/", ["country"]]]], ["old_login_form", [["login_form", []]]], ["onboarding-class", [["teach/onboarding-class/%(access_code)s", ["access_code"]]]], ["onboarding-classes", [["teach/onboarding-classes", []]]], ["onboarding-organisation", [["teach/onboarding-organisation/", []]]], ["organisation_kick", [["teach/dashboard/kick/%(pk)s/", ["pk"]]]], ["organisation_leave", [["teach/dashboard/school/leave/", []]]], ["organisation_toggle_admin", [["teach/dashboard/toggle_admin/%(pk)s/", ["pk"]]]], ["owned_levels", [["rapidrouter/level_editor/levels/owned/", []]]], ["password_reset_check_and_confirm", [["user/password/reset/%(uidb64)s-%(token)s/", ["uidb64", "token"]]]], ["password_reset_complete", [["teacher/password/reset/complete/", []]]], ["play", [["play/", []]]], ["play_anonymous_level", [["rapidrouter/level_editor/play_anonymous/%(levelId)s/", ["levelId"]]]], ["play_custom_level", [["rapidrouter/custom/%(levelId)s/", ["levelId"]]]], ["play_custom_level_from_editor", [["rapidrouter/level_editor/play_custom/%(levelId)s/", ["levelId"]]]], ["play_default_level", [["rapidrouter/%(level_name)s/", ["level_name"]], ["%(level_name)s/", ["level_name"]]]], ["play_python_default_level", [["pythonden/%(level_name)s/", ["level_name"]]]], ["privacy_notice", [["privacy-notice/", []]]], ["privacy_policy", [["privacy-policy/", []]]], ["process_newsletter_form", [["news_signup/", []]]], ["python_levels", [["pythonden/", []]]], ["python_scoreboard", [["pythonden/scoreboard/", []]]], ["random_level_for_episode", [["rapidrouter/levels/random/%(_0)s/", ["_0"]]]], ["rapid-router/javascript-catalog", [["rapidrouter/js-i18n/", []]]], ["register", [["register_form", []]]], ["registered-users", [["api/registered/%(year)s/%(month)s/%(day)s/", ["year", "month", "day"]]]], ["remove_fake_accounts", [["removeFakeAccounts/", []]]], ["resend_invite_teacher", [["teach/dashboard/resend_invite/%(token)s/", ["token"]]]], ["reset_password_email_sent", [["user/password/reset/done/", []]]], ["reset_screentime_warning", [["user/reset_screentime_warning/", []]]], ["reset_session_time", [["user/reset_session_time/", []]]], ["rest_framework:login", [["rapidrouter/api-auth/login/", []]]], ["rest_framework:logout", [["rapidrouter/api-auth/logout/", []]]], ["save_level_for_editor", [["rapidrouter/level_editor/save/%(levelId)s/", ["levelId"]], ["rapidrouter/level_editor/save/", []]]], ["save_workspace", [["rapidrouter/workspace/save/%(workspaceID)s/", ["workspaceID"]], ["rapidrouter/workspace/save/", []]]], ["school_student_edit_account", [["play/account/school_student/", []]]], ["scoreboard", [["rapidrouter/scoreboard/", []]]], ["second-inactivity-reminder", [["cron/user/inactive/send-second-reminder/", []]]], ["second-verify-email-reminder", [["cron/user/unverified/send-second-reminder/", []]]], ["set_language", [["i18n/setlang/", []]]], ["share_level_for_editor", [["rapidrouter/level_editor/share/%(levelID)s/", ["levelID"]]]], ["shared_levels", [["rapidrouter/level_editor/levels/shared/", []]]], ["start_episode", [["rapidrouter/episode/%(episodeId)s/", ["episodeId"]]]], ["start_python_episode", [["pythonden/episode/%(episodeId)s/", ["episodeId"]]]], ["student_details", [["play/details/", []]]], ["student_direct_login", [["u/%(user_id)s/%(login_id)s/", ["user_id", "login_id"]]]], ["student_edit_account", [["play/account/", []]]], ["student_join_organisation", [["play/join/", []]]], ["student_login", [["login/student/%(access_code)s/", ["access_code"]], ["login/student/%(access_code)s/%(login_type)s/", ["access_code", "login_type"]]]], ["student_login_access_code", [["login/student/", []]]], ["student_password_reset", [["user/password/reset/student/", []]]], ["submit_attempt", [["rapidrouter/submit/", []]]], ["teach", [["teach/", []]]], ["teacher_accept_student_request", [["teach/dashboard/student/accept/%(pk)s/", ["pk"]]]], ["teacher_class_password_reset", [["teach/class/%(access_code)s/password_reset/", ["access_code"]]]], ["teacher_delete_class", [["teach/class/delete/%(access_code)s", ["access_code"]]]], ["teacher_delete_students", [["teach/class/%(access_code)s/students/delete/", ["access_code"]]]], ["teacher_disable_2FA", [["teach/dashboard/disable_2FA/%(pk)s/", ["pk"]]]], ["teacher_dismiss_students", [["teach/class/%(access_code)s/students/dismiss/", ["access_code"]]]], ["teacher_download_csv", [["teach/onboarding-class/%(access_code)s/download_csv/", ["access_code"]]]], ["teacher_edit_class", [["teach/class/edit/%(access_code)s", ["access_code"]]]], ["teacher_edit_student", [["teach/class/student/edit/%(pk)s/", ["pk"]]]], ["teacher_login", [["login/teacher/", []]]], ["teacher_move_students", [["teach/class/%(access_code)s/students/move/", ["access_code"]]]], ["teacher_move_students_to_class", [["teach/class/%(access_code)s/students/move/disambiguate/", ["access_code"]]]], ["teacher_password_reset", [["user/password/reset/teacher/", []]]], ["teacher_print_reminder_cards", [["teach/onboarding-class/%(access_code)s/print_reminder_cards/", ["access_code"]]]], ["teacher_reject_student_request", [["teach/dashboard/student/reject/%(pk)s/", ["pk"]]]], ["terms", [["terms", []]]], ["theme-detail", [["rapidrouter/api/themes/%(pk)s/", ["pk"]]]], ["theme-list", [["rapidrouter/api/themes/", []]]], ["two_factor:backup_tokens", [["account/two_factor/backup/tokens/", []]]], ["two_factor:disable", [["account/two_factor/disable/", []]]], ["two_factor:profile", [["account/two_factor/", []]]], ["two_factor:qr", [["account/two_factor/qrcode/", []]]], ["two_factor:setup", [["account/two_factor/setup/", []]]], ["two_factor:setup_complete", [["account/two_factor/setup/complete/", []]]], ["verify_email", [["verify_email/%(token)s/", ["token"]]]], ["view_class", [["teach/class/%(access_code)s", ["access_code"]]]]], "prefix": "/"};
3
+ var resolverFactory;
4
+ /******/ (() => { // webpackBootstrap
5
+ /******/ "use strict";
6
+ /******/ // The require scope
7
+ /******/ var __webpack_require__ = {};
8
+ /******/
9
+ /************************************************************************/
10
+ /******/ /* webpack/runtime/define property getters */
11
+ /******/ (() => {
12
+ /******/ // define getter functions for harmony exports
13
+ /******/ __webpack_require__.d = (exports, definition) => {
14
+ /******/ for(var key in definition) {
15
+ /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
16
+ /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
17
+ /******/ }
18
+ /******/ }
19
+ /******/ };
20
+ /******/ })();
21
+ /******/
22
+ /******/ /* webpack/runtime/hasOwnProperty shorthand */
23
+ /******/ (() => {
24
+ /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
25
+ /******/ })();
26
+ /******/
27
+ /******/ /* webpack/runtime/make namespace object */
28
+ /******/ (() => {
29
+ /******/ // define __esModule on exports
30
+ /******/ __webpack_require__.r = (exports) => {
31
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
32
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
33
+ /******/ }
34
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
35
+ /******/ };
36
+ /******/ })();
37
+ /******/
38
+ /************************************************************************/
39
+ var __webpack_exports__ = {};
40
+ __webpack_require__.r(__webpack_exports__);
41
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
42
+ /* harmony export */ "UrlResolver": () => (/* binding */ UrlResolver),
43
+ /* harmony export */ "factory": () => (/* binding */ factory)
44
+ /* harmony export */ });
45
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
46
+
47
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
48
+
49
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
50
+
51
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
52
+
53
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
54
+
55
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
56
+
57
+ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
58
+
59
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
60
+
61
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
62
+
63
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
64
+
65
+ var UrlResolver = /*#__PURE__*/function () {
66
+ function UrlResolver(prefix, patterns) {
67
+ _classCallCheck(this, UrlResolver);
68
+
69
+ this.prefix = prefix;
70
+ this.patterns = patterns;
71
+ this.reverse = this.reverse.bind(this);
72
+ }
73
+
74
+ _createClass(UrlResolver, [{
75
+ key: "reverse",
76
+ value: function reverse() {
77
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
78
+ args[_key] = arguments[_key];
79
+ }
80
+
81
+ var validateArgs, buildKwargs;
82
+
83
+ if (args.length === 1 && _typeof(args[0]) === 'object') {
84
+ // kwargs mode
85
+ var providedKeys = Object.keys(args[0]);
86
+
87
+ validateArgs = function validateArgs(_ref) {
88
+ var _ref2 = _slicedToArray(_ref, 2),
89
+ _urlTemplate = _ref2[0],
90
+ urlParams = _ref2[1];
91
+
92
+ // check every needed param was provided (without extra elements)
93
+ return urlParams.length === providedKeys.length && urlParams.every(function (p) {
94
+ return providedKeys.includes(p);
95
+ });
96
+ }; // return first element
97
+
98
+
99
+ buildKwargs = function buildKwargs() {
100
+ return args[0];
101
+ };
102
+ } else {
103
+ // args mode
104
+ // check every required param
105
+ validateArgs = function validateArgs(_ref3) {
106
+ var _ref4 = _slicedToArray(_ref3, 2),
107
+ _urlTemplate = _ref4[0],
108
+ urlParams = _ref4[1];
109
+
110
+ return urlParams.length === args.length;
111
+ }; // build keyword-arguments from arguments
112
+
113
+
114
+ buildKwargs = function buildKwargs(keys) {
115
+ return Object.fromEntries(keys.map(function (key, i) {
116
+ return [key, args[i]];
117
+ }));
118
+ };
119
+ } // search between patterns if one matches provided args
120
+
121
+
122
+ var urlPattern = this.patterns.find(validateArgs);
123
+
124
+ if (!urlPattern) {
125
+ return null;
126
+ }
127
+
128
+ var _urlPattern = _slicedToArray(urlPattern, 2),
129
+ urlTemplate = _urlPattern[0],
130
+ urlKwargNames = _urlPattern[1];
131
+
132
+ var urlKwargs = buildKwargs(urlKwargNames);
133
+ var url = Object.entries(urlKwargs).reduce(function (partialUrl, _ref5) {
134
+ var _ref6 = _slicedToArray(_ref5, 2),
135
+ pName = _ref6[0],
136
+ pValue = _ref6[1];
137
+
138
+ if (pValue == null) pValue = ''; // replace variable with param
139
+
140
+ return partialUrl.replace("%(".concat(pName, ")s"), pValue);
141
+ }, urlTemplate);
142
+ return "".concat(this.prefix).concat(url);
143
+ }
144
+ }]);
145
+
146
+ return UrlResolver;
147
+ }();
148
+ function factory(config) {
149
+ var urlPatterns = config.urls,
150
+ urlPrefix = config.prefix;
151
+ return urlPatterns.reduce(function (resolver, _ref7) {
152
+ var _ref8 = _slicedToArray(_ref7, 2),
153
+ name = _ref8[0],
154
+ pattern = _ref8[1];
155
+
156
+ var urlResolver = new UrlResolver(urlPrefix, pattern);
157
+ resolver[name] = urlResolver.reverse; // turn snake-case into camel-case
158
+
159
+ resolver[name.replace(/[-_]+(.)/g, function (_m, p1) {
160
+ return p1.toUpperCase();
161
+ })] = urlResolver.reverse; // turn snake-case into dash-case
162
+
163
+ resolver[name.replace(/-/g, '_')] = urlResolver.reverse;
164
+ return resolver;
165
+ }, {});
166
+ }
167
+ resolverFactory = __webpack_exports__;
168
+ /******/ })()
169
+ ;
170
+ return data ? resolverFactory.factory(data) : resolverFactory.factory;
171
+ })();