mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-19 21:37:57 +08:00
subsystems cleanup
This commit is contained in:
parent
1e6b59d586
commit
c13b937c79
150
.efrocachemap
generated
150
.efrocachemap
generated
@ -421,7 +421,7 @@
|
||||
"build/assets/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/74/be/fe45a8417e95b6a2233c51992a26",
|
||||
"build/assets/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/48/ab/8cddfcde36a750856f3f81dd20c8",
|
||||
"build/assets/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/2b/46/8aedfa8741090247f04eb9e6df55",
|
||||
"build/assets/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/cf/c0/8614c5b5ccbd2d26d77a09726eb6",
|
||||
"build/assets/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/3c/43/4b7614cd5d9db1c57a77a64271f6",
|
||||
"build/assets/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/83/87/06fc7255ebf8a895ad37d2dfa13d",
|
||||
"build/assets/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/57/68/d03a19b9035cfae7cdc5377d889a",
|
||||
"build/assets/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/25/f1/d88c72fbeeb121340244bc935df4",
|
||||
@ -946,11 +946,11 @@
|
||||
"build/assets/ba_data/meshes/zoeUpperArm.bob": "https://files.ballistica.net/cache/ba1/a8/a8/81010ac1ee9ec5ca872d5c5e853a",
|
||||
"build/assets/ba_data/meshes/zoeUpperLeg.bob": "https://files.ballistica.net/cache/ba1/95/b2/502f74c70f934927f67cd505c3ad",
|
||||
"build/assets/ba_data/python-site-packages/_yaml/__init__.py": "https://files.ballistica.net/cache/ba1/b0/9d/1968d73a04d6cf20e4e79657a6e7",
|
||||
"build/assets/ba_data/python-site-packages/certifi/__init__.py": "https://files.ballistica.net/cache/ba1/00/29/e4b90bb9e91a381dcd3992ed5b8d",
|
||||
"build/assets/ba_data/python-site-packages/certifi/__init__.py": "https://files.ballistica.net/cache/ba1/63/37/efa17f5b457b793332df33904162",
|
||||
"build/assets/ba_data/python-site-packages/certifi/__main__.py": "https://files.ballistica.net/cache/ba1/ef/02/e73f8581609df189a9f61aca365b",
|
||||
"build/assets/ba_data/python-site-packages/certifi/cacert.pem": "https://files.ballistica.net/cache/ba1/5a/0e/670d05eeca037e593b8c2bf6bff4",
|
||||
"build/assets/ba_data/python-site-packages/certifi/cacert.pem": "https://files.ballistica.net/cache/ba1/6a/c2/9a6bccca11cd2ed7e16e27dfccec",
|
||||
"build/assets/ba_data/python-site-packages/certifi/core.py": "https://files.ballistica.net/cache/ba1/1b/50/5388f1475fabd1b60031f985271c",
|
||||
"build/assets/ba_data/python-site-packages/typing_extensions.py": "https://files.ballistica.net/cache/ba1/6f/99/83cb2f859c5d1680af80aa15716b",
|
||||
"build/assets/ba_data/python-site-packages/typing_extensions.py": "https://files.ballistica.net/cache/ba1/11/61/88cec81052958f4f98239d4bf3ca",
|
||||
"build/assets/ba_data/python-site-packages/yaml/__init__.py": "https://files.ballistica.net/cache/ba1/55/7c/37ea8dbd4fa4d6dac97f399b6fdd",
|
||||
"build/assets/ba_data/python-site-packages/yaml/composer.py": "https://files.ballistica.net/cache/ba1/ce/f8/71e1f5f99ba2a7c44941b70afb06",
|
||||
"build/assets/ba_data/python-site-packages/yaml/constructor.py": "https://files.ballistica.net/cache/ba1/8a/15/e361e34b79491c81553bb3534062",
|
||||
@ -2598,20 +2598,20 @@
|
||||
"build/assets/pylib-android/_pyio.py": "https://files.ballistica.net/cache/ba1/a6/e8/8d66fbca88b13213cdd2177390b8",
|
||||
"build/assets/pylib-android/_sitebuiltins.py": "https://files.ballistica.net/cache/ba1/8b/5e/3f6e73917962fa014ad2c4a55e61",
|
||||
"build/assets/pylib-android/_strptime.py": "https://files.ballistica.net/cache/ba1/ff/69/9c3f7647db7621bb88c43cc282d3",
|
||||
"build/assets/pylib-android/_sysconfigdata__linux_aarch64-linux-android.py": "https://files.ballistica.net/cache/ba1/aa/10/553aeca80a3710aa8f89f7fc3ac1",
|
||||
"build/assets/pylib-android/_sysconfigdata__linux_arm-linux-androideabi.py": "https://files.ballistica.net/cache/ba1/ad/f1/41818ec9b47e366cd72361921dbc",
|
||||
"build/assets/pylib-android/_sysconfigdata__linux_i686-linux-android.py": "https://files.ballistica.net/cache/ba1/c2/5c/b3bfba5ffbaadf288ea860d400a5",
|
||||
"build/assets/pylib-android/_sysconfigdata__linux_x86_64-linux-android.py": "https://files.ballistica.net/cache/ba1/5b/ee/5962b42890b6758cea433e67376d",
|
||||
"build/assets/pylib-android/_sysconfigdata_d_linux_aarch64-linux-android.py": "https://files.ballistica.net/cache/ba1/7b/ee/c8b9c2e67865226a6a1fbe5d244f",
|
||||
"build/assets/pylib-android/_sysconfigdata_d_linux_arm-linux-androideabi.py": "https://files.ballistica.net/cache/ba1/37/a5/4b085a7f6cdfa03b3c6c887979ba",
|
||||
"build/assets/pylib-android/_sysconfigdata_d_linux_i686-linux-android.py": "https://files.ballistica.net/cache/ba1/6f/ec/8a10cf682d5bf05bb6a7ab811d08",
|
||||
"build/assets/pylib-android/_sysconfigdata_d_linux_x86_64-linux-android.py": "https://files.ballistica.net/cache/ba1/81/1d/8202416f4ba308e6a011139115e6",
|
||||
"build/assets/pylib-android/_sysconfigdata__linux_aarch64-linux-android.py": "https://files.ballistica.net/cache/ba1/3d/04/00e723f4dad156512d4229270993",
|
||||
"build/assets/pylib-android/_sysconfigdata__linux_arm-linux-androideabi.py": "https://files.ballistica.net/cache/ba1/50/6b/3106270f7f7ae33e195d1f5caa55",
|
||||
"build/assets/pylib-android/_sysconfigdata__linux_i686-linux-android.py": "https://files.ballistica.net/cache/ba1/f3/8a/2b60f9cbf0524885e5c1c99164c1",
|
||||
"build/assets/pylib-android/_sysconfigdata__linux_x86_64-linux-android.py": "https://files.ballistica.net/cache/ba1/d6/7f/056bcaf3d491d68254c206067d19",
|
||||
"build/assets/pylib-android/_sysconfigdata_d_linux_aarch64-linux-android.py": "https://files.ballistica.net/cache/ba1/e4/32/2948686ce1d4b37a1a3f8000e2dc",
|
||||
"build/assets/pylib-android/_sysconfigdata_d_linux_arm-linux-androideabi.py": "https://files.ballistica.net/cache/ba1/a4/d1/4baa8cfc0019363742349449942b",
|
||||
"build/assets/pylib-android/_sysconfigdata_d_linux_i686-linux-android.py": "https://files.ballistica.net/cache/ba1/2a/d6/c96209fd69a4eef4a7d730cd16e8",
|
||||
"build/assets/pylib-android/_sysconfigdata_d_linux_x86_64-linux-android.py": "https://files.ballistica.net/cache/ba1/bf/6c/e8f2788661352014e973351f35cf",
|
||||
"build/assets/pylib-android/_threading_local.py": "https://files.ballistica.net/cache/ba1/4a/96/88e3987d7d692db46feb9214945e",
|
||||
"build/assets/pylib-android/_weakrefset.py": "https://files.ballistica.net/cache/ba1/e4/fa/8532ace46dfbc35149c41ea497f7",
|
||||
"build/assets/pylib-android/abc.py": "https://files.ballistica.net/cache/ba1/a9/66/1fcfe6c12211ec1b16391247947c",
|
||||
"build/assets/pylib-android/abc.py": "https://files.ballistica.net/cache/ba1/a0/da/a1ed187eee8690c1e8438b97da90",
|
||||
"build/assets/pylib-android/aifc.py": "https://files.ballistica.net/cache/ba1/1b/91/34c72b1e542417bee5bf345a1d0a",
|
||||
"build/assets/pylib-android/antigravity.py": "https://files.ballistica.net/cache/ba1/6d/56/bedf73be574cb6d7117caf5d334c",
|
||||
"build/assets/pylib-android/argparse.py": "https://files.ballistica.net/cache/ba1/2d/c7/f53a0390532cfabb416e25e72035",
|
||||
"build/assets/pylib-android/argparse.py": "https://files.ballistica.net/cache/ba1/e2/2c/ac9b12c09592929d57eb982fc554",
|
||||
"build/assets/pylib-android/ast.py": "https://files.ballistica.net/cache/ba1/3a/aa/1b0e56b21b28155707c54bc225a8",
|
||||
"build/assets/pylib-android/asynchat.py": "https://files.ballistica.net/cache/ba1/2e/f3/a0ce322332fabbf8fad4e133c6a3",
|
||||
"build/assets/pylib-android/asyncio/__init__.py": "https://files.ballistica.net/cache/ba1/ed/f0/e79e2b8b85c08f09fd14668e4822",
|
||||
@ -2633,26 +2633,26 @@
|
||||
"build/assets/pylib-android/asyncio/protocols.py": "https://files.ballistica.net/cache/ba1/b8/aa/105b79d24f88c7a2c2cdbc8e7814",
|
||||
"build/assets/pylib-android/asyncio/queues.py": "https://files.ballistica.net/cache/ba1/f6/3b/e54780730992e2377c51ac373126",
|
||||
"build/assets/pylib-android/asyncio/runners.py": "https://files.ballistica.net/cache/ba1/f1/84/754fba961e4ea6e77a9aec633afc",
|
||||
"build/assets/pylib-android/asyncio/selector_events.py": "https://files.ballistica.net/cache/ba1/f7/ee/7809d8b807ccda22db7870f508ac",
|
||||
"build/assets/pylib-android/asyncio/sslproto.py": "https://files.ballistica.net/cache/ba1/3a/63/9532c92e12c9bf06fd131a6fc419",
|
||||
"build/assets/pylib-android/asyncio/selector_events.py": "https://files.ballistica.net/cache/ba1/a1/08/fbd3a49f967da245f39cebf7694e",
|
||||
"build/assets/pylib-android/asyncio/sslproto.py": "https://files.ballistica.net/cache/ba1/2e/c1/b21e523055147d94c8c634154aab",
|
||||
"build/assets/pylib-android/asyncio/staggered.py": "https://files.ballistica.net/cache/ba1/f5/05/6f0a56b73b477a9fa65e71145366",
|
||||
"build/assets/pylib-android/asyncio/streams.py": "https://files.ballistica.net/cache/ba1/e9/c6/09b92b4e9bd3383cf4004c6186c6",
|
||||
"build/assets/pylib-android/asyncio/subprocess.py": "https://files.ballistica.net/cache/ba1/a5/ff/69004c02e2f47d0077a77803c06b",
|
||||
"build/assets/pylib-android/asyncio/subprocess.py": "https://files.ballistica.net/cache/ba1/ed/b8/d98278300b6c99f36cd08643c743",
|
||||
"build/assets/pylib-android/asyncio/taskgroups.py": "https://files.ballistica.net/cache/ba1/51/62/e5b1806d9b647383d34ba1b21b56",
|
||||
"build/assets/pylib-android/asyncio/tasks.py": "https://files.ballistica.net/cache/ba1/23/45/50593cd4928e6ee2c9591b6928ca",
|
||||
"build/assets/pylib-android/asyncio/threads.py": "https://files.ballistica.net/cache/ba1/7b/bf/81d424901524510e07b5d20e4a50",
|
||||
"build/assets/pylib-android/asyncio/timeouts.py": "https://files.ballistica.net/cache/ba1/c7/cb/81c7ee938bc47ff75342befc872a",
|
||||
"build/assets/pylib-android/asyncio/transports.py": "https://files.ballistica.net/cache/ba1/04/59/8090d813bb363cea9bf714b97c3f",
|
||||
"build/assets/pylib-android/asyncio/trsock.py": "https://files.ballistica.net/cache/ba1/30/5d/016a93b3e5224cb45af43fdc52b9",
|
||||
"build/assets/pylib-android/asyncio/unix_events.py": "https://files.ballistica.net/cache/ba1/9c/e0/da3a12b544df9c10fd3b3e0b2f37",
|
||||
"build/assets/pylib-android/asyncio/unix_events.py": "https://files.ballistica.net/cache/ba1/cb/b9/68f7c1e4f87f23b187d7140839f1",
|
||||
"build/assets/pylib-android/asyncio/windows_events.py": "https://files.ballistica.net/cache/ba1/95/46/37d8416216d656011178dbcedbb4",
|
||||
"build/assets/pylib-android/asyncio/windows_utils.py": "https://files.ballistica.net/cache/ba1/4e/fb/ef16e6692c9424804d9bdc496761",
|
||||
"build/assets/pylib-android/asyncore.py": "https://files.ballistica.net/cache/ba1/af/21/d495fa6ccc47b51ca8a8a382ea1c",
|
||||
"build/assets/pylib-android/base64.py": "https://files.ballistica.net/cache/ba1/5f/8b/bbfda4b9145b1968cb9badf8325b",
|
||||
"build/assets/pylib-android/bdb.py": "https://files.ballistica.net/cache/ba1/ae/cf/5370ea25c5decdf8dfa07caf0bfc",
|
||||
"build/assets/pylib-android/bdb.py": "https://files.ballistica.net/cache/ba1/1e/26/c626405bfc06b1e7231183eb928a",
|
||||
"build/assets/pylib-android/bisect.py": "https://files.ballistica.net/cache/ba1/9b/70/437e327d5176da41192567ad0064",
|
||||
"build/assets/pylib-android/bz2.py": "https://files.ballistica.net/cache/ba1/cd/6a/5f2491bc52afd8fc180097371473",
|
||||
"build/assets/pylib-android/cProfile.py": "https://files.ballistica.net/cache/ba1/d5/ef/924a68c0f747ad727a6326ad8e5a",
|
||||
"build/assets/pylib-android/cProfile.py": "https://files.ballistica.net/cache/ba1/9e/9c/07ac3b9e4195a62b74e4f2b9489f",
|
||||
"build/assets/pylib-android/calendar.py": "https://files.ballistica.net/cache/ba1/4e/f3/d6d85d44e36212e5d784051c80b6",
|
||||
"build/assets/pylib-android/cgi.py": "https://files.ballistica.net/cache/ba1/09/0c/5cfc8b4b92a730beec975159bd2a",
|
||||
"build/assets/pylib-android/cgitb.py": "https://files.ballistica.net/cache/ba1/2b/cf/f1cec7f3a3a9c96de7a55ebb4ea3",
|
||||
@ -2691,7 +2691,7 @@
|
||||
"build/assets/pylib-android/curses/has_key.py": "https://files.ballistica.net/cache/ba1/c7/4b/8d6db329fbbd872b7b91bfa94624",
|
||||
"build/assets/pylib-android/curses/panel.py": "https://files.ballistica.net/cache/ba1/8f/36/fdade9588f8a4362d2cc057a6eff",
|
||||
"build/assets/pylib-android/curses/textpad.py": "https://files.ballistica.net/cache/ba1/94/aa/9ebc47a6068d4461652346646dbb",
|
||||
"build/assets/pylib-android/dataclasses.py": "https://files.ballistica.net/cache/ba1/13/28/e12f8255b856ced026e75a623671",
|
||||
"build/assets/pylib-android/dataclasses.py": "https://files.ballistica.net/cache/ba1/fe/be/ea138bff21dbed88762be772514e",
|
||||
"build/assets/pylib-android/datetime.py": "https://files.ballistica.net/cache/ba1/5d/cf/d7f3b1a4db8214c1442164ac999c",
|
||||
"build/assets/pylib-android/decimal.py": "https://files.ballistica.net/cache/ba1/f5/7d/255d45b5d1d7d8e13c41a283c3e4",
|
||||
"build/assets/pylib-android/difflib.py": "https://files.ballistica.net/cache/ba1/6b/3c/8fd541b2b8d0320727025cd25275",
|
||||
@ -2848,7 +2848,7 @@
|
||||
"build/assets/pylib-android/encodings/utf_8_sig.py": "https://files.ballistica.net/cache/ba1/8f/35/42863ef311d8b970a37c0d66b0de",
|
||||
"build/assets/pylib-android/encodings/uu_codec.py": "https://files.ballistica.net/cache/ba1/4e/f8/a65413574c017a96b97fc1638ba6",
|
||||
"build/assets/pylib-android/encodings/zlib_codec.py": "https://files.ballistica.net/cache/ba1/13/88/fb103fdf395451bfc8a2d60933a9",
|
||||
"build/assets/pylib-android/enum.py": "https://files.ballistica.net/cache/ba1/93/e4/c39acfbbebdc9c4f3d204f17e496",
|
||||
"build/assets/pylib-android/enum.py": "https://files.ballistica.net/cache/ba1/62/a3/41268ae3fef3c4affc625c2e68d2",
|
||||
"build/assets/pylib-android/filecmp.py": "https://files.ballistica.net/cache/ba1/76/48/fdc6d0fc8bae7429d5e4081cf353",
|
||||
"build/assets/pylib-android/fileinput.py": "https://files.ballistica.net/cache/ba1/c3/de/f1041e6b12dd5f1906c9dbbd1101",
|
||||
"build/assets/pylib-android/fnmatch.py": "https://files.ballistica.net/cache/ba1/a1/bc/67633695d4defd4c0886428c5363",
|
||||
@ -2869,15 +2869,15 @@
|
||||
"build/assets/pylib-android/html/entities.py": "https://files.ballistica.net/cache/ba1/85/61/b405414160a08f613bdfd89e161b",
|
||||
"build/assets/pylib-android/html/parser.py": "https://files.ballistica.net/cache/ba1/c2/ff/6801a3ef6a2863d37b899615efb8",
|
||||
"build/assets/pylib-android/http/__init__.py": "https://files.ballistica.net/cache/ba1/1d/ab/578aab89ead7171ef10638e88a5d",
|
||||
"build/assets/pylib-android/http/client.py": "https://files.ballistica.net/cache/ba1/d0/b3/7013d5f9794a8311c3545ee5416d",
|
||||
"build/assets/pylib-android/http/client.py": "https://files.ballistica.net/cache/ba1/a3/f2/cd21f8ce7a4ee1b47f0b19fb57f7",
|
||||
"build/assets/pylib-android/http/cookiejar.py": "https://files.ballistica.net/cache/ba1/f3/24/a21e7c17f40e4d5c78139875811c",
|
||||
"build/assets/pylib-android/http/cookies.py": "https://files.ballistica.net/cache/ba1/93/19/b95b505a644b9a112b4c7a7678c3",
|
||||
"build/assets/pylib-android/http/server.py": "https://files.ballistica.net/cache/ba1/a0/6b/26669fc0eb0ef81b819fe8a6602d",
|
||||
"build/assets/pylib-android/http/server.py": "https://files.ballistica.net/cache/ba1/4b/28/6e2b5e6112af17e097539eadd9d7",
|
||||
"build/assets/pylib-android/imghdr.py": "https://files.ballistica.net/cache/ba1/01/1d/27a98acf3774279a584525614ba3",
|
||||
"build/assets/pylib-android/imp.py": "https://files.ballistica.net/cache/ba1/34/bd/1d1620eb0d42f9ef9bbbb11cafae",
|
||||
"build/assets/pylib-android/importlib/__init__.py": "https://files.ballistica.net/cache/ba1/2f/6c/1fb453d61417245cd196311a9b52",
|
||||
"build/assets/pylib-android/importlib/_abc.py": "https://files.ballistica.net/cache/ba1/72/0f/8056e5cd852156378b532ddbbb7c",
|
||||
"build/assets/pylib-android/importlib/_bootstrap.py": "https://files.ballistica.net/cache/ba1/da/9d/e7a6d6839a7185147f35f2040de7",
|
||||
"build/assets/pylib-android/importlib/_bootstrap.py": "https://files.ballistica.net/cache/ba1/6f/48/19e9443e3fda3c28c62f15a8238c",
|
||||
"build/assets/pylib-android/importlib/_bootstrap_external.py": "https://files.ballistica.net/cache/ba1/aa/2d/5aab23ea30219b7a42d2b7d27201",
|
||||
"build/assets/pylib-android/importlib/abc.py": "https://files.ballistica.net/cache/ba1/c9/69/7e928ff17089dc6aea96f5b33003",
|
||||
"build/assets/pylib-android/importlib/machinery.py": "https://files.ballistica.net/cache/ba1/6a/05/6c561b4ea8eb5457761c8a9fd704",
|
||||
@ -2899,7 +2899,7 @@
|
||||
"build/assets/pylib-android/importlib/resources/simple.py": "https://files.ballistica.net/cache/ba1/ae/95/788edf31cbfffd53db748d76f0b9",
|
||||
"build/assets/pylib-android/importlib/simple.py": "https://files.ballistica.net/cache/ba1/f3/4f/28cd359ecaf9fd6cf18a4dca2c33",
|
||||
"build/assets/pylib-android/importlib/util.py": "https://files.ballistica.net/cache/ba1/09/c3/a96d1265db211f32b73a5f76e1ac",
|
||||
"build/assets/pylib-android/inspect.py": "https://files.ballistica.net/cache/ba1/5a/32/1fd388139d2beff15f4306b1fb95",
|
||||
"build/assets/pylib-android/inspect.py": "https://files.ballistica.net/cache/ba1/36/5d/413e26b3a77118e51987cfd2eb1f",
|
||||
"build/assets/pylib-android/io.py": "https://files.ballistica.net/cache/ba1/4a/3a/b68b3f38d3dcf9282f4839fe5d84",
|
||||
"build/assets/pylib-android/ipaddress.py": "https://files.ballistica.net/cache/ba1/b9/83/1cf9058885b35a2411b4cbada972",
|
||||
"build/assets/pylib-android/json/__init__.py": "https://files.ballistica.net/cache/ba1/e8/b0/00d2bf8c53b55a72bc3053800596",
|
||||
@ -2911,7 +2911,7 @@
|
||||
"build/assets/pylib-android/linecache.py": "https://files.ballistica.net/cache/ba1/27/12/c31a3a6d7625d437029a6b7470c9",
|
||||
"build/assets/pylib-android/locale.py": "https://files.ballistica.net/cache/ba1/42/f3/f48fed6a16da350de46aa85b446a",
|
||||
"build/assets/pylib-android/logging/__init__.py": "https://files.ballistica.net/cache/ba1/6e/5d/6f80af880857f5eb29b038512c6d",
|
||||
"build/assets/pylib-android/logging/config.py": "https://files.ballistica.net/cache/ba1/ff/06/97c60f90420c32c697a30bfdfe90",
|
||||
"build/assets/pylib-android/logging/config.py": "https://files.ballistica.net/cache/ba1/f8/11/372496ec5ae34e8047f0280686be",
|
||||
"build/assets/pylib-android/logging/handlers.py": "https://files.ballistica.net/cache/ba1/ab/38/81444783ab84f3859e022b356989",
|
||||
"build/assets/pylib-android/lzma.py": "https://files.ballistica.net/cache/ba1/d7/38/8640aa6af4c64fdc821471930f57",
|
||||
"build/assets/pylib-android/mailbox.py": "https://files.ballistica.net/cache/ba1/d9/db/3c7510e38484ade3d88446b8f231",
|
||||
@ -2920,27 +2920,27 @@
|
||||
"build/assets/pylib-android/modulefinder.py": "https://files.ballistica.net/cache/ba1/3f/c0/74c018de1dd15ab2e309be199dea",
|
||||
"build/assets/pylib-android/netrc.py": "https://files.ballistica.net/cache/ba1/9a/86/9ca83b316ab5a19a0a2cf22efaf3",
|
||||
"build/assets/pylib-android/nntplib.py": "https://files.ballistica.net/cache/ba1/49/26/aa991bd4b96b9318d6242135abf9",
|
||||
"build/assets/pylib-android/ntpath.py": "https://files.ballistica.net/cache/ba1/36/55/7dc9fdcd9eeeab4d46c1a364bd5a",
|
||||
"build/assets/pylib-android/ntpath.py": "https://files.ballistica.net/cache/ba1/57/ea/cdf2824f306ae2b03d5818294c94",
|
||||
"build/assets/pylib-android/nturl2path.py": "https://files.ballistica.net/cache/ba1/93/76/24c4b6f213b652addea66296ccc4",
|
||||
"build/assets/pylib-android/numbers.py": "https://files.ballistica.net/cache/ba1/0c/dc/b42317422500d514ec67d496a06e",
|
||||
"build/assets/pylib-android/opcode.py": "https://files.ballistica.net/cache/ba1/18/cb/a8b1d09ec6fcccfe20e5b13db980",
|
||||
"build/assets/pylib-android/operator.py": "https://files.ballistica.net/cache/ba1/61/e1/97bc43df97ec39ae3e5e59b11c19",
|
||||
"build/assets/pylib-android/optparse.py": "https://files.ballistica.net/cache/ba1/5f/65/f891612b68c71a2846da86254285",
|
||||
"build/assets/pylib-android/os.py": "https://files.ballistica.net/cache/ba1/36/f9/692131ffb9ba4db510de31afc651",
|
||||
"build/assets/pylib-android/pathlib.py": "https://files.ballistica.net/cache/ba1/3e/8b/893cbe95729cdb6d0cc796e89e19",
|
||||
"build/assets/pylib-android/pdb.py": "https://files.ballistica.net/cache/ba1/da/4c/484348d4b2009479dadd878f20b0",
|
||||
"build/assets/pylib-android/pathlib.py": "https://files.ballistica.net/cache/ba1/09/5e/c821fec243124d0a286b4de3848a",
|
||||
"build/assets/pylib-android/pdb.py": "https://files.ballistica.net/cache/ba1/11/7b/0d24ccb89edc5f183c94f6722f70",
|
||||
"build/assets/pylib-android/pickle.py": "https://files.ballistica.net/cache/ba1/e6/f9/f53d29988454690ccde3279c7c38",
|
||||
"build/assets/pylib-android/pickletools.py": "https://files.ballistica.net/cache/ba1/85/b3/0fba86d32dfc4a588300dedf5f01",
|
||||
"build/assets/pylib-android/pipes.py": "https://files.ballistica.net/cache/ba1/2d/d7/96bdbb87982034234fec50d4526c",
|
||||
"build/assets/pylib-android/pkgutil.py": "https://files.ballistica.net/cache/ba1/37/2a/540a2f2f3a324d5ff8e137579aad",
|
||||
"build/assets/pylib-android/pkgutil.py": "https://files.ballistica.net/cache/ba1/8e/3f/dfcb6c90dc50245aee89c49eb515",
|
||||
"build/assets/pylib-android/platform.py": "https://files.ballistica.net/cache/ba1/07/2a/4f8d700c73429d420ca8f5f3a90d",
|
||||
"build/assets/pylib-android/plistlib.py": "https://files.ballistica.net/cache/ba1/8a/a9/836b7a69628873b25811c4d5fffa",
|
||||
"build/assets/pylib-android/poplib.py": "https://files.ballistica.net/cache/ba1/82/9d/c4df5d8e082ad414d499ec4678bd",
|
||||
"build/assets/pylib-android/posixpath.py": "https://files.ballistica.net/cache/ba1/2a/6b/3f940f89b0819ee002b6b82b0318",
|
||||
"build/assets/pylib-android/pprint.py": "https://files.ballistica.net/cache/ba1/b4/e9/efe35d05b6126d41da36eda47754",
|
||||
"build/assets/pylib-android/profile.py": "https://files.ballistica.net/cache/ba1/4c/08/16d9278d2a33e28835fcd291fb62",
|
||||
"build/assets/pylib-android/profile.py": "https://files.ballistica.net/cache/ba1/a9/f1/1f8aa6a2905706a5fc9273d6c981",
|
||||
"build/assets/pylib-android/pstats.py": "https://files.ballistica.net/cache/ba1/c5/88/4aaae199265ab0c3849d053bc996",
|
||||
"build/assets/pylib-android/pty.py": "https://files.ballistica.net/cache/ba1/1d/e2/d1bfbdc54a770de7b3010d322620",
|
||||
"build/assets/pylib-android/pty.py": "https://files.ballistica.net/cache/ba1/c9/7b/51147360cf7fd92c364ab8068a2b",
|
||||
"build/assets/pylib-android/py_compile.py": "https://files.ballistica.net/cache/ba1/77/2b/429c589d2e005e8bd79b12f55a92",
|
||||
"build/assets/pylib-android/pyclbr.py": "https://files.ballistica.net/cache/ba1/bf/19/89a2c73108005e874a640760476a",
|
||||
"build/assets/pylib-android/pydoc.py": "https://files.ballistica.net/cache/ba1/0f/8a/4b2f4a9d23e429c01660a4290bd8",
|
||||
@ -2960,7 +2960,7 @@
|
||||
"build/assets/pylib-android/selectors.py": "https://files.ballistica.net/cache/ba1/98/e0/d83849452cbc2cc1381555bd5024",
|
||||
"build/assets/pylib-android/shelve.py": "https://files.ballistica.net/cache/ba1/3e/56/9c07c863ecbd7f35a6c382d1785a",
|
||||
"build/assets/pylib-android/shlex.py": "https://files.ballistica.net/cache/ba1/08/73/fac90a491702950816ead0e59dd0",
|
||||
"build/assets/pylib-android/shutil.py": "https://files.ballistica.net/cache/ba1/65/1b/e1edc2110d483c96fbe26f40665d",
|
||||
"build/assets/pylib-android/shutil.py": "https://files.ballistica.net/cache/ba1/ed/25/b38eacc66c9059651e6666ec1869",
|
||||
"build/assets/pylib-android/signal.py": "https://files.ballistica.net/cache/ba1/11/4e/f47b1798fca6f56ac8a250974b3e",
|
||||
"build/assets/pylib-android/site.py": "https://files.ballistica.net/cache/ba1/2a/99/f7de2702aa8411d35acbb91fe926",
|
||||
"build/assets/pylib-android/smtpd.py": "https://files.ballistica.net/cache/ba1/06/02/b6a39c4e37133303bee16c3e28a4",
|
||||
@ -2980,12 +2980,12 @@
|
||||
"build/assets/pylib-android/string.py": "https://files.ballistica.net/cache/ba1/c0/72/d3a2d0337386d3235ba72f292752",
|
||||
"build/assets/pylib-android/stringprep.py": "https://files.ballistica.net/cache/ba1/6a/56/35711a838f76fee7b52537bf8b45",
|
||||
"build/assets/pylib-android/struct.py": "https://files.ballistica.net/cache/ba1/4f/d2/88bd6537effd1d5edbba9d44dde2",
|
||||
"build/assets/pylib-android/subprocess.py": "https://files.ballistica.net/cache/ba1/76/c5/0ab326efee3ecd6b54b3a9d0bd94",
|
||||
"build/assets/pylib-android/subprocess.py": "https://files.ballistica.net/cache/ba1/4d/65/22342cab21c558e60b2f50c5cedc",
|
||||
"build/assets/pylib-android/sunau.py": "https://files.ballistica.net/cache/ba1/a0/34/779289fef0b2221345f40e042680",
|
||||
"build/assets/pylib-android/symtable.py": "https://files.ballistica.net/cache/ba1/0c/d4/a624b2e3304664f43189ed9e3bf7",
|
||||
"build/assets/pylib-android/sysconfig.py": "https://files.ballistica.net/cache/ba1/9f/fa/d6cfff49bc09fe36a33a5446c59d",
|
||||
"build/assets/pylib-android/tabnanny.py": "https://files.ballistica.net/cache/ba1/84/61/4c63ead0ab71527cecdf3de68f1a",
|
||||
"build/assets/pylib-android/tarfile.py": "https://files.ballistica.net/cache/ba1/76/bf/209364cd327ee75e9dac3211c882",
|
||||
"build/assets/pylib-android/tarfile.py": "https://files.ballistica.net/cache/ba1/a6/df/d478cf3917a29020944bff1a6f2d",
|
||||
"build/assets/pylib-android/telnetlib.py": "https://files.ballistica.net/cache/ba1/1a/74/6e1fc988b9f5c12b9fd5a97c00ea",
|
||||
"build/assets/pylib-android/tempfile.py": "https://files.ballistica.net/cache/ba1/43/60/07fbe6821c864a53861bd73b4d43",
|
||||
"build/assets/pylib-android/textwrap.py": "https://files.ballistica.net/cache/ba1/3e/b1/6a40553205dc96be5cb9039f3c8c",
|
||||
@ -2998,22 +2998,22 @@
|
||||
"build/assets/pylib-android/tomllib/_parser.py": "https://files.ballistica.net/cache/ba1/f9/a4/dc92c44403f970e94c2e494a7358",
|
||||
"build/assets/pylib-android/tomllib/_re.py": "https://files.ballistica.net/cache/ba1/0e/50/9117e16c41c491615e06bb98861d",
|
||||
"build/assets/pylib-android/tomllib/_types.py": "https://files.ballistica.net/cache/ba1/07/be/9616d6f5e401fd31fbeea619fc97",
|
||||
"build/assets/pylib-android/trace.py": "https://files.ballistica.net/cache/ba1/c8/60/164b4f4317299db04e29070a163d",
|
||||
"build/assets/pylib-android/traceback.py": "https://files.ballistica.net/cache/ba1/bb/2d/c63a0bcd438697904573807bd392",
|
||||
"build/assets/pylib-android/trace.py": "https://files.ballistica.net/cache/ba1/3d/86/98a2c3ec03dc0f394a2f48c2ffbc",
|
||||
"build/assets/pylib-android/traceback.py": "https://files.ballistica.net/cache/ba1/91/f6/7818e621e3b2f5bf583ed6863ef8",
|
||||
"build/assets/pylib-android/tracemalloc.py": "https://files.ballistica.net/cache/ba1/e4/d1/0d2bee7773566e46797a939e5cbf",
|
||||
"build/assets/pylib-android/tty.py": "https://files.ballistica.net/cache/ba1/27/1c/7d61005a0a3c2c0952efc60dcb6d",
|
||||
"build/assets/pylib-android/types.py": "https://files.ballistica.net/cache/ba1/78/f8/942c08dbfc9c582f1bb8d5206639",
|
||||
"build/assets/pylib-android/typing.py": "https://files.ballistica.net/cache/ba1/c0/7f/a037183494716cd57a7c9ac05d78",
|
||||
"build/assets/pylib-android/typing.py": "https://files.ballistica.net/cache/ba1/89/e0/654fda4fd2a09e93391179859cf0",
|
||||
"build/assets/pylib-android/urllib/__init__.py": "https://files.ballistica.net/cache/ba1/34/0c/83beff7dcff8f5c7b87cd43cedaf",
|
||||
"build/assets/pylib-android/urllib/error.py": "https://files.ballistica.net/cache/ba1/b7/dd/e0483ff647eb87162d6e19c04fa0",
|
||||
"build/assets/pylib-android/urllib/parse.py": "https://files.ballistica.net/cache/ba1/d4/72/83907682d432b511b85dd1e32572",
|
||||
"build/assets/pylib-android/urllib/request.py": "https://files.ballistica.net/cache/ba1/e8/9a/853d76344f1ca197926d49b3b9e6",
|
||||
"build/assets/pylib-android/urllib/parse.py": "https://files.ballistica.net/cache/ba1/dc/73/5bb3e0b069762ad988c1b55ce6e3",
|
||||
"build/assets/pylib-android/urllib/request.py": "https://files.ballistica.net/cache/ba1/09/b8/666fe8319542f7247bb9f8573806",
|
||||
"build/assets/pylib-android/urllib/response.py": "https://files.ballistica.net/cache/ba1/c8/53/7707a4b1e493c0ec4489ab523c93",
|
||||
"build/assets/pylib-android/urllib/robotparser.py": "https://files.ballistica.net/cache/ba1/5a/76/16bdf398c166f953ad48c25506eb",
|
||||
"build/assets/pylib-android/uu.py": "https://files.ballistica.net/cache/ba1/93/26/8d78026ebde74a1ccd14024ae59f",
|
||||
"build/assets/pylib-android/uu.py": "https://files.ballistica.net/cache/ba1/7c/b7/95ca0c9e914550e6245dfe53c53e",
|
||||
"build/assets/pylib-android/uuid.py": "https://files.ballistica.net/cache/ba1/75/5d/75cad456d0c3ab0c67f0276cca32",
|
||||
"build/assets/pylib-android/warnings.py": "https://files.ballistica.net/cache/ba1/e5/f0/b4cbc35aae8d4b89a856b189b626",
|
||||
"build/assets/pylib-android/wave.py": "https://files.ballistica.net/cache/ba1/cb/12/5197ba1b7955bbee4ebde9f385ce",
|
||||
"build/assets/pylib-android/wave.py": "https://files.ballistica.net/cache/ba1/72/7a/8dacad95625ea14554b7d655ce2e",
|
||||
"build/assets/pylib-android/weakref.py": "https://files.ballistica.net/cache/ba1/dd/14/612f02ca8acd723f633b6fff0adf",
|
||||
"build/assets/pylib-android/webbrowser.py": "https://files.ballistica.net/cache/ba1/81/85/b8d83c5311ddea5d88a1cfb89c3c",
|
||||
"build/assets/pylib-android/xdrlib.py": "https://files.ballistica.net/cache/ba1/ee/12/e9067ab4904da935b8d2213426d8",
|
||||
@ -3043,7 +3043,7 @@
|
||||
"build/assets/pylib-android/xmlrpc/client.py": "https://files.ballistica.net/cache/ba1/8f/2c/ad71c1c87031be073184e71aa405",
|
||||
"build/assets/pylib-android/xmlrpc/server.py": "https://files.ballistica.net/cache/ba1/31/47/663bd28b952eef0e1316b94bacc6",
|
||||
"build/assets/pylib-android/zipapp.py": "https://files.ballistica.net/cache/ba1/d9/2e/a793f092af6383a6383678cf7b73",
|
||||
"build/assets/pylib-android/zipfile.py": "https://files.ballistica.net/cache/ba1/21/cd/b798a8f660aa3ec322ce59bddac9",
|
||||
"build/assets/pylib-android/zipfile.py": "https://files.ballistica.net/cache/ba1/2c/d1/a57574daf0ec6456dc2d0858952d",
|
||||
"build/assets/pylib-android/zipimport.py": "https://files.ballistica.net/cache/ba1/6d/3b/32a7258f670eb71daf3a8492a4f1",
|
||||
"build/assets/pylib-android/zoneinfo/__init__.py": "https://files.ballistica.net/cache/ba1/0d/f5/e8a66015e2fe2d77f2e4a5dea1ff",
|
||||
"build/assets/pylib-android/zoneinfo/_common.py": "https://files.ballistica.net/cache/ba1/5b/52/bdac4156dcbac96743fa99468bf2",
|
||||
@ -3064,7 +3064,7 @@
|
||||
"build/assets/pylib-apple/_pyio.py": "https://files.ballistica.net/cache/ba1/a6/e8/8d66fbca88b13213cdd2177390b8",
|
||||
"build/assets/pylib-apple/_sitebuiltins.py": "https://files.ballistica.net/cache/ba1/8b/5e/3f6e73917962fa014ad2c4a55e61",
|
||||
"build/assets/pylib-apple/_strptime.py": "https://files.ballistica.net/cache/ba1/ff/69/9c3f7647db7621bb88c43cc282d3",
|
||||
"build/assets/pylib-apple/_sysconfigdata__darwin_darwin.py": "https://files.ballistica.net/cache/ba1/c8/9e/dcdc08ac22a30cac42dad0f099e6",
|
||||
"build/assets/pylib-apple/_sysconfigdata__darwin_darwin.py": "https://files.ballistica.net/cache/ba1/1d/eb/8b4ea385ac52e2fc30eb5b7486d9",
|
||||
"build/assets/pylib-apple/_sysconfigdata__ios_iphoneos.py": "https://files.ballistica.net/cache/ba1/5b/fc/ed73a12261ecc310bffce6786cd2",
|
||||
"build/assets/pylib-apple/_sysconfigdata__ios_iphoneos_arm64.py": "https://files.ballistica.net/cache/ba1/13/cd/af0612cecdfdea79507be605b5fa",
|
||||
"build/assets/pylib-apple/_sysconfigdata__ios_iphonesimulator.py": "https://files.ballistica.net/cache/ba1/f9/c9/55d9c5c9cf5a0a026d084a1f9519",
|
||||
@ -3075,7 +3075,7 @@
|
||||
"build/assets/pylib-apple/_sysconfigdata__tvos_appletvsimulator.py": "https://files.ballistica.net/cache/ba1/a3/c8/8367fb568e377ef2a72f0e9c2394",
|
||||
"build/assets/pylib-apple/_sysconfigdata__tvos_appletvsimulator_arm64.py": "https://files.ballistica.net/cache/ba1/bf/5e/3b80c0bd0f6e8d00372d4f6f1ae5",
|
||||
"build/assets/pylib-apple/_sysconfigdata__tvos_appletvsimulator_x86_64.py": "https://files.ballistica.net/cache/ba1/48/28/cee78f35df83a94a308919080918",
|
||||
"build/assets/pylib-apple/_sysconfigdata_d_darwin_darwin.py": "https://files.ballistica.net/cache/ba1/1c/01/95f871b00015f14a9fabd2e1f645",
|
||||
"build/assets/pylib-apple/_sysconfigdata_d_darwin_darwin.py": "https://files.ballistica.net/cache/ba1/9e/b9/1d9cd5328d59ceb9047d210beaba",
|
||||
"build/assets/pylib-apple/_sysconfigdata_d_ios_iphoneos.py": "https://files.ballistica.net/cache/ba1/5b/fc/ed73a12261ecc310bffce6786cd2",
|
||||
"build/assets/pylib-apple/_sysconfigdata_d_ios_iphoneos_arm64.py": "https://files.ballistica.net/cache/ba1/11/62/2b9e1d51ef4a4225099acb1e8200",
|
||||
"build/assets/pylib-apple/_sysconfigdata_d_ios_iphonesimulator.py": "https://files.ballistica.net/cache/ba1/f9/c9/55d9c5c9cf5a0a026d084a1f9519",
|
||||
@ -4068,26 +4068,26 @@
|
||||
"build/assets/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/2d/ef/5335207d41b21b9823f6805997f1",
|
||||
"build/assets/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/b0/8a/55e2e77623fe657bea24f223a3ae",
|
||||
"build/assets/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/86/5b/2af4d1e26a1a8073c89acb06e599",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/05/39/9f392f63f9383e8ef3457d08f362",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/ea/05/7ea22ed9c5f1f514b9e39d90cde6",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/46/1c/bd65d52f0848387e56a536a346a5",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/40/b8/fa9aeee2292fde22215797faa75b",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/78/b0/3d856abf820b6410d2729246b3c2",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/a1/85/9ca2209cd2baf659b4e2b40b79fd",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/3b/e4/d49571e34cf479114d9cf4742737",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/e7/b8/53a5666e993663054202393e589b",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/8f/6a/9b8d0b4b6dd97f4d5d4b48f5b84d",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/48/1d/c9762e55356a288aebfefecbd43e",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/14/9f/91b6ce7c3282ae203703618627a9",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/78/71/d5ab66d0f577a746e05f44d753bd",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/33/67/e32865d5160bb26183b8b4257a88",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/85/ba/98322913ba70e71e3858ee7916e5",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/12/37/ca8d54ec589bc95dd9030a635035",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/9f/b7/fdec2c3c131abe175e716698605e",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/08/59/d701c12712effe14b89ea37c013f",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/99/01/8c49ac6d34dc7219ccf047794437",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/51/ae/49b7723adac6c2e763d03bf27b16",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/32/18/35d3b785547afc61cfb6b3ba3504",
|
||||
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/7a/5c/7f2aaa9051adf632dc957f61ef55",
|
||||
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/ae/11/e739a151be864da4c87c15c155fa",
|
||||
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/bc/0c/f1a578e5329a81a91618b03f7029",
|
||||
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/32/e1/c608186cfa17d5ebc93e676166bd",
|
||||
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/0f/b0/bfd562781cf6ae1b0224d76e7c3b",
|
||||
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/f3/a9/1b6cce29b356c2317b6f1126ba9b",
|
||||
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/67/ac/03c3e7d5499a978e2af2099aae55",
|
||||
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/22/c0/4b32851978bf97cccd4c45f71a43",
|
||||
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/90/28/e0d6e0de8df08e0537816c8838a0",
|
||||
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/3d/c5/ffa0a2051e467d002bc272316da6",
|
||||
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/9f/fe/5e9e6873b520b720754ab1794b3c",
|
||||
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/62/8f/4ffeb86197612d84f648141e5dd4",
|
||||
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/b6/ca/46a742136cc8824e171de4c8e683",
|
||||
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/c0/d6/18ad1186b589cd30d0f252b0b542",
|
||||
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/12/df/24c41de1b3bab9d010b17969c69f",
|
||||
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/75/c2/8f3635450156521401ff37c6070c",
|
||||
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/8e/df/6d1d1ef0ed45c6a81f60e7dbc3a5",
|
||||
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/bf/1e/d1bf7b259d98fd464889aa755c22",
|
||||
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/46/1b/20394315126f1f9aa200bd736ad7",
|
||||
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/25/36/a159b2c628f6cbbbcc7aa8f90b12",
|
||||
"build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/be/19/b5458933dfc7371d91ecfcd2e06f",
|
||||
"build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/4e/48/123b806cbe6ddb3d9a8368bbb4f8",
|
||||
"build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/be/19/b5458933dfc7371d91ecfcd2e06f",
|
||||
@ -4104,18 +4104,18 @@
|
||||
"build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/7e/fa/291fd7e935502ced7e99b8c8f7f0",
|
||||
"build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/e1/cb/7e8440699e59e8646da25aa5782b",
|
||||
"build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/7e/fa/291fd7e935502ced7e99b8c8f7f0",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/5c/4e/26f72e68d55dcf12d62b1274b7ad",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/c3/61/d40dfab20f59da7155b942632066",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/a9/f7/ddae4d7e7e59f0b9db4eee09d226",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/4a/a4/c9c09853640eb5a5f5a0ce4cf71c",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/9d/42/a7bc0e69180e2e45e5b5b93cc49c",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/9a/a7/5e31d7b317e4544feff2eabad4a5",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/3b/74/84e7f0fb207da9a99a0c71b12a2e",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/2e/dc/4406fedd025a80037e395097ee19",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/66/17/448c77d6413f25555e40055d154b",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/56/b0/7ce3384cfb63d3a224e317c69fa8",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/b6/73/847160ecfbbbea758f130c03abb8",
|
||||
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/dc/e6/e052a9115ca83686c6634d2c26ff",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/2e/56/390279b063b7f8455cf7f1656608",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/3a/d7/a0329b38db9b594c36ff88a884c9",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/a5/9b/0802a9d6604fffc0136ac95a5be3",
|
||||
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/e9/74/5d6a32e3a161a2f5597aa9336b79",
|
||||
"src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/f8/85/fed7f2ed98ff2ba271f9dbe3391c",
|
||||
"src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/48/4b/e6974f0a4d14be8213dc00d971c3",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/3e/7a/203e2a5d2b5bb42cfe3fd2fe16c2",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "https://files.ballistica.net/cache/ba1/41/38/52cb9a73efef37404cec22fca18e",
|
||||
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "https://files.ballistica.net/cache/ba1/c2/f2/cb8d052d76a1f4abe163cab2276e",
|
||||
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "https://files.ballistica.net/cache/ba1/3c/eb/412513963f0818ab39c58bf292e3",
|
||||
"src/ballistica/core/mgen/pyembed/binding_core.inc": "https://files.ballistica.net/cache/ba1/9d/0a/3c9636138e35284923e0c8311c69",
|
||||
"src/ballistica/core/mgen/pyembed/env.inc": "https://files.ballistica.net/cache/ba1/8b/e4/6e5818f360d10b7b0224a9e91d07",
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
### 1.7.21 (build 21143, api 8, 2023-06-25)
|
||||
### 1.7.21 (build 21147, api 8, 2023-06-26)
|
||||
|
||||
- Fixed an issue where server builds would not always include collision meshes.
|
||||
- Upgraded Python to 3.11.4 on Android builds.
|
||||
- Cleaned up the language subsystem and the process for applying app-config
|
||||
changes a bit. Please holler if you see weirdness in either.
|
||||
|
||||
### 1.7.20 (build 21140, api 8, 2023-06-22)
|
||||
|
||||
@ -360,8 +363,8 @@
|
||||
use log calls instead of prints. The environment vars to enable them are now
|
||||
`BA_DEBUG_LOG_CONNECTIVITY` and `BA_DEBUG_LOG_V2_TRANSPORT`. Set either to '1'
|
||||
to enable debug logging.
|
||||
- (build 21125) Fixed a bug where feature-sets would not have their
|
||||
DoApplyConfig callbacks called in C++, which was causing the server-mode
|
||||
- (build 21125) Fixed a bug where app-modes would not have their
|
||||
DoApplyAppConfig callbacks called in C++, which was causing the server-mode
|
||||
`idle_exit_minutes` value to be ignored. Servers should now properly exit
|
||||
after being idle for this length of time.
|
||||
- (build 21126) Reworked the efrocache system used by public builds for
|
||||
|
||||
@ -21,14 +21,14 @@ with specific naming conventions:
|
||||
in this directory called `featureset_foo_bar.py`.
|
||||
- **Python Package**: If feature set `foo_bar` provides a Python package, it
|
||||
should be a directory named `bafoobar` ('ba' prefix, name with spaces removed)
|
||||
that lives under [Python source files](../../src/assets/ba_data/python).
|
||||
that lives under [src/assets/ba_data/python](../../src/assets/ba_data/python).
|
||||
- **Native Code**: If feature set `foo_bar` provides a native component (C++
|
||||
code or otherwise) it should live in a directory named `foo_bar` (unmodified
|
||||
feature set name) under [native source files](../../src/ballistica).
|
||||
feature set name) under [src/ballistica](../../src/ballistica).
|
||||
- **Meta Package**: If feature set `foo_bar` provides a meta package (that is,
|
||||
code or data used to generate other source code), it should be a directory
|
||||
named `bafoobarmeta` ('ba' prefix, name with spaces removed, 'meta' suffix)
|
||||
that lives under [meta source files](../../src/meta).
|
||||
that lives under [src/meta](../../src/meta).
|
||||
- **Test Package**: If feature set `foo_bar` provides a set of tests, it should
|
||||
be a directory named `test_foo_bar` ('test_' prefix, unmodified feature set
|
||||
name) under [tests](../../tests).
|
||||
|
||||
@ -54,8 +54,8 @@ class App:
|
||||
# pylint: disable=too-many-public-methods
|
||||
|
||||
plugins: PluginSubsystem
|
||||
lang: LanguageSubsystem
|
||||
|
||||
# log_handler: LogHandler
|
||||
health_monitor: AppHealthMonitor
|
||||
|
||||
class State(Enum):
|
||||
@ -247,6 +247,7 @@ class App:
|
||||
self._called_on_app_running = False
|
||||
self._app_paused = False
|
||||
self._subsystem_registration_ended = False
|
||||
self._pending_apply_app_config = False
|
||||
|
||||
# Config.
|
||||
self.config_file_healthy = False
|
||||
@ -281,7 +282,6 @@ class App:
|
||||
|
||||
self.components = AppComponentSubsystem()
|
||||
self.meta = MetadataSubsystem()
|
||||
self.lang = LanguageSubsystem()
|
||||
self.net = NetworkSubsystem()
|
||||
self.workspaces = WorkspaceSubsystem()
|
||||
self._pending_intent: AppIntent | None = None
|
||||
@ -297,7 +297,7 @@ class App:
|
||||
self._asyncio_timer: babase.AppTimer | None = None
|
||||
|
||||
def postinit(self) -> None:
|
||||
"""Called after we are inited and assigned to babase.app."""
|
||||
"""Called after we've been inited and assigned to babase.app."""
|
||||
|
||||
if os.environ.get('BA_RUNNING_WITH_DUMMY_MODULES') == '1':
|
||||
return
|
||||
@ -306,6 +306,7 @@ class App:
|
||||
# some of this stuff accesses babase.app and that doesn't
|
||||
# exist yet as of our __init__() call.
|
||||
|
||||
self.lang = LanguageSubsystem()
|
||||
self.plugins = PluginSubsystem()
|
||||
|
||||
def register_subsystem(self, subsystem: AppSubsystem) -> None:
|
||||
@ -622,6 +623,39 @@ class App:
|
||||
# plugin hasn't already told it to do something.
|
||||
self.set_intent(AppIntentDefault())
|
||||
|
||||
def push_apply_app_config(self) -> None:
|
||||
"""Internal. Use app.config.apply() to apply app config changes."""
|
||||
# To be safe, let's run this by itself in the event loop.
|
||||
# This avoids potential trouble if this gets called mid-draw or
|
||||
# something like that.
|
||||
self._pending_apply_app_config = True
|
||||
_babase.pushcall(self._apply_app_config, raw=True)
|
||||
|
||||
def _apply_app_config(self) -> None:
|
||||
assert _babase.in_logic_thread()
|
||||
|
||||
_babase.lifecyclelog('apply-app-config')
|
||||
|
||||
# If multiple apply calls have been made, only actually apply once.
|
||||
if not self._pending_apply_app_config:
|
||||
return
|
||||
|
||||
_pending_apply_app_config = False
|
||||
|
||||
# Inform all app subsystems in the same order they were inited.
|
||||
# Operate on a copy here because subsystems may still be able to
|
||||
# be added at this point.
|
||||
for subsystem in self._subsystems.copy():
|
||||
try:
|
||||
subsystem.do_apply_app_config()
|
||||
except Exception:
|
||||
logging.exception(
|
||||
'Error in do_apply_app_config for subsystem %s.', subsystem
|
||||
)
|
||||
|
||||
# Let the native layer do its thing.
|
||||
_babase.do_apply_app_config()
|
||||
|
||||
class DefaultAppModeSelector(AppModeSelector):
|
||||
"""Decides which app modes to use to handle intents.
|
||||
|
||||
|
||||
@ -10,6 +10,8 @@ import _babase
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any
|
||||
|
||||
_g_pending_apply = False # pylint: disable=invalid-name
|
||||
|
||||
|
||||
class AppConfig(dict):
|
||||
"""A special dict that holds the game's persistent configuration values.
|
||||
@ -74,8 +76,12 @@ class AppConfig(dict):
|
||||
return _babase.get_appconfig_builtin_keys()
|
||||
|
||||
def apply(self) -> None:
|
||||
"""Apply config values to the running app."""
|
||||
_babase.apply_config()
|
||||
"""Apply config values to the running app.
|
||||
|
||||
This call is thread-safe and asynchronous; changes will happen
|
||||
in the next logic event loop cycle.
|
||||
"""
|
||||
_babase.app.push_apply_app_config()
|
||||
|
||||
def commit(self) -> None:
|
||||
"""Commits the config to local storage.
|
||||
|
||||
@ -47,3 +47,6 @@ class AppSubsystem:
|
||||
|
||||
def on_app_shutdown(self) -> None:
|
||||
"""Called when the app is shutting down."""
|
||||
|
||||
def do_apply_app_config(self) -> None:
|
||||
"""Called when the app config should be applied."""
|
||||
|
||||
@ -9,6 +9,7 @@ import logging
|
||||
from typing import TYPE_CHECKING, overload
|
||||
|
||||
import _babase
|
||||
from babase._appsubsystem import AppSubsystem
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Sequence
|
||||
@ -16,44 +17,21 @@ if TYPE_CHECKING:
|
||||
import babase
|
||||
|
||||
|
||||
class LanguageSubsystem:
|
||||
"""Wraps up language related app functionality.
|
||||
class LanguageSubsystem(AppSubsystem):
|
||||
"""Language functionality for the app.
|
||||
|
||||
Category: **App Classes**
|
||||
|
||||
To use this class, access the single instance of it at 'ba.app.lang'.
|
||||
Access the single instance of this class at 'babase.app.lang'.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.language_target: AttrDict | None = None
|
||||
self.language_merged: AttrDict | None = None
|
||||
self.default_language = self._get_default_language()
|
||||
super().__init__()
|
||||
self.default_language: str = self._get_default_language()
|
||||
|
||||
def _can_display_language(self, language: str) -> bool:
|
||||
"""Tell whether we can display a particular language.
|
||||
|
||||
On some platforms we don't have unicode rendering yet
|
||||
which limits the languages we can draw.
|
||||
"""
|
||||
|
||||
# We don't yet support full unicode display on windows or linux :-(.
|
||||
if (
|
||||
language
|
||||
in {
|
||||
'Chinese',
|
||||
'ChineseTraditional',
|
||||
'Persian',
|
||||
'Korean',
|
||||
'Arabic',
|
||||
'Hindi',
|
||||
'Vietnamese',
|
||||
'Thai',
|
||||
'Tamil',
|
||||
}
|
||||
and not _babase.can_display_full_unicode()
|
||||
):
|
||||
return False
|
||||
return True
|
||||
self._language: str | None = None
|
||||
self._language_target: AttrDict | None = None
|
||||
self._language_merged: AttrDict | None = None
|
||||
|
||||
@property
|
||||
def locale(self) -> str:
|
||||
@ -67,62 +45,16 @@ class LanguageSubsystem:
|
||||
assert isinstance(env['locale'], str)
|
||||
return env['locale']
|
||||
|
||||
def _get_default_language(self) -> str:
|
||||
languages = {
|
||||
'ar': 'Arabic',
|
||||
'be': 'Belarussian',
|
||||
'zh': 'Chinese',
|
||||
'hr': 'Croatian',
|
||||
'cs': 'Czech',
|
||||
'da': 'Danish',
|
||||
'nl': 'Dutch',
|
||||
'eo': 'Esperanto',
|
||||
'fil': 'Filipino',
|
||||
'fr': 'French',
|
||||
'de': 'German',
|
||||
'el': 'Greek',
|
||||
'hi': 'Hindi',
|
||||
'hu': 'Hungarian',
|
||||
'id': 'Indonesian',
|
||||
'it': 'Italian',
|
||||
'ko': 'Korean',
|
||||
'ms': 'Malay',
|
||||
'fa': 'Persian',
|
||||
'pl': 'Polish',
|
||||
'pt': 'Portuguese',
|
||||
'ro': 'Romanian',
|
||||
'ru': 'Russian',
|
||||
'sr': 'Serbian',
|
||||
'es': 'Spanish',
|
||||
'sk': 'Slovak',
|
||||
'sv': 'Swedish',
|
||||
'ta': 'Tamil',
|
||||
'th': 'Thai',
|
||||
'tr': 'Turkish',
|
||||
'uk': 'Ukrainian',
|
||||
'vec': 'Venetian',
|
||||
'vi': 'Vietnamese',
|
||||
}
|
||||
|
||||
# Special case for Chinese: map specific variations to traditional.
|
||||
# (otherwise will map to 'Chinese' which is simplified)
|
||||
if self.locale in ('zh_HANT', 'zh_TW'):
|
||||
language = 'ChineseTraditional'
|
||||
else:
|
||||
language = languages.get(self.locale[:2], 'English')
|
||||
if not self._can_display_language(language):
|
||||
language = 'English'
|
||||
return language
|
||||
|
||||
@property
|
||||
def language(self) -> str:
|
||||
"""The name of the language the game is running in.
|
||||
"""The current active language for the app.
|
||||
|
||||
This can be selected explicitly by the user or may be set
|
||||
automatically based on babase.App.locale or other factors.
|
||||
automatically based on locale or other factors.
|
||||
"""
|
||||
assert isinstance(_babase.app.config, dict)
|
||||
return _babase.app.config.get('Lang', self.default_language)
|
||||
if self._language is None:
|
||||
raise RuntimeError('App language is not yet set.')
|
||||
return self._language
|
||||
|
||||
@property
|
||||
def available_languages(self) -> list[str]:
|
||||
@ -164,13 +96,14 @@ class LanguageSubsystem:
|
||||
print_change: bool = True,
|
||||
store_to_config: bool = True,
|
||||
) -> None:
|
||||
"""Set the active language used for the game.
|
||||
"""Set the active app language.
|
||||
|
||||
Pass None to use OS default language.
|
||||
"""
|
||||
# pylint: disable=too-many-locals
|
||||
# pylint: disable=too-many-statements
|
||||
# pylint: disable=too-many-branches
|
||||
assert _babase.in_logic_thread()
|
||||
cfg = _babase.app.config
|
||||
cur_language = cfg.get('Lang', None)
|
||||
|
||||
@ -215,38 +148,36 @@ class LanguageSubsystem:
|
||||
with open(lmodfile, encoding='utf-8') as infile:
|
||||
lmodvalues = json.loads(infile.read())
|
||||
except Exception:
|
||||
from babase import _error
|
||||
|
||||
_error.print_exception('Exception importing language:', language)
|
||||
logging.exception("Error importing language '%s'.", language)
|
||||
_babase.screenmessage(
|
||||
"Error setting language to '"
|
||||
+ language
|
||||
+ "'; see log for details",
|
||||
f"Error setting language to '{language}'; see log for details.",
|
||||
color=(1, 0, 0),
|
||||
)
|
||||
switched = False
|
||||
lmodvalues = None
|
||||
|
||||
self._language = language
|
||||
|
||||
# Create an attrdict of *just* our target language.
|
||||
self.language_target = AttrDict()
|
||||
langtarget = self.language_target
|
||||
self._language_target = AttrDict()
|
||||
langtarget = self._language_target
|
||||
assert langtarget is not None
|
||||
_add_to_attr_dict(
|
||||
langtarget, lmodvalues if lmodvalues is not None else lenglishvalues
|
||||
)
|
||||
|
||||
# Create an attrdict of our target language overlaid
|
||||
# on our base (english).
|
||||
# Create an attrdict of our target language overlaid on our base
|
||||
# (english).
|
||||
languages = [lenglishvalues]
|
||||
if lmodvalues is not None:
|
||||
languages.append(lmodvalues)
|
||||
lfull = AttrDict()
|
||||
for lmod in languages:
|
||||
_add_to_attr_dict(lfull, lmod)
|
||||
self.language_merged = lfull
|
||||
self._language_merged = lfull
|
||||
|
||||
# Pass some keys/values in for low level code to use;
|
||||
# start with everything in their 'internal' section.
|
||||
# Pass some keys/values in for low level code to use; start with
|
||||
# everything in their 'internal' section.
|
||||
internal_vals = [
|
||||
v for v in list(lfull['internal'].items()) if isinstance(v[1], str)
|
||||
]
|
||||
@ -265,7 +196,7 @@ class LanguageSubsystem:
|
||||
('axisText', lfull['configGamepadWindow']['axisText'])
|
||||
)
|
||||
internal_vals.append(('buttonText', lfull['buttonText']))
|
||||
lmerged = self.language_merged
|
||||
lmerged = self._language_merged
|
||||
assert lmerged is not None
|
||||
random_names = [
|
||||
n.strip() for n in lmerged['randomPlayerNamesText'].split(',')
|
||||
@ -283,6 +214,13 @@ class LanguageSubsystem:
|
||||
color=(0, 1, 0),
|
||||
)
|
||||
|
||||
def do_apply_app_config(self) -> None:
|
||||
assert _babase.in_logic_thread()
|
||||
assert isinstance(_babase.app.config, dict)
|
||||
lang = _babase.app.config.get('Lang', self.default_language)
|
||||
if lang != self._language:
|
||||
self.setlanguage(lang, print_change=False, store_to_config=False)
|
||||
|
||||
def get_resource(
|
||||
self,
|
||||
resource: str,
|
||||
@ -294,38 +232,30 @@ class LanguageSubsystem:
|
||||
DEPRECATED; use babase.Lstr functionality for these purposes.
|
||||
"""
|
||||
try:
|
||||
# If we have no language set, go ahead and set it.
|
||||
if self.language_merged is None:
|
||||
language = self.language
|
||||
# If we have no language set, try and set it to english.
|
||||
# Also make a fuss because we should try to avoid this.
|
||||
if self._language_merged is None:
|
||||
try:
|
||||
if _babase.do_once():
|
||||
logging.warning(
|
||||
'get_resource() called before language'
|
||||
' set; falling back to english.'
|
||||
)
|
||||
self.setlanguage(
|
||||
language, print_change=False, store_to_config=False
|
||||
'English', print_change=False, store_to_config=False
|
||||
)
|
||||
except Exception:
|
||||
from babase import _error
|
||||
|
||||
logging.exception('Error setting language to %s.', language)
|
||||
|
||||
# Try english as a fallback.
|
||||
if language != 'English':
|
||||
print('Resorting to fallback language (English)')
|
||||
try:
|
||||
self.setlanguage(
|
||||
'English',
|
||||
print_change=False,
|
||||
store_to_config=False,
|
||||
)
|
||||
except Exception:
|
||||
_error.print_exception(
|
||||
'error setting language to english fallback'
|
||||
)
|
||||
logging.exception(
|
||||
'Error setting fallback english language.'
|
||||
)
|
||||
raise
|
||||
|
||||
# If they provided a fallback_resource value, try the
|
||||
# target-language-only dict first and then fall back to trying the
|
||||
# fallback_resource value in the merged dict.
|
||||
# target-language-only dict first and then fall back to
|
||||
# trying the fallback_resource value in the merged dict.
|
||||
if fallback_resource is not None:
|
||||
try:
|
||||
values = self.language_target
|
||||
values = self._language_target
|
||||
splits = resource.split('.')
|
||||
dicts = splits[:-1]
|
||||
key = splits[-1]
|
||||
@ -336,11 +266,11 @@ class LanguageSubsystem:
|
||||
val = values[key]
|
||||
return val
|
||||
except Exception:
|
||||
# FIXME: Shouldn't we try the fallback resource in the
|
||||
# merged dict AFTER we try the main resource in the
|
||||
# merged dict?
|
||||
# FIXME: Shouldn't we try the fallback resource in
|
||||
# the merged dict AFTER we try the main resource in
|
||||
# the merged dict?
|
||||
try:
|
||||
values = self.language_merged
|
||||
values = self._language_merged
|
||||
splits = fallback_resource.split('.')
|
||||
dicts = splits[:-1]
|
||||
key = splits[-1]
|
||||
@ -352,14 +282,15 @@ class LanguageSubsystem:
|
||||
return val
|
||||
|
||||
except Exception:
|
||||
# If we got nothing for fallback_resource, default
|
||||
# to the normal code which checks or primary
|
||||
# value in the merge dict; there's a chance we can
|
||||
# get an english value for it (which we weren't
|
||||
# looking for the first time through).
|
||||
# If we got nothing for fallback_resource,
|
||||
# default to the normal code which checks or
|
||||
# primary value in the merge dict; there's a
|
||||
# chance we can get an english value for it
|
||||
# (which we weren't looking for the first time
|
||||
# through).
|
||||
pass
|
||||
|
||||
values = self.language_merged
|
||||
values = self._language_merged
|
||||
splits = resource.split('.')
|
||||
dicts = splits[:-1]
|
||||
key = splits[-1]
|
||||
@ -371,9 +302,9 @@ class LanguageSubsystem:
|
||||
return val
|
||||
|
||||
except Exception:
|
||||
# Ok, looks like we couldn't find our main or fallback resource
|
||||
# anywhere. Now if we've been given a fallback value, return it;
|
||||
# otherwise fail.
|
||||
# Ok, looks like we couldn't find our main or fallback
|
||||
# resource anywhere. Now if we've been given a fallback
|
||||
# value, return it; otherwise fail.
|
||||
from babase import _error
|
||||
|
||||
if fallback_value is not None:
|
||||
@ -426,18 +357,93 @@ class LanguageSubsystem:
|
||||
raise ValueError('Invalid Input; must be length 1')
|
||||
return 0xE000 <= ord(char) <= 0xF8FF
|
||||
|
||||
def _can_display_language(self, language: str) -> bool:
|
||||
"""Tell whether we can display a particular language.
|
||||
|
||||
On some platforms we don't have unicode rendering yet which
|
||||
limits the languages we can draw.
|
||||
"""
|
||||
|
||||
# We don't yet support full unicode display on windows or linux :-(.
|
||||
if (
|
||||
language
|
||||
in {
|
||||
'Chinese',
|
||||
'ChineseTraditional',
|
||||
'Persian',
|
||||
'Korean',
|
||||
'Arabic',
|
||||
'Hindi',
|
||||
'Vietnamese',
|
||||
'Thai',
|
||||
'Tamil',
|
||||
}
|
||||
and not _babase.can_display_full_unicode()
|
||||
):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _get_default_language(self) -> str:
|
||||
languages = {
|
||||
'ar': 'Arabic',
|
||||
'be': 'Belarussian',
|
||||
'zh': 'Chinese',
|
||||
'hr': 'Croatian',
|
||||
'cs': 'Czech',
|
||||
'da': 'Danish',
|
||||
'nl': 'Dutch',
|
||||
'eo': 'Esperanto',
|
||||
'fil': 'Filipino',
|
||||
'fr': 'French',
|
||||
'de': 'German',
|
||||
'el': 'Greek',
|
||||
'hi': 'Hindi',
|
||||
'hu': 'Hungarian',
|
||||
'id': 'Indonesian',
|
||||
'it': 'Italian',
|
||||
'ko': 'Korean',
|
||||
'ms': 'Malay',
|
||||
'fa': 'Persian',
|
||||
'pl': 'Polish',
|
||||
'pt': 'Portuguese',
|
||||
'ro': 'Romanian',
|
||||
'ru': 'Russian',
|
||||
'sr': 'Serbian',
|
||||
'es': 'Spanish',
|
||||
'sk': 'Slovak',
|
||||
'sv': 'Swedish',
|
||||
'ta': 'Tamil',
|
||||
'th': 'Thai',
|
||||
'tr': 'Turkish',
|
||||
'uk': 'Ukrainian',
|
||||
'vec': 'Venetian',
|
||||
'vi': 'Vietnamese',
|
||||
}
|
||||
|
||||
# Special case for Chinese: map specific variations to
|
||||
# traditional. (otherwise will map to 'Chinese' which is
|
||||
# simplified)
|
||||
if self.locale in ('zh_HANT', 'zh_TW'):
|
||||
language = 'ChineseTraditional'
|
||||
else:
|
||||
language = languages.get(self.locale[:2], 'English')
|
||||
if not self._can_display_language(language):
|
||||
language = 'English'
|
||||
return language
|
||||
|
||||
|
||||
class Lstr:
|
||||
"""Used to define strings in a language-independent way.
|
||||
|
||||
Category: **General Utility Classes**
|
||||
|
||||
These should be used whenever possible in place of hard-coded strings
|
||||
so that in-game or UI elements show up correctly on all clients in their
|
||||
currently-active language.
|
||||
These should be used whenever possible in place of hard-coded
|
||||
strings so that in-game or UI elements show up correctly on all
|
||||
clients in their currently-active language.
|
||||
|
||||
To see available resource keys, look at any of the bs_language_*.py files
|
||||
in the game or the translations pages at legacy.ballistica.net/translate.
|
||||
To see available resource keys, look at any of the bs_language_*.py
|
||||
files in the game or the translations pages at
|
||||
legacy.ballistica.net/translate.
|
||||
|
||||
##### Examples
|
||||
EXAMPLE 1: specify a string from a resource path
|
||||
@ -573,10 +579,10 @@ class Lstr:
|
||||
def is_flat_value(self) -> bool:
|
||||
"""Return whether the Lstr is a 'flat' value.
|
||||
|
||||
This is defined as a simple string value incorporating no translations,
|
||||
resources, or substitutions. In this case it may be reasonable to
|
||||
replace it with a raw string value, perform string manipulation on it,
|
||||
etc.
|
||||
This is defined as a simple string value incorporating no
|
||||
translations, resources, or substitutions. In this case it may
|
||||
be reasonable to replace it with a raw string value, perform
|
||||
string manipulation on it, etc.
|
||||
"""
|
||||
return bool('v' in self.args and not self.args.get('s', []))
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Build number and version of the ballistica binary we expect to be
|
||||
# using.
|
||||
TARGET_BALLISTICA_BUILD = 21143
|
||||
TARGET_BALLISTICA_BUILD = 21147
|
||||
TARGET_BALLISTICA_VERSION = '1.7.21'
|
||||
|
||||
_g_env_config: EnvConfig | None = None
|
||||
|
||||
@ -176,10 +176,9 @@ void BaseFeatureSet::StartApp() {
|
||||
|
||||
LogVersionInfo();
|
||||
|
||||
g_core->LifecycleLog("will read config");
|
||||
|
||||
// Read the app config.
|
||||
g_base->python->ReadConfig();
|
||||
// Read in ba.app.config for anyone who wants to start looking at it
|
||||
// (though we don't explicitly ask anyone to apply it until later).
|
||||
python->ReadConfig();
|
||||
|
||||
// Allow our subsystems to start doing work in their own threads and
|
||||
// communicating with other subsystems. Note that we may still want to run
|
||||
@ -188,12 +187,8 @@ void BaseFeatureSet::StartApp() {
|
||||
// devices with the logic thread before the logic thread applies the
|
||||
// current config to them).
|
||||
|
||||
g_core->LifecycleLog("will call python on-main-thread");
|
||||
|
||||
python->OnMainThreadStartApp();
|
||||
g_core->LifecycleLog("will call logic on-main-thread");
|
||||
logic->OnMainThreadStartApp();
|
||||
g_core->LifecycleLog("will call graphics-server on-main-thread");
|
||||
graphics_server->OnMainThreadStartApp();
|
||||
if (bg_dynamics_server) {
|
||||
bg_dynamics_server->OnMainThreadStartApp();
|
||||
@ -209,10 +204,14 @@ void BaseFeatureSet::StartApp() {
|
||||
// if called early.
|
||||
app_running_ = true;
|
||||
|
||||
// As the last step of this phase, tell the logic thread to apply
|
||||
// the app config which will kick off screen creation and otherwise
|
||||
// get the ball rolling.
|
||||
logic->event_loop()->PushCall([this] { logic->ApplyAppConfig(); });
|
||||
// As the last step of this phase, tell the logic thread to apply the app
|
||||
// config which will kick off screen creation and otherwise get the ball
|
||||
// rolling.
|
||||
{
|
||||
Python::ScopedInterpreterLock gil;
|
||||
python->objs().Get(BasePython::ObjID::kPushApplyAppConfigCall).Call();
|
||||
}
|
||||
|
||||
g_core->LifecycleLog("start-app end (main thread)");
|
||||
}
|
||||
|
||||
@ -252,11 +251,6 @@ void BaseFeatureSet::set_app_mode(AppMode* mode) {
|
||||
|
||||
app_mode_->OnActivate();
|
||||
|
||||
// Since app-modes will mostly become active after the initial global
|
||||
// apply-app-config happens, we need to tell them to do so explicitly when
|
||||
// they spin up.
|
||||
app_mode_->DoApplyAppConfig();
|
||||
|
||||
// Let some stuff know.
|
||||
logic->OnAppModeChanged();
|
||||
} catch (const Exception& exc) {
|
||||
|
||||
@ -1111,6 +1111,11 @@ void Graphics::BuildAndPushFrameDef() {
|
||||
assert(g_base->InLogicThread());
|
||||
assert(camera_.Exists());
|
||||
|
||||
// Keep track of when we're in here; can be useful for making sure stuff
|
||||
// doesn't muck with our lists/etc. while we're using them.
|
||||
assert(!building_frame_def_);
|
||||
building_frame_def_ = true;
|
||||
|
||||
// We should not be building/pushing any frames until after
|
||||
// app-launch-commands have been run.
|
||||
BA_PRECONDITION_FATAL(g_base->logic->app_bootstrapping_complete());
|
||||
@ -1234,6 +1239,9 @@ void Graphics::BuildAndPushFrameDef() {
|
||||
blotch_soft_verts_.clear();
|
||||
blotch_soft_obj_indices_.clear();
|
||||
blotch_soft_obj_verts_.clear();
|
||||
|
||||
assert(building_frame_def_);
|
||||
building_frame_def_ = false;
|
||||
}
|
||||
|
||||
void Graphics::DrawBoxingGlovesTest(FrameDef* frame_def) {
|
||||
@ -1541,7 +1549,6 @@ void Graphics::SetSupportsHighQualityGraphics(bool s) {
|
||||
|
||||
void Graphics::ClearScreenMessageTranslations() {
|
||||
assert(g_base && g_base->InLogicThread());
|
||||
|
||||
for (auto&& i : screen_messages_) {
|
||||
i.translation_dirty = true;
|
||||
}
|
||||
@ -2017,6 +2024,10 @@ auto Graphics::ReflectionTypeFromString(const std::string& s)
|
||||
|
||||
void Graphics::LanguageChanged() {
|
||||
assert(g_base && g_base->InLogicThread());
|
||||
if (building_frame_def_) {
|
||||
Log(LogLevel::kWarning,
|
||||
"Graphics::LanguageChanged() called during draw; should not happen.");
|
||||
}
|
||||
// Also clear translations on all screen-messages.
|
||||
ClearScreenMessageTranslations();
|
||||
}
|
||||
|
||||
@ -432,6 +432,7 @@ class Graphics {
|
||||
int64_t frame_def_count_{1};
|
||||
bool gyro_enabled_{true};
|
||||
millisecs_t last_suppress_gyro_time_{};
|
||||
int building_frame_def_{};
|
||||
};
|
||||
|
||||
} // namespace ballistica::base
|
||||
|
||||
@ -25,12 +25,9 @@ Logic::Logic() : display_timers_(new TimerList()) {
|
||||
}
|
||||
|
||||
void Logic::OnMainThreadStartApp() {
|
||||
g_core->LifecycleLog("will create logic loop");
|
||||
|
||||
event_loop_ = new EventLoop(EventLoopID::kLogic);
|
||||
g_core->pausable_event_loops.push_back(event_loop_);
|
||||
|
||||
g_core->LifecycleLog("will push logic on-app-start");
|
||||
// Sit and wait for our logic thread to run its startup stuff.
|
||||
event_loop_->PushCallSynchronous([this] { OnAppStart(); });
|
||||
}
|
||||
@ -144,9 +141,8 @@ void Logic::OnAppShutdown() {
|
||||
[] { g_base->app->LogicThreadShutdownComplete(); });
|
||||
}
|
||||
|
||||
void Logic::ApplyAppConfig() {
|
||||
void Logic::DoApplyAppConfig() {
|
||||
assert(g_base->InLogicThread());
|
||||
g_core->LifecycleLog("apply-app-config");
|
||||
|
||||
// Give all our other subsystems a chance.
|
||||
// Note: keep these in the same order as OnAppStart.
|
||||
|
||||
@ -33,7 +33,7 @@ class Logic {
|
||||
|
||||
void OnAppModeChanged();
|
||||
|
||||
void ApplyAppConfig();
|
||||
void DoApplyAppConfig();
|
||||
void OnScreenSizeChange(float virtual_width, float virtual_height,
|
||||
float pixel_width, float pixel_height);
|
||||
|
||||
|
||||
@ -103,6 +103,7 @@ class BasePython {
|
||||
kOpenURLWithWebBrowserModuleCall,
|
||||
kOnNativeModuleImportCall,
|
||||
kSetupEnvForAppRunCall,
|
||||
kPushApplyAppConfigCall,
|
||||
kLast // Sentinel; must be at end.
|
||||
};
|
||||
|
||||
|
||||
@ -552,24 +552,22 @@ static PyMethodDef PyQuitDef = {
|
||||
|
||||
// ----------------------------- apply_config ----------------------------------
|
||||
|
||||
static auto PyApplyConfig(PyObject* self, PyObject* args) -> PyObject* {
|
||||
static auto PyDoApplyAppConfig(PyObject* self, PyObject* args) -> PyObject* {
|
||||
BA_PYTHON_TRY;
|
||||
|
||||
// Hmm; Python runs in the logic thread; technically we could just run
|
||||
// ApplyAppConfig() immediately (though pushing is probably safer).
|
||||
g_base->logic->event_loop()->PushCall(
|
||||
[] { g_base->logic->ApplyAppConfig(); });
|
||||
BA_PRECONDITION(g_base->InLogicThread());
|
||||
g_base->logic->DoApplyAppConfig();
|
||||
|
||||
Py_RETURN_NONE;
|
||||
BA_PYTHON_CATCH;
|
||||
}
|
||||
|
||||
static PyMethodDef PyApplyConfigDef = {
|
||||
"apply_config", // name
|
||||
PyApplyConfig, // method
|
||||
METH_VARARGS, // flags
|
||||
static PyMethodDef PyDoApplyAppConfigDef = {
|
||||
"do_apply_app_config", // name
|
||||
PyDoApplyAppConfig, // method
|
||||
METH_VARARGS, // flags
|
||||
|
||||
"apply_config() -> None\n"
|
||||
"do_apply_app_config() -> None\n"
|
||||
"\n"
|
||||
"(internal)",
|
||||
};
|
||||
@ -1468,7 +1466,7 @@ auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
|
||||
PyEnvDef,
|
||||
PyPreEnvDef,
|
||||
PyCommitConfigDef,
|
||||
PyApplyConfigDef,
|
||||
PyDoApplyAppConfigDef,
|
||||
PyQuitDef,
|
||||
PyAppTimerDef,
|
||||
PyAppTimeDef,
|
||||
|
||||
@ -1170,6 +1170,7 @@ static auto PySetInternalLanguageKeys(PyObject* self, PyObject* args)
|
||||
BA_PRECONDITION(PyList_Check(random_names_list_obj));
|
||||
std::unordered_map<std::string, std::string> language;
|
||||
int size = static_cast<int>(PyList_GET_SIZE(list_obj));
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
PyObject* entry = PyList_GET_ITEM(list_obj, i);
|
||||
if (!PyTuple_Check(entry) || PyTuple_GET_SIZE(entry) != 2
|
||||
@ -1180,6 +1181,7 @@ static auto PySetInternalLanguageKeys(PyObject* self, PyObject* args)
|
||||
language[PyUnicode_AsUTF8(PyTuple_GET_ITEM(entry, 0))] =
|
||||
PyUnicode_AsUTF8(PyTuple_GET_ITEM(entry, 1));
|
||||
}
|
||||
|
||||
size = static_cast<int>(PyList_GET_SIZE(random_names_list_obj));
|
||||
std::list<std::string> random_names;
|
||||
for (int i = 0; i < size; i++) {
|
||||
@ -1189,6 +1191,7 @@ static auto PySetInternalLanguageKeys(PyObject* self, PyObject* args)
|
||||
}
|
||||
random_names.emplace_back(PyUnicode_AsUTF8(entry));
|
||||
}
|
||||
|
||||
Utils::SetRandomNameList(random_names);
|
||||
assert(g_base->logic);
|
||||
g_base->assets->SetLanguageKeys(language);
|
||||
|
||||
@ -27,7 +27,7 @@ void CorePython::InitPython() {
|
||||
|
||||
// Pre-config as isolated if we include our own Python and as standard
|
||||
// otherwise.
|
||||
PyPreConfig preconfig;
|
||||
PyPreConfig preconfig{};
|
||||
if (g_buildconfig.contains_python_dist()) {
|
||||
PyPreConfig_InitIsolatedConfig(&preconfig);
|
||||
} else {
|
||||
@ -44,7 +44,7 @@ void CorePython::InitPython() {
|
||||
|
||||
// Configure as isolated if we include our own Python and as standard
|
||||
// otherwise.
|
||||
PyConfig config;
|
||||
PyConfig config{};
|
||||
if (g_buildconfig.contains_python_dist()) {
|
||||
PyConfig_InitIsolatedConfig(&config);
|
||||
// We manage paths 100% ourself in this case and don't want any site
|
||||
@ -113,6 +113,7 @@ void CorePython::InitPython() {
|
||||
// Init Python.
|
||||
status = Py_InitializeFromConfig(&config);
|
||||
BA_PRECONDITION_FATAL(!PyStatus_Exception(status));
|
||||
PyConfig_Clear(&config);
|
||||
}
|
||||
|
||||
void CorePython::EnablePythonLoggingCalls() {
|
||||
|
||||
@ -77,7 +77,14 @@ bool SceneV1AppMode::InMainMenu() const {
|
||||
|
||||
static SceneV1AppMode* g_scene_v1_app_mode{};
|
||||
|
||||
void SceneV1AppMode::OnActivate() { Reset(); }
|
||||
void SceneV1AppMode::OnActivate() {
|
||||
Reset();
|
||||
|
||||
// To set initial states, explicitly fire some of our 'On-Foo-Changed'
|
||||
// callbacks.
|
||||
DoApplyAppConfig();
|
||||
LanguageChanged();
|
||||
}
|
||||
|
||||
void SceneV1AppMode::OnAppStart() { assert(g_base->InLogicThread()); }
|
||||
|
||||
@ -1197,6 +1204,7 @@ void SceneV1AppMode::PruneSessions() {
|
||||
}
|
||||
|
||||
void SceneV1AppMode::LanguageChanged() {
|
||||
assert(g_base && g_base->InLogicThread());
|
||||
if (Session* session = GetForegroundSession()) {
|
||||
session->LanguageChanged();
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
|
||||
namespace ballistica {
|
||||
|
||||
// These are set automatically via script; don't modify them here.
|
||||
const int kEngineBuildNumber = 21143;
|
||||
const int kEngineBuildNumber = 21147;
|
||||
const char* kEngineVersion = "1.7.21";
|
||||
|
||||
auto MonolithicMain(const core::CoreConfig& core_config) -> int {
|
||||
|
||||
@ -76,16 +76,9 @@ EventLoop::EventLoop(EventLoopID identifier_in, ThreadSource source)
|
||||
// Block until the thread is bootstrapped.
|
||||
// (maybe not necessary, but let's be cautious in case we'd
|
||||
// try to use things like thread_id before they're known).
|
||||
if (identifier_ == EventLoopID::kLogic) {
|
||||
g_core->LifecycleLog("logic thread bootstrap wait begin");
|
||||
}
|
||||
std::unique_lock lock(client_listener_mutex_);
|
||||
client_listener_cv_.wait(lock, [this] { return bootstrapped_; });
|
||||
|
||||
if (identifier_ == EventLoopID::kLogic) {
|
||||
g_core->LifecycleLog("logic thread bootstrap wait end");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ThreadSource::kWrapMain: {
|
||||
@ -512,7 +505,7 @@ void EventLoop::PushThreadMessage(const ThreadMessage& t) {
|
||||
// So tally up any logs and send them after.
|
||||
std::vector<std::pair<LogLevel, std::string>> log_entries;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(thread_message_mutex_);
|
||||
std::unique_lock lock(thread_message_mutex_);
|
||||
|
||||
// Plop the data on to the list; we're assuming the mutex is locked.
|
||||
thread_messages_.push_back(t);
|
||||
@ -742,11 +735,11 @@ auto EventLoop::CheckPushSafety() -> bool {
|
||||
}
|
||||
}
|
||||
auto EventLoop::CheckPushRunnableSafety() -> bool {
|
||||
std::scoped_lock lock(client_listener_mutex_);
|
||||
std::unique_lock lock(thread_message_mutex_);
|
||||
|
||||
// We first complain when we get to 1000 queued messages so
|
||||
// let's consider things unsafe when we're halfway there.
|
||||
return (thread_messages_.size() < kThreadMessageSafetyThreshold);
|
||||
return thread_messages_.size() < kThreadMessageSafetyThreshold;
|
||||
}
|
||||
|
||||
} // namespace ballistica
|
||||
|
||||
@ -12,4 +12,5 @@ values = [
|
||||
babase.app.handle_deep_link, # kDeepLinkCall
|
||||
babase.app.lang.get_resource, # kGetResourceCall
|
||||
babase.app.lang.translate, # kTranslateCall
|
||||
babase.app.push_apply_app_config, # kPushApplyAppConfigCall
|
||||
]
|
||||
|
||||
@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
||||
|
||||
# Python version we build here (not necessarily same as we use in repo).
|
||||
PY_VER_ANDROID = '3.11'
|
||||
PY_VER_EXACT_ANDROID = '3.11.3'
|
||||
PY_VER_EXACT_ANDROID = '3.11.4'
|
||||
PY_VER_APPLE = '3.11'
|
||||
PY_VER_EXACT_APPLE = '3.11.3'
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user