mc-shell 0.6.6__py3-none-any.whl → 0.6.8__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 (43) hide show
  1. {mc_shell-0.6.6.dist-info → mc_shell-0.6.8.dist-info}/METADATA +1 -1
  2. {mc_shell-0.6.6.dist-info → mc_shell-0.6.8.dist-info}/RECORD +38 -29
  3. {mc_shell-0.6.6.dist-info → mc_shell-0.6.8.dist-info}/WHEEL +1 -1
  4. mcshell/Matrix3.py +45 -46
  5. mcshell/__init__.py +52 -14
  6. mcshell/constants.py +10 -0
  7. mcshell/data/app/index.html +38 -5
  8. mcshell/data/app/mced.55f94dd4.css +2 -0
  9. mcshell/data/app/mced.55f94dd4.css.map +1 -0
  10. mcshell/data/app/{mced.0c019c78.js → mced.aa2df54f.js} +90 -89
  11. mcshell/data/app/mced.aa2df54f.js.map +1 -0
  12. mcshell/data/app/mced.efd4d8e7.css +13 -0
  13. mcshell/data/app/mced.efd4d8e7.css.map +1 -0
  14. mcshell/data/app/{toolbox.f17a15a5.xml → toolbox.57f1313e.xml} +20 -13
  15. mcshell/data/datapacks/flat_world/data/minecraft/dimension/overworld.json +17 -0
  16. mcshell/data/datapacks/flat_world/data/minecraft/worldgen/biome/the_void.json +28 -0
  17. mcshell/data/datapacks/flat_world/pack.mcmeta +6 -0
  18. mcshell/data/datapacks/void_world/data/minecraft/dimension/overworld.json +17 -0
  19. mcshell/data/datapacks/void_world/data/minecraft/functions/init.mcfunction +4 -0
  20. mcshell/data/datapacks/void_world/data/minecraft/tags/functions/load.json +5 -0
  21. mcshell/data/datapacks/void_world/data/minecraft/worldgen/biome/the_void.json +28 -0
  22. mcshell/data/datapacks/void_world/pack.mcmeta +6 -0
  23. mcshell/data/materials/colourables.json +137 -137
  24. mcshell/data/materials/pickers.json +156 -156
  25. mcshell/mcactions.py +155 -47
  26. mcshell/mcactions_base.py +50 -9
  27. mcshell/mcblockly.py +12 -3
  28. mcshell/mcexperience_base.py +0 -0
  29. mcshell/mcplayer.py +122 -14
  30. mcshell/mcserver.py +8 -7
  31. mcshell/mcturtle.py +210 -189
  32. mcshell/mcvoxel_original.py +1 -1
  33. mcshell/ppdownloader.py +112 -121
  34. mcshell/ppmanager.py +101 -187
  35. mcshell/pyncactions.py +11 -6
  36. mcshell/vendored/pyncraft/minecraft.py +6 -8
  37. mcshell/data/app/mced.0c019c78.js.map +0 -1
  38. mcshell/data/app/mced.9b908af4.css +0 -2
  39. mcshell/data/app/mced.9b908af4.css.map +0 -1
  40. mcshell/data/app/mced.b6ed8b22.css +0 -2
  41. mcshell/data/app/mced.b6ed8b22.css.map +0 -1
  42. {mc_shell-0.6.6.dist-info → mc_shell-0.6.8.dist-info}/entry_points.txt +0 -0
  43. {mc_shell-0.6.6.dist-info → mc_shell-0.6.8.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mc-shell
3
- Version: 0.6.6
3
+ Version: 0.6.8
4
4
  Summary: An interactive shell and editor for controlling Minecraft servers and creating powers.
5
5
  License-File: LICENSE
6
6
  Author: Jeff
@@ -1,10 +1,10 @@
1
- mcshell/Matrix3.py,sha256=To40uU8ueBIMDLCEn-8Bs1v7hFhhrtnmo-Oo0XB0wo0,3261
1
+ mcshell/Matrix3.py,sha256=SxbAwvXiMS69t6auzJyKQj_eQ4aojgMLS_ArHlO6SaY,2713
2
2
  mcshell/Vec3.py,sha256=sEDlYFYCOU9AQxzmrZc9YBihKwgdFcD3mzX-gcAeI3Q,2408
3
- mcshell/__init__.py,sha256=vX6YK6WWxD0h6O4B7xMLDtrpHh7JfaWoJZ9NjQKGAp0,39540
3
+ mcshell/__init__.py,sha256=NzXomOD0Wj-4--CrWD2CgQKnXPoH6jzCvlMOBct-3bo,41104
4
4
  mcshell/blueprints/control_api.py,sha256=_yJiTjxOQbqPVFBuDJ-CNaY_eU2250qtRfAGKWGUWXY,1475
5
5
  mcshell/blueprints/ipython_api.py,sha256=v9T63k7YMfI9KpTODtsCrz-jHCwJf7s01I6Ghci6W2Y,1819
6
6
  mcshell/blueprints/powers_api.py,sha256=THMhRYaFlp7Jz6qAXyt4CteM3oF1ncrlj6bFyS2n67o,9229
7
- mcshell/constants.py,sha256=81Cac6qEFCLPTwKnyaLytI-h04pCjbQekFfy9JTNtVk,16737
7
+ mcshell/constants.py,sha256=wEFRuh5zPc5-DhSJJGfxvQ3Z31GjOhTBo81bkoyj06U,17051
8
8
  mcshell/data/FruitJuice-0.3.0.jar,sha256=3VR1wOGUizwfUC_A0GM6hQj0uYlajL1yiQxnLSBjaYI,36576
9
9
  mcshell/data/FruitJuice-0.4.0.jar,sha256=_--V3y4x8Fv9FX7de_cXhoN5ZlU15PAgFuLxMMv_yfc,34047
10
10
  mcshell/data/FruitJuice-0.4.1.jar,sha256=PZoY_ar5A0sraLhOIn9IMlsmI3G-YOHcPLm-AKA3AJU,34461
@@ -13,26 +13,34 @@ mcshell/data/app/control.a8439284.css.map,sha256=ZEiTVXHk0K7Qpy84IqsOyQ5uhkpCXpQ
13
13
  mcshell/data/app/control.b03e9afc.js,sha256=Q6tAuU4muMRUSTDCxodu84-LETcFpJNy7KG46Ke3Fhg,82513
14
14
  mcshell/data/app/control.b03e9afc.js.map,sha256=2lbwgkEHyRk9jvMxjmQCO_xaAtEeE9BZcRw3oiRWSQE,711955
15
15
  mcshell/data/app/control.html,sha256=Lo4Be83fDbN_ueEopJg8_5dz_w77DzMz5MjICxARS_I,6811
16
- mcshell/data/app/index.html,sha256=UOlFeQ-duncisRKsEGNzXld0RKVsuiRy8meUhaqhdTU,6368
17
- mcshell/data/app/mced.0c019c78.js,sha256=SZ9zUfBWVKyJ2ft_TH-QOd4opPjZOzLloFfxkZ1hZzQ,920516
18
- mcshell/data/app/mced.0c019c78.js.map,sha256=eThJhb_5a6pp2DooEvrj4nTww3VzR3CxsHtXSkYg2Dw,7437525
19
- mcshell/data/app/mced.9b908af4.css,sha256=EjMn5sjsEK8OxEiZhvW6-d2d_QFSKgfAyrgfJ_3U91E,1332
20
- mcshell/data/app/mced.9b908af4.css.map,sha256=QXTDmmtdY-juQ6zIOWQUKJj8wS46lYe3fvJ1AMYXCek,3956
16
+ mcshell/data/app/index.html,sha256=kyTs6GwU-9c-OdyjAMSzIOh4_Vz3gPkTfpc4JDRe6oE,8521
17
+ mcshell/data/app/mced.55f94dd4.css,sha256=IgSa3Lw2eX2pK4a4HTAU9eNmdBHzmm-7RLiMueP4LsI,3613
18
+ mcshell/data/app/mced.55f94dd4.css.map,sha256=u_UPCwOikaTttN_zUjRwNR9Bob3icjejwW755ERu6D8,17492
21
19
  mcshell/data/app/mced.a4de160c.js,sha256=ahKduGSJ-xeluXQdGHV2xpTGZbE-jkKlGKjPD6K20lw,105503
22
20
  mcshell/data/app/mced.a4de160c.js.map,sha256=k2uNMR9oaf9amVAcOFflclgfOaWSTKTtvXSd9KCbvI4,767193
23
- mcshell/data/app/mced.b6ed8b22.css,sha256=E9Kyqw5rNM5ikhaWFomlO-uNzQrl-dwLgTVLKYLdhU4,2755
24
- mcshell/data/app/mced.b6ed8b22.css.map,sha256=1wTqPSB0E7K0F5jtVgufzgNUBNSYHMEwOi2JlWqPP60,12627
25
- mcshell/data/app/toolbox.f17a15a5.xml,sha256=xfy-cWy6Q1Zc4v8w5MD2ohMc9oTWQA_HBbfmli8DaXU,20458
21
+ mcshell/data/app/mced.aa2df54f.js,sha256=9kKAbOJz1PWlUBbM7ulcNeSAE9I4UTzdqGnueBwhDJc,1032072
22
+ mcshell/data/app/mced.aa2df54f.js.map,sha256=pm3sfoSvIyGJ3CP-Llpb9QAQvRuXn5dJWZE_CvbrrmM,7963844
23
+ mcshell/data/app/mced.efd4d8e7.css,sha256=fccepR2s7g5O1Ly3ly_GfBEJCqbJ19L6jo15aH_ZQKg,4500
24
+ mcshell/data/app/mced.efd4d8e7.css.map,sha256=aw_c3MsrASG73Xinxau8AbpZDxP8ANKU7MPR_HKjNlk,11439
25
+ mcshell/data/app/toolbox.57f1313e.xml,sha256=C-musR8P-iG7rd8-gMdf3FgZlLYois9BHfdYJg7CLcc,20804
26
26
  mcshell/data/control_layout.json,sha256=Ay2pcdGUWQeFV_2-MPhCswkEGGnqDXW6O6C-uAAJ8l0,56
27
+ mcshell/data/datapacks/flat_world/data/minecraft/dimension/overworld.json,sha256=EU__5KAnyhYiEv4oW-BPxRVrNFp0wxKzvbPpqGqsJFo,312
28
+ mcshell/data/datapacks/flat_world/data/minecraft/worldgen/biome/the_void.json,sha256=nHtAzTgnaTjPKTJCUzG79fHGUMG7x_a1zFTddVJ1Kcg,572
29
+ mcshell/data/datapacks/flat_world/pack.mcmeta,sha256=8PPT47vFZJ8Jnw15TEBKxi2wjtSba7VSar1KlWSGwdA,125
30
+ mcshell/data/datapacks/void_world/data/minecraft/dimension/overworld.json,sha256=i8KvFe3wGwaHbyGDnIAp_ZXqjp2n3X3ndj-V5VbN2yQ,310
31
+ mcshell/data/datapacks/void_world/data/minecraft/functions/init.mcfunction,sha256=HSKOBSILA59AgKTuWCwD2hDUCh5qmfzJVCh6ABUFojY,146
32
+ mcshell/data/datapacks/void_world/data/minecraft/tags/functions/load.json,sha256=hAgOjtZuJf3SrAjdLuZwjT7qWwivUErW9LKraomW2Jo,42
33
+ mcshell/data/datapacks/void_world/data/minecraft/worldgen/biome/the_void.json,sha256=nHtAzTgnaTjPKTJCUzG79fHGUMG7x_a1zFTddVJ1Kcg,572
34
+ mcshell/data/datapacks/void_world/pack.mcmeta,sha256=2172-PjjX2VhtRwh4e0I7YHK4U-rQPcrv4FUOX65yKk,131
27
35
  mcshell/data/doc/command_docs.pkl,sha256=JvBRzPGKqIPULNVqqa5WT3OrDVyb80wrfd2gwcXivHg,21694
28
36
  mcshell/data/entities/entity_id_map.pkl,sha256=Gk_QcE4JlocwfASi2hm_tDubOjdPoC-f9FqeD5b_07s,1185
29
37
  mcshell/data/entities/generate_entity_blocks.mjs,sha256=kKKls2CvWmJZflYe9_HpQDVHaVaxTVJQGOUZdYXGqts,6120
30
38
  mcshell/data/entities/pickers.json,sha256=OtgYu-G91tMFZpvvIuJgTkBY-nv4enV0vMiiD7OQoeI,1926
31
- mcshell/data/materials/colourables.json,sha256=p0Rgbafws3dM34SLtSCABEvJJm89Haq1Fvz-mnbhd9o,6207
39
+ mcshell/data/materials/colourables.json,sha256=_DHmx7cWoZ4g-IpXEvVr5HwSFRLJ7Y2TXwYkBQuKtss,6207
32
40
  mcshell/data/materials/generate_material_blocks.mjs,sha256=nK49t6Ydk7Z-aYrAmzkL2aguDSoe2b6iA6hEoKGCrFM,9698
33
41
  mcshell/data/materials/materials.pkl,sha256=NASqBFeuPJC2UDU2Vbk_CEeQpTDXgTAjT-8NXhGT5cw,40421
34
42
  mcshell/data/materials/mcblocks.csv,sha256=AkttFKbUzwqbJos3dfRDKmV3R9Pdk_B6myBzeBs5Tz8,80392
35
- mcshell/data/materials/pickers.json,sha256=vieeKMYcVsknbZZOGOoix_jTjvRgBjx5T6ucyETjl9k,10422
43
+ mcshell/data/materials/pickers.json,sha256=ouOSrVaHZG4cytGZq81z7Tr6sfdz5RGBIcFGDkTBndM,10422
36
44
  mcshell/data/materials/singles.json,sha256=eHUg_8HZ_Ty8pqQARi7Fu1L6Y_ihUTQL1CVXmwxUjys,25115
37
45
  mcshell/data/paper-global-template.yaml,sha256=QTHmpkusBw35JEqBRiXtSBoHED78EpvuP_R1s_sMdyY,4614
38
46
  mcshell/data/powers/stdlib.json,sha256=PTNNSUJ8VbTgmWFfmPZZyGDUXOigTpSDiVjQ-Qm39bE,984092
@@ -159,23 +167,24 @@ mcshell/data/webpage-cache/worldborder.pkl,sha256=rRTxk6g82SZ3ZBXSXqrE7bCrAqZLA_
159
167
  mcshell/data/webpage-cache/worldbuilder.pkl,sha256=DjfIl48tYw_ouu29T2bbBHsqLzdzNpIQJK3v1umYuAA,413263
160
168
  mcshell/data/webpage-cache/wsserver.pkl,sha256=DTNR_XdQadFahe5SqDcEsaMgq2u7Sc8DDbOV0pnh5b8,427232
161
169
  mcshell/data/webpage-cache/xp.pkl,sha256=dmZSPuz-VDbcqp7mxE6b1t9Vr-1PAhTRh3DQQr9Z9Sc,438659
162
- mcshell/mcactions.py,sha256=-X8-UegUV31TVHoI1sLysMZ36Acz3PTOa2s7ZjRzNDc,19419
163
- mcshell/mcactions_base.py,sha256=DwNTyCjery4aBbowd8xCESwlIj3UwNFs9Ewh0bDdWDE,11930
164
- mcshell/mcblockly.py,sha256=pJfEs7ZERZgO38anuS8G9pB7zER0D4fjBhUZlZf89Jo,34126
170
+ mcshell/mcactions.py,sha256=Y5aEI-9zzB_6HcqfQxR2Lt4cba1aph4zTokgewdBvvI,23206
171
+ mcshell/mcactions_base.py,sha256=TXUD4--7bvyyLeqgdKmVgKZYGqZ0ARxSZrrI_hSkyFs,13542
172
+ mcshell/mcblockly.py,sha256=C8VVadtnHj3T984qJrF5WxQlivqg_eZURsGyfHr1IE8,34779
165
173
  mcshell/mcclient.py,sha256=KWG42v9l391pBEywudouDH0uV3nTa79QrJKvHt_dU4s,4431
166
174
  mcshell/mceventactions.py,sha256=_TFJ3hEQ4XE-Hd557skw8mgmOZupJQO1dhjROOHHkLE,2576
175
+ mcshell/mcexperience_base.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
176
  mcshell/mclsystem.py,sha256=4UlKZqo8_mHEgeT2suEV8o9jTu9qGib-mSQL3P9ILKw,1365
168
- mcshell/mcplayer.py,sha256=-zri6bSPCu9MC6hFE29Tfu8u2V7znVWsHU9r4iiEvv0,7497
177
+ mcshell/mcplayer.py,sha256=86BNpo_fjUmli-ZPrH-kuAi26wBP3FS0I0NpAiMcKQQ,11460
169
178
  mcshell/mcrepo.py,sha256=QpYKcVFCH6uQF9fo1VNfSVO3M5ghAl-EFNAPeUTpQ4U,5217
170
179
  mcshell/mcscraper.py,sha256=z72w7XKzpXXz3Unm12-u2qUFzEhKt5ejfbLeDD8LPTI,7668
171
- mcshell/mcserver.py,sha256=jeMmi7fMzaCpgv0ZEBEiznNSPsXWdDjQ_jHcD4083j0,16056
180
+ mcshell/mcserver.py,sha256=GEGQCdo1iAj15yOS9NZvjvGhsXlTlq9VWN8yz2Kbdr4,16095
172
181
  mcshell/mcshell.py,sha256=3kZfbLolls0E1QhmHhM1DiUlW56YI7UlbgpHZcZqC34,2309
173
- mcshell/mcturtle.py,sha256=hMGAz9KcnG163ot2ejXQGgPQ8WsFttNV5qEY7DTbZ-I,14886
182
+ mcshell/mcturtle.py,sha256=H8ThIBivnr6-WEpJ8rd16HZ_KU4t0CbWz4FyIhFSSpw,18915
174
183
  mcshell/mcvoxel.py,sha256=ORxlXnwLyR9puajvDgU3HHxrF5BUzCn6-j2iXn_Y1lE,32705
175
- mcshell/mcvoxel_original.py,sha256=ORxlXnwLyR9puajvDgU3HHxrF5BUzCn6-j2iXn_Y1lE,32705
176
- mcshell/ppdownloader.py,sha256=jMkzwDhGKpHuESIMx_ZggUMG_iOt5-pWPl2vyvCNKuQ,7970
177
- mcshell/ppmanager.py,sha256=oXn8acW2lEoDEIEmtC3uEO64RtpDfZOO6b_XwNB0JcI,12286
178
- mcshell/pyncactions.py,sha256=stiZYW1v2Oe7uNHTTI_ll61tuqzMlh2A6CU_6km_nhA,11111
184
+ mcshell/mcvoxel_original.py,sha256=nUfHOo75awppnO7ucMsMAaP_hM29_FkicwmvUmncBNs,32717
185
+ mcshell/ppdownloader.py,sha256=CUvDM0uda9if84th5t0QXAWSIr0ERkkxY5WR7SjhacY,7349
186
+ mcshell/ppmanager.py,sha256=DmstMzlKpz0Q2n2KHp_lR45ERJXrgk572bxnR9qRfVk,8343
187
+ mcshell/pyncactions.py,sha256=1q5zTGWOyhcXyAZWmcwtSqBLtaD7MLw4SjCP17_nSGQ,11227
179
188
  mcshell/serveractions.py,sha256=Z-R9bcTgGNs6qaTz8PG5nHfoMASLbJoG4KXsS2ABbgE,7217
180
189
  mcshell/vendored/pyncraft/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
181
190
  mcshell/vendored/pyncraft/block.py,sha256=aI86MkBV2k63Mhe3TAlb9jo0Zz_gGWaxLa_Z-cNsOXU,4019
@@ -183,11 +192,11 @@ mcshell/vendored/pyncraft/connection.py,sha256=s8rszSMrwtE-5rC7fidVs_KVkHDxLmTfn
183
192
  mcshell/vendored/pyncraft/entity.py,sha256=TTJCUh7N-VSIHhJldHsQ-5owMHIN8NiWfMeHkIEnWgo,3404
184
193
  mcshell/vendored/pyncraft/event.py,sha256=abjveW6Fg6OWzD3RsVRMkV3NMV6H8-7-jp-tgb38fD0,1807
185
194
  mcshell/vendored/pyncraft/logger.py,sha256=9Su0Fq8HiwXTlZoweG1cQrpRjC8yaGKheyPanrJlbho,842
186
- mcshell/vendored/pyncraft/minecraft.py,sha256=oMt8ADObJPBpAmRkqkslmSN1wFbDM2DNmx4W7Kg9MTY,14763
195
+ mcshell/vendored/pyncraft/minecraft.py,sha256=ieI6Di6XcHOFyQ7VTVCGIruhoWDF51e1CqYws2VSuOU,14750
187
196
  mcshell/vendored/pyncraft/util.py,sha256=B59FM0nLWlXdsy9kW2OUhGdDMCvrkmdIZTVLR-euzk0,559
188
197
  mcshell/vendored/pyncraft/vec3.py,sha256=R8DaFpPCbbWLN-3B5n0mvJXQ8wGOvhqfHclB4-jVtj8,2458
189
- mc_shell-0.6.6.dist-info/METADATA,sha256=sDsBQgpvEOh89SLGP-qUndCKWnJQU870gphBVXmN36Q,7199
190
- mc_shell-0.6.6.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
191
- mc_shell-0.6.6.dist-info/entry_points.txt,sha256=LSFQFpAb30QS7RK0_ygUK36vqbt9x27L51jo2WJ-4v0,47
192
- mc_shell-0.6.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
193
- mc_shell-0.6.6.dist-info/RECORD,,
198
+ mc_shell-0.6.8.dist-info/METADATA,sha256=F_XLO45NL7BrkpdGWb0rWzLcuncbgsFvc5aVz26D0wg,7199
199
+ mc_shell-0.6.8.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
200
+ mc_shell-0.6.8.dist-info/entry_points.txt,sha256=LSFQFpAb30QS7RK0_ygUK36vqbt9x27L51jo2WJ-4v0,47
201
+ mc_shell-0.6.8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
202
+ mc_shell-0.6.8.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.3.0
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
mcshell/Matrix3.py CHANGED
@@ -1,21 +1,16 @@
1
1
  import numpy as np
2
2
  import math
3
-
4
3
  from mcshell.Vec3 import Vec3
5
4
 
6
5
  class Matrix3:
7
6
  def __init__(self, elements=None):
8
7
  """
9
- Initializes a 3x3 matrix.
10
- Args:
11
- elements (list of lists or np.ndarray, optional):
12
- A 3x3 list of lists or a NumPy array.
13
- Defaults to identity matrix if None.
8
+ Initializes a 3x3 matrix for 3D transformations.
14
9
  """
15
10
  if elements is not None:
16
11
  self.matrix = np.array(elements, dtype=np.float64)
17
12
  if self.matrix.shape != (3, 3):
18
- raise ValueError("Matrix3 elements must be a 3x3 array or list of lists.")
13
+ raise ValueError("Matrix3 elements must be a 3x3 array.")
19
14
  else:
20
15
  self.matrix = np.identity(3, dtype=np.float64)
21
16
 
@@ -24,64 +19,68 @@ class Matrix3:
24
19
 
25
20
  def __matmul__(self, other):
26
21
  """
27
- Matrix multiplication using the @ operator.
28
- Supports: Matrix @ Vector -> Vector
29
- Matrix @ Matrix -> Matrix
22
+ Matrix multiplication.
23
+ If 'other' is a Vec3, it returns a transformed Vec3.
30
24
  """
31
25
  if isinstance(other, Vec3):
32
- # Matrix @ Vector -> returns a new transformed Vec3
33
- result_np = self.matrix @ np.array([other.x, other.y, other.z])
26
+ # Matrix @ Vector
27
+ vec_np = np.array([other.x, other.y, other.z])
28
+ result_np = self.matrix @ vec_np
34
29
  return Vec3(result_np[0], result_np[1], result_np[2])
35
30
  if isinstance(other, Matrix3):
36
- # Matrix @ Matrix -> returns a new combined Matrix3
31
+ # Matrix @ Matrix
37
32
  return Matrix3(self.matrix @ other.matrix)
38
33
  return NotImplemented
39
34
 
40
- def to_numpy(self):
41
- return self.matrix
42
-
43
35
  @staticmethod
44
- def from_euler_angles(yaw_degrees, pitch_degrees, roll_degrees):
36
+ def from_euler_angles(yaw_degrees=0, pitch_degrees=0, roll_degrees=0):
45
37
  """
46
- Creates a rotation matrix from Euler angles (yaw, pitch, roll) in degrees.
47
- Order of rotation: Z (yaw), then Y (pitch), then X (roll) - common convention.
48
- Adjust if your low-level functions expect a different order.
38
+ Creates a rotation matrix using Minecraft/Game conventions:
39
+ - Yaw: Rotation around Y (Up) axis.
40
+ - Pitch: Rotation around X (Right) axis.
41
+ - Roll: Rotation around Z (Forward) axis.
42
+
43
+ Order of operations: Yaw -> Pitch -> Roll (R = Ry @ Rx @ Rz)
49
44
  """
50
- yaw = math.radians(yaw_degrees)
51
- pitch = math.radians(pitch_degrees)
52
- roll = math.radians(roll_degrees)
45
+ y = math.radians(yaw_degrees)
46
+ p = math.radians(pitch_degrees)
47
+ r = math.radians(roll_degrees)
53
48
 
54
- # Rotation matrix around Z (Yaw)
55
- Rz = np.array([
56
- [math.cos(yaw), -math.sin(yaw), 0],
57
- [math.sin(yaw), math.cos(yaw), 0],
58
- [0, 0, 1]
59
- ])
60
- # Rotation matrix around Y (Pitch)
49
+ # Yaw (Around Y)
61
50
  Ry = np.array([
62
- [math.cos(pitch), 0, math.sin(pitch)],
51
+ [math.cos(y), 0, math.sin(y)],
63
52
  [0, 1, 0],
64
- [-math.sin(pitch), 0, math.cos(pitch)]
53
+ [-math.sin(y), 0, math.cos(y)]
65
54
  ])
66
- # Rotation matrix around X (Roll)
55
+
56
+ # Pitch (Around X)
67
57
  Rx = np.array([
68
58
  [1, 0, 0],
69
- [0, math.cos(roll), -math.sin(roll)],
70
- [0, math.sin(roll), math.cos(roll)]
59
+ [0, math.cos(p), -math.sin(p)],
60
+ [0, math.sin(p), math.cos(p)]
71
61
  ])
72
- # Combined rotation: R = Rz * Ry * Rx (or Rx * Ry * Rz depending on convention)
73
- # Common aerospace/robotics: Yaw (Z), Pitch (Y), Roll (X) -> R = Rz @ Ry @ Rx
74
- # Game development often uses a different order. Check your library's expectation.
75
- # Let's assume ZYX order for now.
76
- return Matrix3(Rz @ Ry @ Rx)
62
+
63
+ # Roll (Around Z)
64
+ Rz = np.array([
65
+ [math.cos(r), -math.sin(r), 0],
66
+ [math.sin(r), math.cos(r), 0],
67
+ [0, 0, 1]
68
+ ])
69
+
70
+ # Combined rotation: Ry @ Rx @ Rz
71
+ return Matrix3(Ry @ Rx @ Rz)
77
72
 
78
73
  @staticmethod
79
74
  def identity():
80
75
  return Matrix3(np.identity(3))
81
76
 
82
- # You can add matrix multiplication, etc., if needed
83
- def multiply_vector(self, vec3_instance):
84
- if not isinstance(vec3_instance, Vec3):
85
- raise TypeError("Can only multiply Matrix3 by a Vec3 instance.")
86
- result_np = self.matrix @ np.array(tuple(vec3_instance))
87
- return Vec3(result_np[0], result_np[1], result_np[2])
77
+ def rotate_around_point(self, vector: Vec3, pivot: Vec3) -> Vec3:
78
+ """
79
+ Rotates a vector around an arbitrary pivot point instead of the origin.
80
+ """
81
+ # 1. Move the vector so the pivot is at (0,0,0)
82
+ local_offset = vector - pivot
83
+ # 2. Rotate the local offset
84
+ rotated_offset = self @ local_offset
85
+ # 3. Move it back to world space
86
+ return pivot + rotated_offset
mcshell/__init__.py CHANGED
@@ -18,12 +18,11 @@ from mcshell.ppdownloader import *
18
18
 
19
19
  from mcshell.mcserver import stop_app_server
20
20
 
21
- #pycraft.settings
22
- SHOW_DEBUG=False
23
- SHOW_Log=False
21
+ import atexit
24
22
 
25
23
  @magics_class
26
24
  class MCShell(Magics):
25
+
27
26
  def __init__(self,shell):
28
27
  super(MCShell,self).__init__(shell)
29
28
 
@@ -85,24 +84,22 @@ class MCShell(Magics):
85
84
 
86
85
  @line_magic
87
86
  def pp_create_world(self, line):
88
- """
89
- Creates a new, self-contained Paper server instance in its own directory.
90
- Usage: % pp_create_world < world_name > --version=<mc_version>
91
- Example: %pp_create_world my_creative_world
92
- """
93
87
  args = line.split()
94
88
  if not args:
95
- print("Usage: %pp_create_world <world_name> [--version=<mc_version>]")
89
+ print("Usage: %pp_create_world <world_name> [--version=<v>] [--datapacks=p1,p2]")
96
90
  return
97
91
 
98
92
  world_name = args[0]
99
- mc_version = MC_VERSION # default
93
+ mc_version = MC_VERSION
94
+ datapacks_to_install = []
100
95
 
101
- # Simple argument parsing for --version flag if we use it
102
- # Usage: % pp_create_world < world_name > --version = < mc_version >
96
+ # Enhanced argument parsing
103
97
  for arg in args[1:]:
104
98
  if arg.startswith("--version="):
105
99
  mc_version = arg.split('=', 1)[1]
100
+ elif arg.startswith("--datapacks="):
101
+ # Expects a comma-separated list of names
102
+ datapacks_to_install = arg.split('=', 1)[1].split(',')
106
103
 
107
104
  # Define paths
108
105
  world_dir = MC_WORLDS_BASE_DIR.joinpath(world_name)
@@ -223,6 +220,30 @@ class MCShell(Magics):
223
220
  if plugin_urls:
224
221
  downloader.install_plugins(plugin_urls, plugins_dir)
225
222
 
223
+ # --- Datapack Installation Logic ---
224
+ if datapacks_to_install:
225
+ # Datapacks must be in 'world/datapacks' for first-run generation
226
+ world_datapacks_dir = world_dir / "world" / "datapacks"
227
+ world_datapacks_dir.mkdir(parents=True, exist_ok=True)
228
+
229
+ for pack_name in datapacks_to_install:
230
+ pack_name = pack_name.strip()
231
+ source = MC_DATAPACK_LIB_DIR / pack_name
232
+
233
+ # Check for the name directly (folder) or with .zip extension
234
+ if not source.exists():
235
+ source = MC_DATAPACK_LIB_DIR / f"{pack_name}.zip"
236
+
237
+ if source.exists():
238
+ target = world_datapacks_dir / source.name
239
+ if source.is_dir():
240
+ shutil.copytree(source, target)
241
+ else:
242
+ shutil.copy2(source, target)
243
+ print(f"Installed datapack: {pack_name}")
244
+ else:
245
+ print(f"Warning: Datapack '{pack_name}' not found in library.")
246
+
226
247
  print(f"\nWorld '{world_name}' created successfully.")
227
248
  print(f"To start it, run: %pp_start_world {world_name}")
228
249
 
@@ -763,12 +784,13 @@ class MCShell(Magics):
763
784
 
764
785
  RUNNING_POWERS[execution_id] = {'thread': thread, 'cancel_event': cancel_event}
765
786
 
766
- # --- Save Metadata (This part remains synchronous) ---
767
787
  power_repo = JsonFileRepository(player_name)
768
788
 
769
789
  if power_repo:
770
790
  print(f"--- Power '{metadata.get('function_name')}' metadata defined/updated. ---")
771
791
  print(f"--- Started debug execution with ID: {execution_id} ---")
792
+ # ADD THIS LINE: A specific prefix for the frontend to find
793
+ print(f"MCED_EXECUTION_ID:{execution_id}")
772
794
  print("--- To stop it, run: %mc_cancel_power " + execution_id + " ---")
773
795
 
774
796
  except Exception as e:
@@ -977,13 +999,29 @@ class MCShell(Magics):
977
999
  except requests.exceptions.RequestException as e:
978
1000
  print(f"Error: Could not connect to the other player's application server. {e}")
979
1001
 
980
- import atexit # <-- Import the standard library module
1002
+ def sync_datapack_library():
1003
+ """
1004
+ Synchronizes the internal datapack library to the user's worlds directory.
1005
+ Does not overwrite existing files to allow students to tweak their copies.
1006
+ """
1007
+ if MC_INTERNAL_DATAPACKS.exists():
1008
+ MC_DATAPACK_LIB_DIR.mkdir(parents=True, exist_ok=True)
1009
+ for item in MC_INTERNAL_DATAPACKS.iterdir():
1010
+ target = MC_DATAPACK_LIB_DIR / item.name
1011
+ if not target.exists():
1012
+ if item.is_dir():
1013
+ shutil.copytree(item, target)
1014
+ else:
1015
+ shutil.copy2(item, target)
981
1016
 
982
1017
  def load_ipython_extension(ip):
983
1018
  """
984
1019
  Called by IPython when the extension is loaded.
985
1020
  This is where we register the magics and the shutdown hook.
986
1021
  """
1022
+
1023
+ sync_datapack_library()
1024
+
987
1025
  # Register the main magic class
988
1026
  mcshell_instance = MCShell(ip)
989
1027
  ip.register_magics(mcshell_instance)
mcshell/constants.py CHANGED
@@ -96,6 +96,16 @@ MC_CONTROL_LAYOUT_PATH = MC_DATA_DIR.joinpath('control_layout.json')
96
96
  MC_WORLDS_BASE_DIR = pathlib.Path('~').expanduser().joinpath('mc-worlds')
97
97
  MC_CENTRAL_CONFIG_FILE = pathlib.Path("/etc/mc-shell/user_map.json")
98
98
 
99
+ # new: datapacks
100
+ MC_INTERNAL_DATAPACKS = MC_DATA_DIR / 'datapacks'
101
+ MC_DATAPACK_LIB_DIR = MC_WORLDS_BASE_DIR / 'datapacks-library'
102
+
103
+ MC_JRE_DIR = MC_WORLDS_BASE_DIR / 'jre'
104
+ # Determine the binary name based on the OS
105
+ JRE_BINARY = "java.exe" if os.name == "nt" else "bin/java"
106
+
107
+ MC_JRE_PATH = MC_JRE_DIR / JRE_BINARY
108
+
99
109
  RE_NON_JSON_VALUE = r"(?<!\")\b(?:[0-9]+[a-zA-Z]+|[0-9]+(?:\.[0-9]+)?[a-zA-Z]+|true|false|null)\b(?!\")"
100
110
  RE_NON_JSON_ARRAY = r"\[[BISL];\s*[^\]]+\]"
101
111
 
@@ -1,7 +1,4 @@
1
- <!DOCTYPE html><html lang=en><script type=importmap>{"imports":{"2N3MJ":"/toolbox.f17a15a5.xml"}}</script><script type=module src=/mced.a4de160c.js></script><link rel=stylesheet href=/mced.9b908af4.css><meta charset=utf-8><title>MC-ED Editor</title><link rel=stylesheet href=/mced.b6ed8b22.css><body x-data="{
2
- isLibraryCollapsed: false,
3
- isCodeCollapsed: false
4
- }">
1
+ <!DOCTYPE html><html lang=en><script type=importmap>{"imports":{"2N3MJ":"/toolbox.57f1313e.xml"}}</script><script type=module src=/mced.a4de160c.js></script><link rel=stylesheet href=/mced.efd4d8e7.css><meta charset=utf-8><title>MC-ED Editor</title><link rel=stylesheet href=/mced.55f94dd4.css><body x-data="{ isLibraryCollapsed: true, isCodeCollapsed: true, keyboardVisible: false }">
5
2
  <div class=editor-layout :class="{ 'library-collapsed': isLibraryCollapsed, 'code-collapsed': isCodeCollapsed }">
6
3
  <aside id=power-library-panel>
7
4
 
@@ -21,11 +18,18 @@
21
18
 
22
19
  <main id=main-content-panel>
23
20
  <div id=controls>
21
+ <button @click="isLibraryCollapsed = !isLibraryCollapsed">Toggle Library</button>
22
+ <button @click="isCodeCollapsed = !isCodeCollapsed">Toggle Code</button>
23
+
24
24
  <button id=savePowerAsButton @click=prepareAndOpenSaveModal()>Save/Update Power...</button>
25
25
  <button id=loadPowerFromFileButton>Load from File...</button>
26
26
 
27
27
  <button id=executePowerButton>Execute (Debug)</button>
28
+ <button id=cancelPowerButton style=color:#fff;background-color:#d9534f>Cancel Power</button>
28
29
  <button id=clearWorkspaceButton>Clear Workspace</button>
30
+ <button class=control-button @click="keyboardVisible = !keyboardVisible" :class="keyboardVisible ? 'btn-active' : ''">
31
+ <i class="fa-keyboard fas"></i> Toggle Keyboard
32
+ </button>
29
33
  </div>
30
34
  <div id=blocklyDiv></div>
31
35
  </main>
@@ -109,8 +113,37 @@
109
113
  </div>
110
114
  </div>
111
115
  </div>
116
+
117
+ <div x-data="{
118
+ show: false,
119
+ message: '',
120
+ defaultValue: '',
121
+ callback: null,
122
+ inputValue: ''
123
+ }" @blockly-prompt.window="
124
+ show = true;
125
+ message = $event.detail.message;
126
+ defaultValue = $event.detail.defaultValue;
127
+ /* Change this line to use onComplete */
128
+ callback = $event.detail.onComplete;
129
+ /* callback = $event.detail.callback; */
130
+ inputValue = $event.detail.defaultValue;
131
+ // Use nextTick to wait for the modal to be visible before focusing
132
+ $nextTick(() => { $refs.promptInput.focus(); });
133
+ " x-show=show class=modal-overlay style=z-index:35000> <div class=modal-content>
134
+ <p x-text=message></p>
135
+ <input x-model=inputValue @keyup.enter="callback(inputValue); show = false;">
136
+ <div class=modal-buttons>
137
+ <button @click="callback(inputValue); show = false;">OK</button>
138
+ <button @click="callback(null); show = false;">Cancel</button>
139
+ </div>
140
+ </div>
141
+ </div>
142
+
112
143
  </div>
113
144
  </template>
114
145
 
115
- <script type=module src=/mced.0c019c78.js></script>
146
+ <script type=module src=/mced.aa2df54f.js></script>
147
+ <div class=simple-keyboard x-show=keyboardVisible style=z-index:20000;background:#fff;width:100%;position:fixed;bottom:0;left:0>
148
+ </div>
116
149
 
@@ -0,0 +1,2 @@
1
+ html,body{color:#333;background-color:#f0f0f0;height:100vh;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;overflow:hidden}.editor-layout{box-sizing:border-box;grid-template-columns:300px 1fr 100ch;gap:8px;height:100%;padding:8px;transition:grid-template-columns .25s ease-in-out;display:grid}#power-library-panel{background-color:#fff;border-radius:8px;flex-direction:column;min-width:0;display:flex;overflow-y:auto;box-shadow:0 2px 4px #0000001a}#power-list{flex-grow:1;padding:8px}#main-content-panel{flex-direction:column;gap:8px;min-width:0;display:flex}#controls{background:#fff;border-radius:8px;flex-wrap:wrap;flex-shrink:0;gap:8px;padding:8px;display:flex;box-shadow:0 2px 4px #0000001a}#controls button{cursor:pointer;background-color:#f7f7f7;border:1px solid #ccc;border-radius:4px;padding:6px 12px}#controls button:hover{background-color:#e9e9e9;border-color:#bbb}#blocklyDiv{flex-grow:1;position:relative!important}#code-container{color:#f8f8f2;box-sizing:border-box;white-space:pre-wrap;overflow-wrap:break-word;word-break:break-word;background-color:#272822;flex-grow:1;margin:0;padding:1em;font-family:Fira Code,Dank Mono,monospace;font-size:14px;line-height:1.5;overflow:auto}.editor-layout{width:100vw;height:100vh;display:flex;overflow:hidden}#power-library-panel,#code-preview-panel{flex-direction:column;transition:width .3s;display:flex;overflow-x:hidden}#main-content-panel{flex-direction:column;flex:1;min-width:0;display:flex}.library-collapsed #power-library-panel,.code-collapsed #code-preview-panel{border:none!important;width:0!important;min-width:0!important;padding:0!important}.simple-keyboard{background-color:#fff;width:100%;position:fixed;bottom:0;left:0;box-shadow:0 -5px 20px #0000004d;z-index:50000!important}.simple-keyboard.hg-layout-numpad{max-width:300px;margin:0 auto}.hg-button{height:60px!important;font-size:1.2rem!important}[x-cloak]{display:none!important}.modal-overlay{z-index:40000;background-color:#0009;width:100%;height:100%;position:fixed;top:0;left:0}.modal-content{background-color:#fff;border-radius:12px;width:90%;max-width:500px;padding:25px;transition:all .2s ease-out;position:fixed;left:50%;box-shadow:0 5px 15px #0000004d;z-index:40001!important;top:30%!important;transform:translate(-50%,-30%)scale(1)!important}.modal-content input{width:100%;margin:15px 0;padding:10px;font-size:1.1rem}.modal-buttons{justify-content:flex-end;gap:10px;display:flex}.enter-start{opacity:0;transform:translate(-50%,-50%)scale(.95)}.enter-end,.leave-start{opacity:1;transform:translate(-50%,-50%)scale(1)}.leave-end{opacity:0;transform:translate(-50%,-50%)scale(.95)}.editor-layout.library-collapsed{grid-template-columns:45px 1fr 100ch}.editor-layout.code-collapsed{grid-template-columns:300px 1fr 40ch}.editor-layout.library-collapsed.code-collapsed{grid-template-columns:45px 1fr 40ch}#code-preview-panel{background-color:#fff;border-radius:8px;flex-direction:column;display:flex;overflow:hidden;box-shadow:0 2px 4px #0000001a}.panel-header{border-bottom:1px solid #e0e0e0;flex-shrink:0;justify-content:space-between;align-items:center;padding:12px 16px;display:flex}#power-library-panel h2{border-bottom:none;margin:0;padding:0;font-size:16px}.code-header{color:#555;background-color:#f7f7f7;border-top:1px solid #ccc;border-bottom:1px solid #ccc;padding:4px 10px;font-size:13px;font-weight:500}.toggle-btn{cursor:pointer;background:0 0;border:1px solid #0000;border-radius:4px;padding:2px 6px;font-size:16px;line-height:1}.toggle-btn:hover{background-color:#e0e0e0}
2
+ /*# sourceMappingURL=mced.55f94dd4.css.map */
@@ -0,0 +1 @@
1
+ {"mappings":"ACCA,4KAUA,0KAUA,2JAiBA,oCAMA,2EAOA,yIAWA,kHAQA,kEAgBA,oDAqCA,yQA0BA,qEAQA,mHAQA,0EAQA,8JAcA,0IAiBA,gEAMA,4DAOA,iCAIA,uGAUA,8QAwCA,4EAOA,8DASA,gEAKA,yEAUA,8DAOA,sEASA,mEAKA,oFASA,8IAqCA,4IAQA,6EAMA,wJASA,gIASA","sources":["mced.55f94dd4.css","src/editor.css"],"sourcesContent":["html, body {\n color: #333;\n background-color: #f0f0f0;\n height: 100vh;\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif;\n overflow: hidden;\n}\n\n.editor-layout {\n box-sizing: border-box;\n grid-template-columns: 300px 1fr 100ch;\n gap: 8px;\n height: 100%;\n padding: 8px;\n transition: grid-template-columns .25s ease-in-out;\n display: grid;\n}\n\n#power-library-panel {\n background-color: #fff;\n border-radius: 8px;\n flex-direction: column;\n min-width: 0;\n display: flex;\n overflow-y: auto;\n box-shadow: 0 2px 4px #0000001a;\n}\n\n#power-list {\n flex-grow: 1;\n padding: 8px;\n}\n\n#main-content-panel {\n flex-direction: column;\n gap: 8px;\n min-width: 0;\n display: flex;\n}\n\n#controls {\n background: #fff;\n border-radius: 8px;\n flex-wrap: wrap;\n flex-shrink: 0;\n gap: 8px;\n padding: 8px;\n display: flex;\n box-shadow: 0 2px 4px #0000001a;\n}\n\n#controls button {\n cursor: pointer;\n background-color: #f7f7f7;\n border: 1px solid #ccc;\n border-radius: 4px;\n padding: 6px 12px;\n}\n\n#controls button:hover {\n background-color: #e9e9e9;\n border-color: #bbb;\n}\n\n#blocklyDiv {\n flex-grow: 1;\n position: relative !important;\n}\n\n#code-container {\n color: #f8f8f2;\n box-sizing: border-box;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n word-break: break-word;\n background-color: #272822;\n flex-grow: 1;\n margin: 0;\n padding: 1em;\n font-family: Fira Code, Dank Mono, monospace;\n font-size: 14px;\n line-height: 1.5;\n overflow: auto;\n}\n\n.editor-layout {\n width: 100vw;\n height: 100vh;\n display: flex;\n overflow: hidden;\n}\n\n#power-library-panel, #code-preview-panel {\n flex-direction: column;\n transition: width .3s;\n display: flex;\n overflow-x: hidden;\n}\n\n#main-content-panel {\n flex-direction: column;\n flex: 1;\n min-width: 0;\n display: flex;\n}\n\n.library-collapsed #power-library-panel, .code-collapsed #code-preview-panel {\n border: none !important;\n width: 0 !important;\n min-width: 0 !important;\n padding: 0 !important;\n}\n\n.simple-keyboard {\n background-color: #fff;\n width: 100%;\n position: fixed;\n bottom: 0;\n left: 0;\n box-shadow: 0 -5px 20px #0000004d;\n z-index: 50000 !important;\n}\n\n.simple-keyboard.hg-layout-numpad {\n max-width: 300px;\n margin: 0 auto;\n}\n\n.hg-button {\n height: 60px !important;\n font-size: 1.2rem !important;\n}\n\n[x-cloak] {\n display: none !important;\n}\n\n.modal-overlay {\n z-index: 40000;\n background-color: #0009;\n width: 100%;\n height: 100%;\n position: fixed;\n top: 0;\n left: 0;\n}\n\n.modal-content {\n background-color: #fff;\n border-radius: 12px;\n width: 90%;\n max-width: 500px;\n padding: 25px;\n transition: all .2s ease-out;\n position: fixed;\n left: 50%;\n box-shadow: 0 5px 15px #0000004d;\n z-index: 40001 !important;\n top: 30% !important;\n transform: translate(-50%, -30%)scale(1) !important;\n}\n\n.modal-content input {\n width: 100%;\n margin: 15px 0;\n padding: 10px;\n font-size: 1.1rem;\n}\n\n.modal-buttons {\n justify-content: flex-end;\n gap: 10px;\n display: flex;\n}\n\n.enter-start {\n opacity: 0;\n transform: translate(-50%, -50%)scale(.95);\n}\n\n.enter-end, .leave-start {\n opacity: 1;\n transform: translate(-50%, -50%)scale(1);\n}\n\n.leave-end {\n opacity: 0;\n transform: translate(-50%, -50%)scale(.95);\n}\n\n.editor-layout.library-collapsed {\n grid-template-columns: 45px 1fr 100ch;\n}\n\n.editor-layout.code-collapsed {\n grid-template-columns: 300px 1fr 40ch;\n}\n\n.editor-layout.library-collapsed.code-collapsed {\n grid-template-columns: 45px 1fr 40ch;\n}\n\n#code-preview-panel {\n background-color: #fff;\n border-radius: 8px;\n flex-direction: column;\n display: flex;\n overflow: hidden;\n box-shadow: 0 2px 4px #0000001a;\n}\n\n.panel-header {\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n display: flex;\n}\n\n#power-library-panel h2 {\n border-bottom: none;\n margin: 0;\n padding: 0;\n font-size: 16px;\n}\n\n.code-header {\n color: #555;\n background-color: #f7f7f7;\n border-top: 1px solid #ccc;\n border-bottom: 1px solid #ccc;\n padding: 4px 10px;\n font-size: 13px;\n font-weight: 500;\n}\n\n.toggle-btn {\n cursor: pointer;\n background: none;\n border: 1px solid #0000;\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 16px;\n line-height: 1;\n}\n\n.toggle-btn:hover {\n background-color: #e0e0e0;\n}\n/*# sourceMappingURL=mced.55f94dd4.css.map */\n","/* General layout for the entire page */\nhtml, body {\n height: 100vh; /* Use 100% of the viewport height */\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n background-color: #f0f0f0;\n color: #333;\n overflow: hidden; /* Prevent the body itself from scrolling */\n}\n\n/* Make the grid container fill its parent (the body) */\n.editor-layout {\n display: grid;\n height: 100%; /* Fill the full height of the body */\n grid-template-columns: 300px 1fr 100ch;\n transition: grid-template-columns 0.25s ease-in-out;\n gap: 8px;\n padding: 8px;\n box-sizing: border-box;\n}\n/* --- Left Panel: Power Library --- */\n#power-library-panel {\n background-color: #ffffff;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n display: flex;\n flex-direction: column;\n overflow-y: auto; /* Allow scrolling if the list of powers is long */\n min-width: 0;\n}\n\n#power-library-panel h2 {\n padding: 12px 16px;\n margin: 0;\n border-bottom: 1px solid #e0e0e0;\n font-size: 16px;\n}\n\n#power-list {\n padding: 8px;\n flex-grow: 1; /* Allow the list to fill the available space */\n}\n\n/* --- Right Panel: Main Content --- */\n#main-content-panel {\n display: flex;\n flex-direction: column; /* Stack the toolbar, editor, and preview vertically */\n gap: 8px;\n min-width: 0;\n}\n\n#controls {\n flex-shrink: 0; /* Prevent the control bar from shrinking */\n background: #ffffff;\n padding: 8px;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n display: flex;\n flex-wrap: wrap; /* Allow buttons to wrap on smaller screens */\n gap: 8px;\n}\n\n#controls button {\n padding: 6px 12px;\n border: 1px solid #ccc;\n background-color: #f7f7f7;\n border-radius: 4px;\n cursor: pointer;\n}\n\n#controls button:hover {\n background-color: #e9e9e9;\n border-color: #bbb;\n}\n\n/*#editor-preview-pane {*/\n/* flex-grow: 1; !* This pane will take up the remaining vertical space *!*/\n/* display: flex;*/\n/* flex-direction: column; !* To stack Blockly and the code display *!*/\n/* border: 1px solid #ccc;*/\n/* border-radius: 8px;*/\n/* overflow: hidden; !* Hide anything that spills out *!*/\n/* background-color: #ffffff;*/\n/* min-height: 0; !* Add this for better flexbox behavior in some browsers *!*/\n/*}*/\n\n#blocklyDiv {\n flex-grow: 1; /* Blockly editor takes up most of the space in this pane */\n /*position: relative; !* Needed for Blockly's UI elements *!*/\n position: relative !important;\n}\n\n/* Ensure the main container can hold the absolute button */\n/*#blocklyDiv {*/\n/* position: relative !important;*/\n/*}*/\n\n/*.toolbox-toggle-btn {*/\n/* position: absolute;*/\n/* top: 10px;*/\n/* !* 'left' is now managed by JS to track the toolbox width *!*/\n/* width: 44px;*/\n/* height: 44px;*/\n/* background: #333;*/\n/* color: white;*/\n/* display: flex;*/\n/* align-items: center;*/\n/* justify-content: center;*/\n/* border-radius: 0 8px 8px 0;*/\n/* cursor: pointer;*/\n/* z-index: 1000; !* Over everything *!*/\n/* box-shadow: 2px 0 10px rgba(0,0,0,0.5);*/\n/* transition: left 0.3s ease-in-out;*/\n/*}*/\n\n/*.blocklyToolboxDiv {*/\n/* transition: transform 0.3s ease-in-out;*/\n/* !* No more overflow:visible needed here since button is outside *!*/\n/*}*/\n\n/*.toolbox-collapsed {*/\n/* transform: translateX(-100%);*/\n/*}*/\n#code-container {\n /* REMOVED: height: 250px; */\n /* REMOVED: flex-shrink: 0; */\n\n /* ADDED: This tells the element to grow and fill all available vertical space */\n /* in its parent flex container (#code-preview-panel). */\n flex-grow: 1;\n\n /* These properties remain the same */\n margin: 0;\n overflow: auto; /* For vertical AND horizontal scrolling if needed */\n background-color: #272822;\n color: #f8f8f2;\n font-family: 'Fira Code', 'Dank Mono', monospace;\n font-size: 14px;\n line-height: 1.5;\n padding: 1em;\n box-sizing: border-box;\n\n /* Wrapping rules remain the same */\n white-space: pre-wrap;\n overflow-wrap: break-word;\n word-break: break-word;\n}\n/*-------------------------------------------------------------*/\n/* Ensure the layout container can shrink its children to 0 */\n.editor-layout {\n display: flex;\n width: 100vw;\n height: 100vh;\n overflow: hidden;\n}\n\n/* Base styles for the side panels */\n#power-library-panel, #code-preview-panel {\n transition: width 0.3s ease;\n overflow-x: hidden; /* Critical: hides content as width hits 0 */\n display: flex;\n flex-direction: column;\n}\n\n/* Central panel grows to take all remaining space */\n#main-content-panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-width: 0; /* Allows the panel to shrink/grow correctly in flex */\n}\n\n/* Collapsed States */\n.library-collapsed #power-library-panel {\n width: 0 !important;\n min-width: 0 !important;\n padding: 0 !important;\n border: none !important;\n}\n\n.code-collapsed #code-preview-panel {\n width: 0 !important;\n min-width: 0 !important;\n padding: 0 !important;\n border: none !important;\n}\n/*-------------------------------------------------------------*/\n.simple-keyboard {\n z-index: 50000 !important; /* Higher than modals and Blockly widgets */\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100%;\n background-color: white; /* Ensure it's not transparent */\n box-shadow: 0 -5px 20px rgba(0,0,0,0.3);\n}\n\n/* Ensure the keys are large enough for touchscreens */\n.hg-button {\n height: 50px !important;\n font-size: 20px !important;\n}\n\n/* Center the numpad and give it a calculator-like width */\n.simple-keyboard.hg-layout-numpad {\n max-width: 300px;\n margin: 0 auto; /* Center it at the bottom of the screen */\n}\n\n/* Ensure keys are large and easy to hit on a touchscreen */\n.hg-button {\n height: 60px !important;\n font-size: 1.2rem !important;\n}\n\n/* --- MODAL STYLES --- */\n\n[x-cloak] {\n display: none !important;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.6);\n z-index: 40000;\n}\n\n.modal-content {\n position: fixed;\n /*top: 50%;*/\n left: 50%;\n /* Start with the final transform state so transitions work correctly */\n /*transform: translate(-50%, -50%) scale(1);*/\n background-color: white;\n padding: 25px;\n border-radius: 12px;\n box-shadow: 0 5px 15px rgba(0,0,0,0.3);\n /*z-index: 1001;*/\n width: 90%;\n max-width: 500px;\n /* Define the transition properties on the base class */\n transition: all 0.2s ease-out;\n z-index: 40001 !important; /* One step above the backdrop */\n\n /* 3. Adjust Positioning for Portrait Monitors */\n /* Instead of top: 50%, move it higher to stay clear of the keyboard */\n top: 30% !important;\n transform: translate(-50%, -30%) scale(1) !important;\n}\n\n/*.modal-overlay {*/\n/* position: fixed;*/\n/* top: 0; left: 0; width: 100%; height: 100%;*/\n/* background: rgba(0,0,0,0.5);*/\n/* display: flex;*/\n/* justify-content: center;*/\n/* align-items: center;*/\n/*}*/\n\n/*.modal-content {*/\n/* background: white;*/\n/* padding: 20px;*/\n/* border-radius: 8px;*/\n/* box-shadow: 0 4px 15px rgba(0,0,0,0.3);*/\n/* min-width: 300px;*/\n/*}*/\n\n.modal-content input {\n width: 100%;\n margin: 15px 0;\n padding: 10px;\n font-size: 1.1rem;\n}\n\n.modal-buttons {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n}\n/* --- CORRECTED ALPINE.JS TRANSITION CLASSES --- */\n/* These are the classes that Alpine v3 actually adds to the element */\n\n/* State BEFORE the element enters. It's invisible and slightly smaller. */\n.enter-start {\n opacity: 0;\n transform: translate(-50%, -50%) scale(0.95);\n}\n/* State AFTER the element has finished entering. Fully visible. */\n.enter-end {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n/* State BEFORE the element starts to leave. Fully visible. */\n.leave-start {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n/* State AFTER the element has finished leaving. Invisible. */\n.leave-end {\n opacity: 0;\n transform: translate(-50%, -50%) scale(0.95);\n}\n\n\n/* When the library is collapsed, shrink the first column */\n.editor-layout.library-collapsed {\n grid-template-columns: 45px 1fr 100ch;\n}\n\n/* NEW: When the code preview is collapsed, shrink the third column */\n/*.editor-layout.code-collapsed {*/\n/* grid-template-columns: 300px 1fr 0px;*/\n/*}*/\n/* When the code preview is collapsed, shrink the third column to 45px */\n.editor-layout.code-collapsed {\n grid-template-columns: 300px 1fr 40ch;\n}\n\n/* Also update the rule for when both are collapsed */\n.editor-layout.library-collapsed.code-collapsed {\n grid-template-columns: 45px 1fr 40ch;\n}\n/* Handle both being collapsed at the same time */\n/*.editor-layout.library-collapsed.code-collapsed {*/\n/* grid-template-columns: 45px 1fr 0px;*/\n/*}*/\n\n/* NEW: Add styles for the new right-hand column */\n#code-preview-panel {\n display: flex;\n flex-direction: column;\n background-color: #ffffff;\n border-radius: 8px;\n box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n overflow: hidden; /* Hide content when collapsed */\n}\n\n/* Add a transition to the grid layout for smooth sidebar animation */\n/*.editor-layout {*/\n/* display: grid;*/\n/* grid-template-columns: 300px 1fr;*/\n/* transition: grid-template-columns 0.25s ease-in-out;*/\n/* !* ... other existing styles ... *!*/\n/*}*/\n\n/* When the library is collapsed, animate the grid column to a small width */\n/*.editor-layout.library-collapsed {*/\n/* grid-template-columns: 45px 1fr; !* Shrink to just wide enough for the button *!*/\n/*}*/\n\n/* Add a transition for the code container's height and padding */\n/*#code-container {*/\n/* transition: height 0.25s ease-in-out, padding 0.25s ease-in-out, border 0.25s ease-in-out;*/\n/* !* ... all your other existing styles for #code-container ... *!*/\n/*}*/\n\n/* When the code pane is collapsed, set the code container's height to 0 */\n/*#editor-preview-pane.code-pane-collapsed #code-container {*/\n/* height: 0;*/\n/* padding-top: 0;*/\n/* padding-bottom: 0;*/\n/* border-top-width: 0;*/\n/*}*/\n\n/* --- You may also need to add these styles for the new panel-header --- */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n border-bottom: 1px solid #e0e0e0;\n flex-shrink: 0; /* Prevent header from shrinking when content scrolls */\n}\n#power-library-panel h2 {\n padding: 0; /* Remove padding from h2 since it's now in panel-header */\n border-bottom: none;\n margin: 0;\n font-size: 16px;\n}\n.code-header {\n padding: 4px 10px;\n background-color: #f7f7f7;\n border-top: 1px solid #ccc;\n border-bottom: 1px solid #ccc;\n color: #555;\n font-size: 13px;\n font-weight: 500;\n}\n.toggle-btn {\n background: none;\n border: 1px solid transparent;\n border-radius: 4px;\n cursor: pointer;\n font-size: 16px;\n line-height: 1;\n padding: 2px 6px;\n}\n.toggle-btn:hover {\n background-color: #e0e0e0;\n}\n\n/* When the parent pane is marked as collapsed... */\n/*#editor-preview-pane.code-pane-collapsed .code-header {*/\n/* !* You might want to keep the header visible to allow re-opening,*/\n/* but we can hide the text inside it if we want.*/\n/* Or just let it be. The toggle button is what matters. *!*/\n/*}*/\n\n/*!* ...target the code container and set its height to 0. *!*/\n/*!* This makes it take up no space in the flex layout. *!*/\n/*#editor-preview-pane.code-pane-collapsed #code-container {*/\n/* height: 0;*/\n/* padding-top: 0;*/\n/* padding-bottom: 0;*/\n/* border-top-width: 0;*/\n/* overflow: hidden; !* Hide scrollbars during collapse *!*/\n/*}*/\n\n/*\nBecause #code-container now takes up 0 height, the #blocklyDiv (with its flex-grow: 1)\nwill automatically expand to fill the space that was just freed up inside the\n#editor-preview-pane flex container.\n*/\n\n\n"],"names":[],"version":3,"file":"mced.55f94dd4.css.map"}