cuju-render 0.1.0__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 (382) hide show
  1. cuju/render/__init__.py +759 -0
  2. cuju/render/__main__.py +1065 -0
  3. cuju/render/_export/__init__.py +3 -0
  4. cuju/render/_export/feed.py +542 -0
  5. cuju/render/_export/sizes.py +157 -0
  6. cuju/render/_export/video.py +1618 -0
  7. cuju/render/_export/video_jobs.py +408 -0
  8. cuju/render/_format/__init__.py +3 -0
  9. cuju/render/_format/annotations.py +235 -0
  10. cuju/render/_format/codec.py +307 -0
  11. cuju/render/_format/keep.py +121 -0
  12. cuju/render/_format/recording.py +860 -0
  13. cuju/render/_format/writer.py +54 -0
  14. cuju/render/_guide/__init__.py +3 -0
  15. cuju/render/_guide/doctor.py +523 -0
  16. cuju/render/_guide/help.py +62 -0
  17. cuju/render/_guide/tutorial.py +254 -0
  18. cuju/render/_http/__init__.py +3 -0
  19. cuju/render/_http/commands.py +57 -0
  20. cuju/render/_http/headers.py +103 -0
  21. cuju/render/_http/launch.py +500 -0
  22. cuju/render/_http/launchers.py +408 -0
  23. cuju/render/_http/pwa.py +128 -0
  24. cuju/render/_http/server.py +2105 -0
  25. cuju/render/_http/window.py +360 -0
  26. cuju/render/_moments/__init__.py +3 -0
  27. cuju/render/_moments/captions.py +284 -0
  28. cuju/render/_moments/events.py +1123 -0
  29. cuju/render/_moments/search.py +694 -0
  30. cuju/render/_packages/__init__.py +3 -0
  31. cuju/render/_packages/glsl.py +746 -0
  32. cuju/render/_packages/loudness.py +334 -0
  33. cuju/render/_packages/pack.py +1959 -0
  34. cuju/render/_packages/presentation.py +1376 -0
  35. cuju/render/_packages/vocabulary.py +609 -0
  36. cuju/render/_playing/__init__.py +3 -0
  37. cuju/render/_playing/achievements.py +463 -0
  38. cuju/render/_playing/bench.py +609 -0
  39. cuju/render/_playing/challenges.py +1813 -0
  40. cuju/render/_playing/demo.py +323 -0
  41. cuju/render/_playing/draw.py +211 -0
  42. cuju/render/_playing/errors.py +20 -0
  43. cuju/render/_playing/game.py +645 -0
  44. cuju/render/_playing/limits.py +339 -0
  45. cuju/render/_playing/play.py +926 -0
  46. cuju/render/_playing/policy_worker.py +250 -0
  47. cuju/render/_playing/strict.py +810 -0
  48. cuju/render/_registry/__init__.py +3 -0
  49. cuju/render/_registry/clips.py +394 -0
  50. cuju/render/_registry/joints.py +108 -0
  51. cuju/render/_registry/teams.py +2058 -0
  52. cuju/render/_store/__init__.py +3 -0
  53. cuju/render/_store/home.py +70 -0
  54. cuju/render/_store/library.py +604 -0
  55. cuju/render/_store/samples.py +163 -0
  56. cuju/render/_text/__init__.py +3 -0
  57. cuju/render/_text/languages.py +637 -0
  58. cuju/render/_text/messages.py +1396 -0
  59. cuju/render/_tournaments/__init__.py +3 -0
  60. cuju/render/_tournaments/results.py +547 -0
  61. cuju/render/_tournaments/tournament.py +2742 -0
  62. cuju/render/_tournaments/tournament_cli.py +587 -0
  63. cuju/render/_tournaments/tournament_runner.py +1975 -0
  64. cuju/render/_version.py +6 -0
  65. cuju/render/_watch/__init__.py +3 -0
  66. cuju/render/_watch/grid.py +265 -0
  67. cuju/render/_watch/live.py +664 -0
  68. cuju/render/_watch/notebook.py +79 -0
  69. cuju/render/_watch/show.py +171 -0
  70. cuju/render/samples/sample-11v11.cjr +0 -0
  71. cuju/render/samples/sample-5v5.cjr +0 -0
  72. cuju/render/samples/teams/starter/main.py +33 -0
  73. cuju/render/scenarios/benchmark_full_game_11_vs_11_easy.py +46 -0
  74. cuju/render/scenarios/benchmark_full_game_11_vs_11_hard.py +46 -0
  75. cuju/render/scenarios/benchmark_full_game_11_vs_11_medium.py +46 -0
  76. cuju/render/scenarios/benchmark_full_game_5_vs_5_easy.py +34 -0
  77. cuju/render/scenarios/benchmark_full_game_5_vs_5_hard.py +34 -0
  78. cuju/render/scenarios/benchmark_full_game_5_vs_5_medium.py +34 -0
  79. cuju/render/web/assets/adboard_polygon.webp +0 -0
  80. cuju/render/web/assets/adboard_your_ad_here.webp +0 -0
  81. cuju/render/web/assets/animations/kaykit-rig-medium-combatmelee.glb +0 -0
  82. cuju/render/web/assets/animations/kaykit-rig-medium-general.glb +0 -0
  83. cuju/render/web/assets/animations/kaykit-rig-medium-movementadvanced.glb +0 -0
  84. cuju/render/web/assets/animations/kaykit-rig-medium-movementbasic.glb +0 -0
  85. cuju/render/web/assets/animations/kaykit-rig-medium-simulation.glb +0 -0
  86. cuju/render/web/assets/animations/kaykit-rig-medium-special.glb +0 -0
  87. cuju/render/web/assets/ball.glb +0 -0
  88. cuju/render/web/assets/challenges/3_vs_1_with_keeper.mp4 +0 -0
  89. cuju/render/web/assets/challenges/3_vs_1_with_keeper.webp +0 -0
  90. cuju/render/web/assets/challenges/corner.mp4 +0 -0
  91. cuju/render/web/assets/challenges/corner.webp +0 -0
  92. cuju/render/web/assets/challenges/counterattack_easy.mp4 +0 -0
  93. cuju/render/web/assets/challenges/counterattack_easy.webp +0 -0
  94. cuju/render/web/assets/challenges/counterattack_hard.mp4 +0 -0
  95. cuju/render/web/assets/challenges/counterattack_hard.webp +0 -0
  96. cuju/render/web/assets/challenges/empty_goal.mp4 +0 -0
  97. cuju/render/web/assets/challenges/empty_goal.webp +0 -0
  98. cuju/render/web/assets/challenges/empty_goal_close.mp4 +0 -0
  99. cuju/render/web/assets/challenges/empty_goal_close.webp +0 -0
  100. cuju/render/web/assets/challenges/manifest.json +375 -0
  101. cuju/render/web/assets/challenges/one_on_one.mp4 +0 -0
  102. cuju/render/web/assets/challenges/one_on_one.webp +0 -0
  103. cuju/render/web/assets/challenges/one_on_one_hard.mp4 +0 -0
  104. cuju/render/web/assets/challenges/one_on_one_hard.webp +0 -0
  105. cuju/render/web/assets/challenges/pass_and_shoot_with_keeper.mp4 +0 -0
  106. cuju/render/web/assets/challenges/pass_and_shoot_with_keeper.webp +0 -0
  107. cuju/render/web/assets/challenges/run_pass_and_shoot_with_keeper.mp4 +0 -0
  108. cuju/render/web/assets/challenges/run_pass_and_shoot_with_keeper.webp +0 -0
  109. cuju/render/web/assets/challenges/run_to_score.mp4 +0 -0
  110. cuju/render/web/assets/challenges/run_to_score.webp +0 -0
  111. cuju/render/web/assets/challenges/run_to_score_with_keeper.mp4 +0 -0
  112. cuju/render/web/assets/challenges/run_to_score_with_keeper.webp +0 -0
  113. cuju/render/web/assets/challenges/single_goal_versus_lazy.mp4 +0 -0
  114. cuju/render/web/assets/challenges/single_goal_versus_lazy.webp +0 -0
  115. cuju/render/web/assets/crowd.webp +0 -0
  116. cuju/render/web/assets/crowd_normal.webp +0 -0
  117. cuju/render/web/assets/cuju-logo-384.png +0 -0
  118. cuju/render/web/assets/cuju-logo.png +0 -0
  119. cuju/render/web/assets/cuju-logo.svg +46 -0
  120. cuju/render/web/assets/cuju-mark-light.svg +33 -0
  121. cuju/render/web/assets/cuju-mark.svg +33 -0
  122. cuju/render/web/assets/goal.glb +0 -0
  123. cuju/render/web/assets/grass.webp +0 -0
  124. cuju/render/web/assets/hair_black.png +0 -0
  125. cuju/render/web/assets/hair_blonde.png +0 -0
  126. cuju/render/web/assets/hair_brown.png +0 -0
  127. cuju/render/web/assets/hair_darkblonde.png +0 -0
  128. cuju/render/web/assets/hair_long01.glb +0 -0
  129. cuju/render/web/assets/hair_long02.glb +0 -0
  130. cuju/render/web/assets/hair_medium01.glb +0 -0
  131. cuju/render/web/assets/hair_red.png +0 -0
  132. cuju/render/web/assets/hair_short01.glb +0 -0
  133. cuju/render/web/assets/hair_short02.glb +0 -0
  134. cuju/render/web/assets/icons/cuju-192.png +0 -0
  135. cuju/render/web/assets/icons/cuju-512.png +0 -0
  136. cuju/render/web/assets/icons/cuju-maskable-512.png +0 -0
  137. cuju/render/web/assets/kit_goalkeeper.webp +0 -0
  138. cuju/render/web/assets/kit_mask.png +0 -0
  139. cuju/render/web/assets/kit_normal.webp +0 -0
  140. cuju/render/web/assets/manifest.json +601 -0
  141. cuju/render/web/assets/models/kaykit-barbarian.glb +0 -0
  142. cuju/render/web/assets/models/kaykit-barbarian.json +23 -0
  143. cuju/render/web/assets/models/kaykit-knight.glb +0 -0
  144. cuju/render/web/assets/models/kaykit-knight.json +23 -0
  145. cuju/render/web/assets/models/kaykit-mage.glb +0 -0
  146. cuju/render/web/assets/models/kaykit-mage.json +23 -0
  147. cuju/render/web/assets/models/kaykit-mannequin-medium.glb +0 -0
  148. cuju/render/web/assets/models/kaykit-mannequin-medium.json +23 -0
  149. cuju/render/web/assets/models/kaykit-ranger.glb +0 -0
  150. cuju/render/web/assets/models/kaykit-ranger.json +23 -0
  151. cuju/render/web/assets/models/kaykit-rogue-hooded.glb +0 -0
  152. cuju/render/web/assets/models/kaykit-rogue-hooded.json +23 -0
  153. cuju/render/web/assets/models/kaykit-rogue.glb +0 -0
  154. cuju/render/web/assets/models/kaykit-rogue.json +23 -0
  155. cuju/render/web/assets/models/kaykit-skeleton-mage.glb +0 -0
  156. cuju/render/web/assets/models/kaykit-skeleton-mage.json +23 -0
  157. cuju/render/web/assets/models/kaykit-skeleton-minion.glb +0 -0
  158. cuju/render/web/assets/models/kaykit-skeleton-minion.json +23 -0
  159. cuju/render/web/assets/models/kaykit-skeleton-rogue.glb +0 -0
  160. cuju/render/web/assets/models/kaykit-skeleton-rogue.json +23 -0
  161. cuju/render/web/assets/models/kaykit-skeleton-warrior.glb +0 -0
  162. cuju/render/web/assets/models/kaykit-skeleton-warrior.json +23 -0
  163. cuju/render/web/assets/pitch.webp +0 -0
  164. cuju/render/web/assets/pitch_normal.webp +0 -0
  165. cuju/render/web/assets/player.glb +0 -0
  166. cuju/render/web/assets/shoe.webp +0 -0
  167. cuju/render/web/assets/shoe_sole.png +0 -0
  168. cuju/render/web/assets/skin_01.png +0 -0
  169. cuju/render/web/assets/skin_02.png +0 -0
  170. cuju/render/web/assets/skin_03.png +0 -0
  171. cuju/render/web/assets/skin_04.png +0 -0
  172. cuju/render/web/assets/sounds/applause.ogg +0 -0
  173. cuju/render/web/assets/sounds/beach-wave-1.ogg +0 -0
  174. cuju/render/web/assets/sounds/beach-wave-2.ogg +0 -0
  175. cuju/render/web/assets/sounds/beach-wave-3.ogg +0 -0
  176. cuju/render/web/assets/sounds/beach-wave-4.ogg +0 -0
  177. cuju/render/web/assets/sounds/city-horn.ogg +0 -0
  178. cuju/render/web/assets/sounds/city-loop.ogg +0 -0
  179. cuju/render/web/assets/sounds/city-siren.ogg +0 -0
  180. cuju/render/web/assets/sounds/crowd-cheer.ogg +0 -0
  181. cuju/render/web/assets/sounds/crowd-loop.ogg +0 -0
  182. cuju/render/web/assets/sounds/crowd-ooh.ogg +0 -0
  183. cuju/render/web/assets/sounds/gulls.ogg +0 -0
  184. cuju/render/web/assets/sounds/neon-sting.ogg +0 -0
  185. cuju/render/web/assets/sounds/rain-loop.ogg +0 -0
  186. cuju/render/web/assets/sounds/sounds.json +46 -0
  187. cuju/render/web/assets/sounds/space-beep.ogg +0 -0
  188. cuju/render/web/assets/sounds/space-hum.ogg +0 -0
  189. cuju/render/web/assets/sounds/space-radio.ogg +0 -0
  190. cuju/render/web/assets/sounds/whistle-long.ogg +0 -0
  191. cuju/render/web/assets/sounds/whistle-short.ogg +0 -0
  192. cuju/render/web/assets/sounds/wind-loop.ogg +0 -0
  193. cuju/render/web/easy.css +357 -0
  194. cuju/render/web/export.html +23 -0
  195. cuju/render/web/feed.css +262 -0
  196. cuju/render/web/feed.html +28 -0
  197. cuju/render/web/flat.css +120 -0
  198. cuju/render/web/home.css +837 -0
  199. cuju/render/web/index.html +373 -0
  200. cuju/render/web/js/boot.js +50 -0
  201. cuju/render/web/js/broadcast/audio.js +2141 -0
  202. cuju/render/web/js/broadcast/celebrate.js +1238 -0
  203. cuju/render/web/js/broadcast/decisions.js +609 -0
  204. cuju/render/web/js/broadcast/hud.js +352 -0
  205. cuju/render/web/js/broadcast/show.js +3614 -0
  206. cuju/render/web/js/broadcast/transition.js +2231 -0
  207. cuju/render/web/js/broadcast/voices.js +153 -0
  208. cuju/render/web/js/capture.js +101 -0
  209. cuju/render/web/js/core/accessibility.js +90 -0
  210. cuju/render/web/js/core/api.js +429 -0
  211. cuju/render/web/js/core/comfort.js +135 -0
  212. cuju/render/web/js/core/i18n.js +705 -0
  213. cuju/render/web/js/core/icons.js +167 -0
  214. cuju/render/web/js/core/input-settings.js +156 -0
  215. cuju/render/web/js/core/keys.js +277 -0
  216. cuju/render/web/js/core/language-ui.js +125 -0
  217. cuju/render/web/js/core/menu.js +853 -0
  218. cuju/render/web/js/core/names.js +113 -0
  219. cuju/render/web/js/core/page-structure.js +110 -0
  220. cuju/render/web/js/core/scenarios.js +109 -0
  221. cuju/render/web/js/core/spoilers.js +236 -0
  222. cuju/render/web/js/core/typeahead.js +38 -0
  223. cuju/render/web/js/export/dom-picture.js +330 -0
  224. cuju/render/web/js/export/export-host.js +97 -0
  225. cuju/render/web/js/export/feed-dialog.js +191 -0
  226. cuju/render/web/js/export/feed-params.js +266 -0
  227. cuju/render/web/js/export/feed.js +363 -0
  228. cuju/render/web/js/export/mp4-mux.js +295 -0
  229. cuju/render/web/js/export/photo-core.js +313 -0
  230. cuju/render/web/js/export/photo.js +1314 -0
  231. cuju/render/web/js/export/safe-frame.js +59 -0
  232. cuju/render/web/js/export/size-fields.js +103 -0
  233. cuju/render/web/js/export/sizes.js +178 -0
  234. cuju/render/web/js/export/video-boot.js +55 -0
  235. cuju/render/web/js/export/video-browser.js +325 -0
  236. cuju/render/web/js/export/video-export.js +417 -0
  237. cuju/render/web/js/export/video-plan.js +207 -0
  238. cuju/render/web/js/export/video-range.js +185 -0
  239. cuju/render/web/js/export/webm-mux.js +198 -0
  240. cuju/render/web/js/feed-boot.js +151 -0
  241. cuju/render/web/js/feed-frame.js +101 -0
  242. cuju/render/web/js/help/doctor.js +488 -0
  243. cuju/render/web/js/help/firstrun.js +379 -0
  244. cuju/render/web/js/help/help-center.js +438 -0
  245. cuju/render/web/js/help/install-offer.js +164 -0
  246. cuju/render/web/js/help/install-state.js +104 -0
  247. cuju/render/web/js/help/lessons-core.js +207 -0
  248. cuju/render/web/js/help/lessons.js +463 -0
  249. cuju/render/web/js/help/palette.js +584 -0
  250. cuju/render/web/js/help/pwa.js +257 -0
  251. cuju/render/web/js/help/tour-core.js +241 -0
  252. cuju/render/web/js/help/tour.js +461 -0
  253. cuju/render/web/js/main.js +2513 -0
  254. cuju/render/web/js/pages/draw.js +188 -0
  255. cuju/render/web/js/pages/fieldpage.js +530 -0
  256. cuju/render/web/js/pages/home.js +521 -0
  257. cuju/render/web/js/pages/matches.js +779 -0
  258. cuju/render/web/js/pages/moments-ui.js +359 -0
  259. cuju/render/web/js/pages/queue-filters.js +63 -0
  260. cuju/render/web/js/pages/recording-groups.js +80 -0
  261. cuju/render/web/js/pages/recordings.js +1069 -0
  262. cuju/render/web/js/play/bench.js +347 -0
  263. cuju/render/web/js/play/challenges.js +1302 -0
  264. cuju/render/web/js/play/medals.js +127 -0
  265. cuju/render/web/js/play/play.js +1953 -0
  266. cuju/render/web/js/play/teasers.js +196 -0
  267. cuju/render/web/js/play/touch.js +350 -0
  268. cuju/render/web/js/play/tournament-layout.js +487 -0
  269. cuju/render/web/js/play/tournament-results.js +441 -0
  270. cuju/render/web/js/play/tournament-strict.js +560 -0
  271. cuju/render/web/js/play/tournament.js +2585 -0
  272. cuju/render/web/js/players/animate.js +972 -0
  273. cuju/render/web/js/players/clips.js +224 -0
  274. cuju/render/web/js/players/kaykit.js +162 -0
  275. cuju/render/web/js/players/kits.js +676 -0
  276. cuju/render/web/js/players/number-patch.js +82 -0
  277. cuju/render/web/js/players/players.js +2694 -0
  278. cuju/render/web/js/players/recolor.js +893 -0
  279. cuju/render/web/js/players/retarget.js +325 -0
  280. cuju/render/web/js/players/rig-numbers.js +174 -0
  281. cuju/render/web/js/presentation/animator.js +231 -0
  282. cuju/render/web/js/presentation/assign.js +85 -0
  283. cuju/render/web/js/presentation/behaviors.js +440 -0
  284. cuju/render/web/js/presentation/budget.js +209 -0
  285. cuju/render/web/js/presentation/catalog.js +1674 -0
  286. cuju/render/web/js/presentation/clocks.js +72 -0
  287. cuju/render/web/js/presentation/commands.js +301 -0
  288. cuju/render/web/js/presentation/contract.js +240 -0
  289. cuju/render/web/js/presentation/effects.js +904 -0
  290. cuju/render/web/js/presentation/flash.js +605 -0
  291. cuju/render/web/js/presentation/freeze-worklet.js +22 -0
  292. cuju/render/web/js/presentation/glsl.js +464 -0
  293. cuju/render/web/js/presentation/host.js +323 -0
  294. cuju/render/web/js/presentation/index.js +2066 -0
  295. cuju/render/web/js/presentation/loudness-worklet.js +235 -0
  296. cuju/render/web/js/presentation/loudness.js +740 -0
  297. cuju/render/web/js/presentation/moments.js +536 -0
  298. cuju/render/web/js/presentation/post.js +327 -0
  299. cuju/render/web/js/presentation/preview.js +180 -0
  300. cuju/render/web/js/presentation/protocol.js +174 -0
  301. cuju/render/web/js/presentation/reach.js +158 -0
  302. cuju/render/web/js/presentation/rigging.js +130 -0
  303. cuju/render/web/js/presentation/sandbox.js +157 -0
  304. cuju/render/web/js/presentation/shaders.js +235 -0
  305. cuju/render/web/js/presentation/stage.js +402 -0
  306. cuju/render/web/js/presentation/teamaudio.js +722 -0
  307. cuju/render/web/js/presentation/tracks.js +197 -0
  308. cuju/render/web/js/presentation/values.js +81 -0
  309. cuju/render/web/js/recording/annotation-data.js +203 -0
  310. cuju/render/web/js/recording/captions.js +491 -0
  311. cuju/render/web/js/recording/codec.js +185 -0
  312. cuju/render/web/js/recording/decode-worker.js +70 -0
  313. cuju/render/web/js/recording/decode.js +94 -0
  314. cuju/render/web/js/recording/episodes.js +46 -0
  315. cuju/render/web/js/recording/format.js +461 -0
  316. cuju/render/web/js/recording/live.js +348 -0
  317. cuju/render/web/js/recording/moments-query.js +59 -0
  318. cuju/render/web/js/recording/moments.js +149 -0
  319. cuju/render/web/js/recording/pose.js +86 -0
  320. cuju/render/web/js/recording/timeline.js +275 -0
  321. cuju/render/web/js/teams/art.js +50 -0
  322. cuju/render/web/js/teams/clip-editor.js +293 -0
  323. cuju/render/web/js/teams/editor.js +1979 -0
  324. cuju/render/web/js/teams/library.js +344 -0
  325. cuju/render/web/js/teams/painter.js +633 -0
  326. cuju/render/web/js/teams/surprise-ui.js +195 -0
  327. cuju/render/web/js/teams/surprise.js +497 -0
  328. cuju/render/web/js/teams/team-check.js +127 -0
  329. cuju/render/web/js/watch/annotations.js +270 -0
  330. cuju/render/web/js/watch/flat.js +366 -0
  331. cuju/render/web/js/watch/grid.js +436 -0
  332. cuju/render/web/js/watch/pitch2d.js +289 -0
  333. cuju/render/web/js/watch/player-tools.js +192 -0
  334. cuju/render/web/js/watch/presets.js +201 -0
  335. cuju/render/web/js/world/arenas.js +997 -0
  336. cuju/render/web/js/world/ball.js +204 -0
  337. cuju/render/web/js/world/cameras.js +982 -0
  338. cuju/render/web/js/world/crowd.js +376 -0
  339. cuju/render/web/js/world/field.js +227 -0
  340. cuju/render/web/js/world/framing.js +145 -0
  341. cuju/render/web/js/world/occlusion.js +48 -0
  342. cuju/render/web/js/world/pitch.js +703 -0
  343. cuju/render/web/js/world/scene.js +395 -0
  344. cuju/render/web/js/world/sky.js +325 -0
  345. cuju/render/web/js/world/stadium.js +1262 -0
  346. cuju/render/web/js/world/vendor-sky.js +367 -0
  347. cuju/render/web/js/world/weather.js +264 -0
  348. cuju/render/web/languages/en.json +4750 -0
  349. cuju/render/web/lessons.json +137 -0
  350. cuju/render/web/manifest.webmanifest +23 -0
  351. cuju/render/web/style.css +8399 -0
  352. cuju/render/web/sw.js +235 -0
  353. cuju/render/web/vendor/fabric/LICENSE +16 -0
  354. cuju/render/web/vendor/fabric/fabric.min.mjs +1 -0
  355. cuju/render/web/vendor/lucide/LICENSE +43 -0
  356. cuju/render/web/vendor/lucide/icons.js +141 -0
  357. cuju/render/web/vendor/three/LICENSE +21 -0
  358. cuju/render/web/vendor/three/build/three.core.js +60586 -0
  359. cuju/render/web/vendor/three/build/three.module.js +19719 -0
  360. cuju/render/web/vendor/three/examples/jsm/loaders/GLTFLoader.js +4925 -0
  361. cuju/render/web/vendor/three/examples/jsm/postprocessing/EffectComposer.js +365 -0
  362. cuju/render/web/vendor/three/examples/jsm/postprocessing/MaskPass.js +195 -0
  363. cuju/render/web/vendor/three/examples/jsm/postprocessing/OutputPass.js +148 -0
  364. cuju/render/web/vendor/three/examples/jsm/postprocessing/Pass.js +191 -0
  365. cuju/render/web/vendor/three/examples/jsm/postprocessing/RenderPass.js +193 -0
  366. cuju/render/web/vendor/three/examples/jsm/postprocessing/ShaderPass.js +135 -0
  367. cuju/render/web/vendor/three/examples/jsm/postprocessing/UnrealBloomPass.js +541 -0
  368. cuju/render/web/vendor/three/examples/jsm/shaders/CopyShader.js +52 -0
  369. cuju/render/web/vendor/three/examples/jsm/shaders/LuminosityHighPassShader.js +68 -0
  370. cuju/render/web/vendor/three/examples/jsm/shaders/OutputShader.js +103 -0
  371. cuju/render/web/vendor/three/examples/jsm/utils/BufferGeometryUtils.js +1501 -0
  372. cuju/render/web/vendor/three/examples/jsm/utils/SkeletonUtils.js +496 -0
  373. cuju_render-0.1.0.dist-info/METADATA +116 -0
  374. cuju_render-0.1.0.dist-info/RECORD +382 -0
  375. cuju_render-0.1.0.dist-info/WHEEL +4 -0
  376. cuju_render-0.1.0.dist-info/licenses/LICENSE +202 -0
  377. cuju_render-0.1.0.dist-info/licenses/LICENSES/CC-BY-4.0.txt +396 -0
  378. cuju_render-0.1.0.dist-info/licenses/LICENSES/CC0-1.0.txt +127 -0
  379. cuju_render-0.1.0.dist-info/licenses/LICENSES/ISC.txt +16 -0
  380. cuju_render-0.1.0.dist-info/licenses/LICENSES/MIT.txt +24 -0
  381. cuju_render-0.1.0.dist-info/licenses/LICENSES/Unlicense.txt +13 -0
  382. cuju_render-0.1.0.dist-info/licenses/NOTICE +35 -0
@@ -0,0 +1,79 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ """Shows the viewer inside a notebook of Jupyter or Google Colab.
5
+
6
+ The environment is read from the modules that the process has already loaded, so a script or a
7
+ terminal never imports IPython or Colab. Jupyter shows the page of the local server in a frame,
8
+ and Colab serves it through its own proxy, which carries the page from the machine of the notebook
9
+ to the browser of the person who uses it.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import html
15
+ import importlib
16
+ import sys
17
+ from typing import Any
18
+
19
+ # The text of the link that opens the viewer at full size.
20
+ FULL_SIZE = 'Open the viewer full size'
21
+
22
+
23
+ def environment() -> str | None:
24
+ """Returns `colab` or `jupyter` inside a notebook of either, and `None` elsewhere.
25
+
26
+ The terminal of IPython counts as no notebook, since a browser shows its pages.
27
+ """
28
+ ipython = sys.modules.get('IPython')
29
+ get = getattr(ipython, 'get_ipython', None)
30
+ shell = get() if callable(get) else None
31
+ if shell is None:
32
+ return None
33
+ kind = type(shell)
34
+ if kind.__module__.startswith('google.colab'):
35
+ return 'colab'
36
+ if kind.__name__ == 'ZMQInteractiveShell' or hasattr(shell, 'kernel'):
37
+ return 'colab' if 'google.colab' in sys.modules else 'jupyter'
38
+ return None
39
+
40
+
41
+ def execution_count() -> int | None:
42
+ """Returns the number of the cell that runs, or `None` outside IPython."""
43
+ ipython = sys.modules.get('IPython')
44
+ get = getattr(ipython, 'get_ipython', None)
45
+ shell = get() if callable(get) else None
46
+ count = getattr(shell, 'execution_count', None)
47
+ return count if isinstance(count, int) else None
48
+
49
+
50
+ def markup(frame: str, full: str, height: int) -> str:
51
+ """Returns the HTML of the viewer in a frame of `height` pixels, with a link to `full`."""
52
+ return (
53
+ '<div class="cuju-render">'
54
+ f'<iframe src="{html.escape(frame)}" width="100%" height="{int(height)}" '
55
+ 'style="border: 0" allow="autoplay; fullscreen" title="cuju viewer"></iframe>'
56
+ f'<p><a href="{html.escape(full)}" target="_blank" rel="noopener">{FULL_SIZE}</a></p>'
57
+ '</div>'
58
+ )
59
+
60
+
61
+ def display(kind: str, port: int, key: str, fragment: str, height: int) -> None:
62
+ """Shows the page of the server on `port` in the output of the running cell.
63
+
64
+ Args:
65
+ kind: `jupyter` or `colab`, as `environment` returns it.
66
+ port: The port of the server.
67
+ key: The key of the server, which lets the notebook frame the page.
68
+ fragment: The end of the address, from `#` on.
69
+ height: The height of the frame in pixels.
70
+ """
71
+ framed = f'/?embed={key}{fragment}'
72
+ if kind == 'colab':
73
+ output: Any = importlib.import_module('google.colab.output')
74
+ output.serve_kernel_port_as_iframe(port, path=framed, height=str(int(height)))
75
+ output.serve_kernel_port_as_window(port, path=f'/{fragment}', anchor_text=FULL_SIZE)
76
+ return
77
+ shown: Any = importlib.import_module('IPython.display')
78
+ base = f'http://127.0.0.1:{port}'
79
+ shown.display(shown.HTML(markup(base + framed, f'{base}/{fragment}', height)))
@@ -0,0 +1,171 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ """`show`, which opens the viewer on a batch, a recording or a live source in one call.
5
+
6
+ `show` reuses the server of the home folder or starts one in the background, gives a batch a live
7
+ source, and opens the page in the browser, or inline in a notebook of Jupyter or Google Colab.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import os
13
+ from typing import Any
14
+
15
+ from cuju.errors import ArgumentError
16
+
17
+ from .._http import launch as _launch
18
+ from . import notebook as _notebook
19
+ from .live import LiveSource
20
+
21
+ # The ways `show` may open the page.
22
+ _DISPLAYS = ('auto', 'browser', 'inline', 'none')
23
+
24
+
25
+ class View:
26
+ """The viewer that `show` opened, with its address and the live source it attached.
27
+
28
+ A view is a context manager, and leaving it closes the live source that `show` gave a batch,
29
+ while the server goes on.
30
+
31
+ Attributes:
32
+ url: The address of the page on this machine.
33
+ server: The server, with its `port` and its process `pid`.
34
+ source: The live source that the page shows, or `None` for a recording or the Home page.
35
+ """
36
+
37
+ def __init__(
38
+ self,
39
+ server: _launch.Server,
40
+ fragment: str,
41
+ source: LiveSource | None,
42
+ owned: bool,
43
+ height: int,
44
+ kind: str | None,
45
+ ) -> None:
46
+ self.server = server
47
+ self.url = fragment if '://' in fragment else server.url + fragment
48
+ self.source = source
49
+ self._fragment = fragment
50
+ self._owned = owned
51
+ self._height = height
52
+ self._kind = kind
53
+ # The cell that `show` displayed the view in, which the value of the cell shows again.
54
+ self._shown_in: int | None = None
55
+
56
+ def __repr__(self) -> str:
57
+ return f'View({self.url!r})'
58
+
59
+ def __enter__(self) -> View:
60
+ return self
61
+
62
+ def __exit__(self, *exception: object) -> None:
63
+ self.close()
64
+
65
+ def close(self) -> None:
66
+ """Closes the live source that `show` attached to a batch, and leaves any other one."""
67
+ if self._owned and self.source is not None:
68
+ self.source.close()
69
+
70
+ def display(self) -> None:
71
+ """Shows the viewer inline in the output of the running notebook cell."""
72
+ kind = self._kind or _notebook.environment()
73
+ if kind is None:
74
+ raise ArgumentError('expected a notebook of Jupyter or Google Colab to show the viewer')
75
+ if '://' in self._fragment:
76
+ raise ArgumentError(f'expected a page of this server, found {self._fragment}')
77
+ self._shown_in = _notebook.execution_count()
78
+ _notebook.display(kind, self.server.port, self.server.key, self._fragment, self._height)
79
+
80
+ def _ipython_display_(self) -> None:
81
+ # A view that `show` returns as the value of its own cell is already on screen, and the
82
+ # terminal of IPython prints the view's address.
83
+ if self._shown_in is not None and self._shown_in == _notebook.execution_count():
84
+ return
85
+ if (self._kind or _notebook.environment()) is None or '://' in self._fragment:
86
+ print(repr(self))
87
+ return
88
+ self.display()
89
+
90
+
91
+ def _fragment_of(
92
+ target: Any, environment: int, title: str | None, teams: Any
93
+ ) -> tuple[str, LiveSource | None, bool]:
94
+ """Returns the end of the page's address for `target`, its live source and whether `show`
95
+ attached that source."""
96
+ from .. import watch
97
+
98
+ if isinstance(target, LiveSource):
99
+ return f'#live={target.identifier}', target, False
100
+ if callable(getattr(target, 'add_observer', None)):
101
+ for observer in target.observers:
102
+ if isinstance(observer, LiveSource) and observer.environment == environment:
103
+ return f'#live={observer.identifier}', observer, False
104
+ source = watch(target, environment, title, teams)
105
+ return f'#live={source.identifier}', source, True
106
+ if target is None or isinstance(target, (str, os.PathLike)):
107
+ return _launch.resolve(target), None, False
108
+ raise ArgumentError(
109
+ 'expected a batch, a live source, a recording file, the identifier of a recording or None, '
110
+ f'found {type(target).__name__}; for a MultiDeviceBatch show one of its parts'
111
+ )
112
+
113
+
114
+ def show(
115
+ target: Any = None,
116
+ *,
117
+ environment: int = 0,
118
+ title: str | None = None,
119
+ teams: list[dict[str, Any]] | None = None,
120
+ display: str = 'auto',
121
+ port: int | None = None,
122
+ stay: bool = False,
123
+ height: int = 600,
124
+ ) -> View:
125
+ """Opens the viewer on a batch, a recording or a live source, starting the server when needed.
126
+
127
+ The server of the home folder answers when one runs, and otherwise `show` starts one in a
128
+ process of its own, which ends with this process unless `stay` is true. A batch receives a
129
+ live source of `environment`, or keeps the one it has, and the page opens on it. A recording
130
+ file outside the library is copied into it first.
131
+
132
+ Args:
133
+ target: A batch, a `LiveSource`, a `.cjr` file, the identifier of a recording or live
134
+ source, a URL of the page, or `None` for the Home page.
135
+ environment: The environment of a batch to show.
136
+ title: The title of a new live source, as for `watch`.
137
+ teams: The names and colors of the teams of a new live source, as for `watch`.
138
+ display: `auto` shows the viewer inline in a notebook of Jupyter or Colab and opens the
139
+ browser elsewhere, `browser` and `inline` choose one, and `none` opens nothing.
140
+ port: The port of a server that `show` starts, by default 8780 when it is free.
141
+ stay: Whether a server that `show` starts outlives this process.
142
+ height: The height of the inline viewer in pixels.
143
+
144
+ Returns:
145
+ The view, with the page's `url` and its live `source`. Leaving it as a context manager
146
+ closes a source that `show` attached.
147
+
148
+ Raises:
149
+ ArgumentError: If the target names nothing to show, or `display` is not one of the four.
150
+ """
151
+ if display not in _DISPLAYS:
152
+ raise ArgumentError(
153
+ f'expected display to be one of {", ".join(_DISPLAYS)}, found {display!r}'
154
+ )
155
+ fragment, source, owned = _fragment_of(target, environment, title, teams)
156
+ kind = _notebook.environment()
157
+ try:
158
+ server = _launch.start(port, stay, colab=kind == 'colab')
159
+ except BaseException:
160
+ if owned and source is not None:
161
+ source.close()
162
+ raise
163
+ view = View(server, fragment, source, owned, height, kind)
164
+ if display == 'auto':
165
+ display = 'inline' if kind is not None and '://' not in fragment else 'browser'
166
+ if display == 'inline':
167
+ view.display()
168
+ elif display == 'browser':
169
+ opened = _launch.open_browser(view.url)
170
+ print(f'cuju render {"opened" if opened else "serves"} {view.url}', flush=True)
171
+ return view
Binary file
Binary file
@@ -0,0 +1,33 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """The starter team, a Kaggle submission that cuju ships as a sample of a team.
4
+
5
+ `agent(obs)` is written as the agent of a Kaggle `main.py` for the GRF competition. It reads
6
+ `obs['players_raw'][0]`, GRF's raw observation of the player it controls, and returns a list of one
7
+ action of the default action set. The player runs at the ball, carries it toward the right goal and
8
+ shoots from close range. Copy this folder to start a team of your own.
9
+ """
10
+
11
+ import math
12
+
13
+ # The directions of GRF's default action set, from the right in steps of 45 degrees toward the
14
+ # bottom, since y grows toward the bottom of the pitch.
15
+ DIRECTIONS = [5, 6, 7, 8, 1, 2, 3, 4]
16
+ SHOT = 12
17
+
18
+
19
+ def direction(dx, dy):
20
+ """Returns the action that runs closest to the direction `(dx, dy)`."""
21
+ return DIRECTIONS[round(math.atan2(dy, dx) / (math.pi / 4)) % 8]
22
+
23
+
24
+ def agent(obs):
25
+ """Returns the action of the player of `obs`, as a Kaggle agent does."""
26
+ raw = obs['players_raw'][0]
27
+ x, y = raw['left_team'][raw['active']]
28
+ ball = raw['ball']
29
+ if raw['ball_owned_team'] == 0 and raw['ball_owned_player'] == raw['active']:
30
+ if x > 0.7 and abs(y) < 0.25:
31
+ return [SHOT]
32
+ return [direction(1.0 - x, -y)]
33
+ return [direction(ball[0] - x, ball[1] - y)]
@@ -0,0 +1,46 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # Copyright 2019 Google LLC
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ # Adapted from GRF and GRF_MARL by Light-MALib.
5
+ # https://github.com/jidiai/GRF_MARL
6
+ # ruff: noqa: F403, F405
7
+
8
+ from . import *
9
+
10
+
11
+ def build_scenario(builder):
12
+ builder.config().game_duration = 3000
13
+ builder.config().second_half = 1500
14
+ builder.config().right_team_difficulty = 0.05
15
+ builder.config().left_team_difficulty = 0.05
16
+ builder.config().deterministic = False
17
+ if builder.EpisodeNumber() % 2 == 0:
18
+ first_team = Team.e_Left
19
+ second_team = Team.e_Right
20
+ else:
21
+ first_team = Team.e_Right
22
+ second_team = Team.e_Left
23
+ builder.SetTeam(first_team)
24
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
25
+ builder.AddPlayer(-0.422000, -0.19576, e_PlayerRole_LB)
26
+ builder.AddPlayer(-0.500000, -0.06356, e_PlayerRole_CB)
27
+ builder.AddPlayer(-0.500000, 0.063559, e_PlayerRole_CB)
28
+ builder.AddPlayer(-0.422000, 0.195760, e_PlayerRole_RB)
29
+ builder.AddPlayer(-0.184212, -0.105680, e_PlayerRole_CM)
30
+ builder.AddPlayer(-0.267574, 0.000000, e_PlayerRole_CM)
31
+ builder.AddPlayer(-0.184212, 0.10568, e_PlayerRole_CM)
32
+ builder.AddPlayer(-0.010000, -0.21610, e_PlayerRole_LM)
33
+ builder.AddPlayer(0.000000, 0.020000, e_PlayerRole_CF)
34
+ builder.AddPlayer(0.000000, -0.020000, e_PlayerRole_RM)
35
+ builder.SetTeam(second_team)
36
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
37
+ builder.AddPlayer(-0.422000, -0.19576, e_PlayerRole_LB)
38
+ builder.AddPlayer(-0.500000, -0.06356, e_PlayerRole_CB)
39
+ builder.AddPlayer(-0.500000, 0.063559, e_PlayerRole_CB)
40
+ builder.AddPlayer(-0.422000, 0.195760, e_PlayerRole_RB)
41
+ builder.AddPlayer(-0.184212, -0.105680, e_PlayerRole_CM)
42
+ builder.AddPlayer(-0.267574, 0.000000, e_PlayerRole_CM)
43
+ builder.AddPlayer(-0.184212, 0.10568, e_PlayerRole_CM)
44
+ builder.AddPlayer(-0.010000, -0.21610, e_PlayerRole_LM)
45
+ builder.AddPlayer(-0.050000, 0.000000, e_PlayerRole_CF)
46
+ builder.AddPlayer(-0.010000, 0.216102, e_PlayerRole_RM)
@@ -0,0 +1,46 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # Copyright 2019 Google LLC
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ # Adapted from GRF and GRF_MARL by Light-MALib.
5
+ # https://github.com/jidiai/GRF_MARL
6
+ # ruff: noqa: F403, F405
7
+
8
+ from . import *
9
+
10
+
11
+ def build_scenario(builder):
12
+ builder.config().game_duration = 3000
13
+ builder.config().second_half = 1500
14
+ builder.config().right_team_difficulty = 1.0
15
+ builder.config().left_team_difficulty = 1.0
16
+ builder.config().deterministic = False
17
+ if builder.EpisodeNumber() % 2 == 0:
18
+ first_team = Team.e_Left
19
+ second_team = Team.e_Right
20
+ else:
21
+ first_team = Team.e_Right
22
+ second_team = Team.e_Left
23
+ builder.SetTeam(first_team)
24
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
25
+ builder.AddPlayer(-0.422000, -0.19576, e_PlayerRole_LB)
26
+ builder.AddPlayer(-0.500000, -0.06356, e_PlayerRole_CB)
27
+ builder.AddPlayer(-0.500000, 0.063559, e_PlayerRole_CB)
28
+ builder.AddPlayer(-0.422000, 0.195760, e_PlayerRole_RB)
29
+ builder.AddPlayer(-0.184212, -0.105680, e_PlayerRole_CM)
30
+ builder.AddPlayer(-0.267574, 0.000000, e_PlayerRole_CM)
31
+ builder.AddPlayer(-0.184212, 0.10568, e_PlayerRole_CM)
32
+ builder.AddPlayer(-0.010000, -0.21610, e_PlayerRole_LM)
33
+ builder.AddPlayer(0.000000, 0.020000, e_PlayerRole_CF)
34
+ builder.AddPlayer(0.000000, -0.020000, e_PlayerRole_RM)
35
+ builder.SetTeam(second_team)
36
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
37
+ builder.AddPlayer(-0.422000, -0.19576, e_PlayerRole_LB)
38
+ builder.AddPlayer(-0.500000, -0.06356, e_PlayerRole_CB)
39
+ builder.AddPlayer(-0.500000, 0.063559, e_PlayerRole_CB)
40
+ builder.AddPlayer(-0.422000, 0.195760, e_PlayerRole_RB)
41
+ builder.AddPlayer(-0.184212, -0.105680, e_PlayerRole_CM)
42
+ builder.AddPlayer(-0.267574, 0.000000, e_PlayerRole_CM)
43
+ builder.AddPlayer(-0.184212, 0.10568, e_PlayerRole_CM)
44
+ builder.AddPlayer(-0.010000, -0.21610, e_PlayerRole_LM)
45
+ builder.AddPlayer(-0.050000, 0.000000, e_PlayerRole_CF)
46
+ builder.AddPlayer(-0.010000, 0.216102, e_PlayerRole_RM)
@@ -0,0 +1,46 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # Copyright 2019 Google LLC
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ # Adapted from GRF and GRF_MARL by Light-MALib.
5
+ # https://github.com/jidiai/GRF_MARL
6
+ # ruff: noqa: F403, F405
7
+
8
+ from . import *
9
+
10
+
11
+ def build_scenario(builder):
12
+ builder.config().game_duration = 3000
13
+ builder.config().second_half = 1500
14
+ builder.config().right_team_difficulty = 0.6
15
+ builder.config().left_team_difficulty = 0.6
16
+ builder.config().deterministic = False
17
+ if builder.EpisodeNumber() % 2 == 0:
18
+ first_team = Team.e_Left
19
+ second_team = Team.e_Right
20
+ else:
21
+ first_team = Team.e_Right
22
+ second_team = Team.e_Left
23
+ builder.SetTeam(first_team)
24
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
25
+ builder.AddPlayer(-0.422000, -0.19576, e_PlayerRole_LB)
26
+ builder.AddPlayer(-0.500000, -0.06356, e_PlayerRole_CB)
27
+ builder.AddPlayer(-0.500000, 0.063559, e_PlayerRole_CB)
28
+ builder.AddPlayer(-0.422000, 0.195760, e_PlayerRole_RB)
29
+ builder.AddPlayer(-0.184212, -0.105680, e_PlayerRole_CM)
30
+ builder.AddPlayer(-0.267574, 0.000000, e_PlayerRole_CM)
31
+ builder.AddPlayer(-0.184212, 0.10568, e_PlayerRole_CM)
32
+ builder.AddPlayer(-0.010000, -0.21610, e_PlayerRole_LM)
33
+ builder.AddPlayer(0.000000, 0.020000, e_PlayerRole_CF)
34
+ builder.AddPlayer(0.000000, -0.020000, e_PlayerRole_RM)
35
+ builder.SetTeam(second_team)
36
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
37
+ builder.AddPlayer(-0.422000, -0.19576, e_PlayerRole_LB)
38
+ builder.AddPlayer(-0.500000, -0.06356, e_PlayerRole_CB)
39
+ builder.AddPlayer(-0.500000, 0.063559, e_PlayerRole_CB)
40
+ builder.AddPlayer(-0.422000, 0.195760, e_PlayerRole_RB)
41
+ builder.AddPlayer(-0.184212, -0.105680, e_PlayerRole_CM)
42
+ builder.AddPlayer(-0.267574, 0.000000, e_PlayerRole_CM)
43
+ builder.AddPlayer(-0.184212, 0.10568, e_PlayerRole_CM)
44
+ builder.AddPlayer(-0.010000, -0.21610, e_PlayerRole_LM)
45
+ builder.AddPlayer(-0.050000, 0.000000, e_PlayerRole_CF)
46
+ builder.AddPlayer(-0.010000, 0.216102, e_PlayerRole_RM)
@@ -0,0 +1,34 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # Copyright 2019 Google LLC
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ # Adapted from GRF and GRF_MARL by Light-MALib.
5
+ # https://github.com/jidiai/GRF_MARL
6
+ # ruff: noqa: F403, F405
7
+
8
+ from . import *
9
+
10
+
11
+ def build_scenario(builder):
12
+ builder.config().game_duration = 3000
13
+ builder.config().second_half = 1500
14
+ builder.config().right_team_difficulty = 0.05
15
+ builder.config().left_team_difficulty = 0.05
16
+ builder.config().deterministic = False
17
+ if builder.EpisodeNumber() % 2 == 0:
18
+ first_team = Team.e_Left
19
+ second_team = Team.e_Right
20
+ else:
21
+ first_team = Team.e_Right
22
+ second_team = Team.e_Left
23
+ builder.SetTeam(first_team)
24
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
25
+ builder.AddPlayer(0.000000, 0.020000, e_PlayerRole_RM)
26
+ builder.AddPlayer(0.000000, -0.020000, e_PlayerRole_CF)
27
+ builder.AddPlayer(-0.1, -0.1, e_PlayerRole_LB)
28
+ builder.AddPlayer(-0.1, 0.1, e_PlayerRole_CB)
29
+ builder.SetTeam(second_team)
30
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
31
+ builder.AddPlayer(-0.04, 0.040000, e_PlayerRole_RM)
32
+ builder.AddPlayer(-0.04, -0.040000, e_PlayerRole_CF)
33
+ builder.AddPlayer(-0.1, -0.1, e_PlayerRole_LB)
34
+ builder.AddPlayer(-0.1, 0.1, e_PlayerRole_CB)
@@ -0,0 +1,34 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # Copyright 2019 Google LLC
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ # Adapted from GRF and GRF_MARL by Light-MALib.
5
+ # https://github.com/jidiai/GRF_MARL
6
+ # ruff: noqa: F403, F405
7
+
8
+ from . import *
9
+
10
+
11
+ def build_scenario(builder):
12
+ builder.config().game_duration = 3000
13
+ builder.config().second_half = 1500
14
+ builder.config().right_team_difficulty = 1.0
15
+ builder.config().left_team_difficulty = 1.0
16
+ builder.config().deterministic = False
17
+ if builder.EpisodeNumber() % 2 == 0:
18
+ first_team = Team.e_Left
19
+ second_team = Team.e_Right
20
+ else:
21
+ first_team = Team.e_Right
22
+ second_team = Team.e_Left
23
+ builder.SetTeam(first_team)
24
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
25
+ builder.AddPlayer(0.000000, 0.020000, e_PlayerRole_RM)
26
+ builder.AddPlayer(0.000000, -0.020000, e_PlayerRole_CF)
27
+ builder.AddPlayer(-0.1, -0.1, e_PlayerRole_LB)
28
+ builder.AddPlayer(-0.1, 0.1, e_PlayerRole_CB)
29
+ builder.SetTeam(second_team)
30
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
31
+ builder.AddPlayer(-0.04, 0.040000, e_PlayerRole_RM)
32
+ builder.AddPlayer(-0.04, -0.040000, e_PlayerRole_CF)
33
+ builder.AddPlayer(-0.1, -0.1, e_PlayerRole_LB)
34
+ builder.AddPlayer(-0.1, 0.1, e_PlayerRole_CB)
@@ -0,0 +1,34 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # Copyright 2019 Google LLC
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ # Adapted from GRF and GRF_MARL by Light-MALib.
5
+ # https://github.com/jidiai/GRF_MARL
6
+ # ruff: noqa: F403, F405
7
+
8
+ from . import *
9
+
10
+
11
+ def build_scenario(builder):
12
+ builder.config().game_duration = 3000
13
+ builder.config().second_half = 1500
14
+ builder.config().right_team_difficulty = 0.6
15
+ builder.config().left_team_difficulty = 0.6
16
+ builder.config().deterministic = False
17
+ if builder.EpisodeNumber() % 2 == 0:
18
+ first_team = Team.e_Left
19
+ second_team = Team.e_Right
20
+ else:
21
+ first_team = Team.e_Right
22
+ second_team = Team.e_Left
23
+ builder.SetTeam(first_team)
24
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
25
+ builder.AddPlayer(0.000000, 0.020000, e_PlayerRole_RM)
26
+ builder.AddPlayer(0.000000, -0.020000, e_PlayerRole_CF)
27
+ builder.AddPlayer(-0.1, -0.1, e_PlayerRole_LB)
28
+ builder.AddPlayer(-0.1, 0.1, e_PlayerRole_CB)
29
+ builder.SetTeam(second_team)
30
+ builder.AddPlayer(-1.000000, 0.000000, e_PlayerRole_GK, False, False)
31
+ builder.AddPlayer(-0.04, 0.040000, e_PlayerRole_RM)
32
+ builder.AddPlayer(-0.04, -0.040000, e_PlayerRole_CF)
33
+ builder.AddPlayer(-0.1, -0.1, e_PlayerRole_LB)
34
+ builder.AddPlayer(-0.1, 0.1, e_PlayerRole_CB)
Binary file