{
    "listfiles": {
        "//default_config.json": {
            "md5": "521c1fe95499c99e7e60fc41095bbe38",
            "timestamp": 1781548442.2059739,
            "size": 2338
        },
        "//raceline_Race_Test.json": {
            "md5": "31f37740d39ec951c300c5ee43aabd75",
            "timestamp": 1780656891.1344836,
            "size": 72349
        },
        "//notgit.py": {
            "md5": "3419bb032ea7f7921828e0440ea44265",
            "timestamp": 1785329416.4932218,
            "size": 11393
        },
        "//run.py": {
            "md5": "b56431e599092c2d570871ef276a8a3c",
            "timestamp": 1785346427.8011303,
            "size": 81878
        },
        "//SOUNDLICENSES": {
            "md5": "8b81db86d47d47339983b806b382105e",
            "timestamp": 1781005004.6020749,
            "size": 2594
        },
        "//http_server.py": {
            "md5": "850afb5980b3899556c57e36b958d586",
            "timestamp": 1780656891.1344836,
            "size": 8682
        },
        "//grabbed.txt": {
            "md5": "9583039f7fb72a53d3ac8faba5463ac5",
            "timestamp": 1785355988.088641,
            "size": 33662
        },
        "//docs.json": {
            "md5": "d63e9223ddfbcf975fee08505423ab91",
            "timestamp": 1785347900.695209,
            "size": 462129
        },
        "//Tux_license.txt": {
            "md5": "1d013aa1f15664f9d6ce85d1d144243f",
            "timestamp": 1780656891.1934836,
            "size": 1187
        },
        "//logo.png": {
            "md5": "321d4ffa9036b43147c4c924f3023851",
            "timestamp": 1780656891.1934836,
            "size": 552799
        },
        "//DanisRaceDebug.txt": {
            "md5": "ebb92418c0714477f8c6b289fe26a9b1",
            "timestamp": 1780656891.1924837,
            "size": 172
        },
        "//assembly.blend": {
            "md5": "e447934be5e295d9174cf3cd0ad3a1f5",
            "timestamp": 1785340059.1567903,
            "size": 259674007
        },
        "//names.json": {
            "md5": "3fde35ff2e8b1d1f63cea21706a9421e",
            "timestamp": 1780656891.1934836,
            "size": 1169
        },
        "//search.py": {
            "md5": "6b20a1bd92501c7cd0cdeb5b2fdfed9f",
            "timestamp": 1780656891.7154837,
            "size": 1564
        },
        "//Update_Force.py": {
            "md5": "f94f17eeabf16ee8dc45f17fc6b0a9f6",
            "timestamp": 1780656891.1344836,
            "size": 4268
        },
        "//build.py": {
            "md5": "14b57819884943cd82e233deffdfdc35",
            "timestamp": 1781549406.5650253,
            "size": 2733
        },
        "//ScriptSnippits.txt": {
            "md5": "e42ba34766773284b8a109e28089af33",
            "timestamp": 1780656891.1354837,
            "size": 6460
        },
        "//depsgraph_research.blend": {
            "md5": "de388324074df5877f9f8aba8f95fab2",
            "timestamp": 1780656891.1924837,
            "size": 1066714
        },
        "//LICENSE": {
            "md5": "118f8289dcca48f7095059c77b5632a6",
            "timestamp": 1780656891.1934836,
            "size": 494
        },
        "//checklist.org": {
            "md5": "7c986b598bdaacc8feeac002817cf54c",
            "timestamp": 1780656891.1354837,
            "size": 8403
        },
        "/textures/palm_cutout.png": {
            "md5": "ad91c96cd2147326d282d8a33369a997",
            "timestamp": 1780656891.8354836,
            "size": 104527
        },
        "/textures/MoriasFace.png": {
            "md5": "572cfe4c9f52e6475d6bf99c88c28459",
            "timestamp": 1780656891.8094838,
            "size": 2212819
        },
        "/textures/top_left_corner.png": {
            "md5": "ca18fc3714603edca69b3e1999e1607a",
            "timestamp": 1780656891.8074837,
            "size": 54874
        },
        "/textures/grey_black.jpg": {
            "md5": "90ec6be675d13dd83f593375dedb9301",
            "timestamp": 1780656891.7474837,
            "size": 1316
        },
        "/textures/city_night.jpg": {
            "md5": "0edab60d64cdc5d65af1f2321d8545c6",
            "timestamp": 1780656891.8024836,
            "size": 596434
        },
        "/textures/islands_foam.png": {
            "md5": "cbabef3b361734be3c813326e12c8573",
            "timestamp": 1780656891.8224838,
            "size": 169399
        },
        "/textures/city_day.jpg": {
            "md5": "12672bbe0c4bd0b2051570322af47bfd",
            "timestamp": 1780656891.7474837,
            "size": 3430059
        },
        "/textures/crash_3000_light_dots.png": {
            "md5": "b573878585a0555a3f188b7e550d4955",
            "timestamp": 1780656891.8634837,
            "size": 88304
        },
        "/textures/Underground_front_screen.png": {
            "md5": "8f90426dec001c8e7865918ba5867a88",
            "timestamp": 1780656891.8234837,
            "size": 158612
        },
        "/textures/dirt_normal.jpg": {
            "md5": "3c9b5ca68262e10da731ce3efda1c418",
            "timestamp": 1780656891.8074837,
            "size": 135345
        },
        "/textures/Dani_Franzo.png": {
            "md5": "553ab3da959a1de48a1b7da6ba7bbad0",
            "timestamp": 1781720642.8111703,
            "size": 360894
        },
        "/textures/wheel-board.png": {
            "md5": "e4d18199a0cbf35c4c0b01a87ef7858d",
            "timestamp": 1780656891.8044837,
            "size": 82357
        },
        "/textures/LogoHat.png": {
            "md5": "c1eef09926d8bc9e2b85b82fcf760f4e",
            "timestamp": 1780656891.8094838,
            "size": 68534
        },
        "/textures/driftsmoke.png": {
            "md5": "02b0adf82ed71f7f64151a89c58ef1bb",
            "timestamp": 1780863056.311494,
            "size": 16517
        },
        "/textures/Shoenormal.png": {
            "md5": "00adde3dcfa6c07c471f526a1133b4cb",
            "timestamp": 1780656891.8354836,
            "size": 321210
        },
        "/textures/karting_place_screen.jpg": {
            "md5": "eea7cf08755088bfe62e5eb0da292bc6",
            "timestamp": 1780656891.8344836,
            "size": 46937
        },
        "/textures/fence.blend": {
            "md5": "c19a05abd91d96377fb87d7262a2a9c3",
            "timestamp": 1780656891.8234837,
            "size": 840076
        },
        "/textures/cliff.jpg": {
            "md5": "417ceff26b4bb580671bb746fe83d8c0",
            "timestamp": 1780656891.8354836,
            "size": 679722
        },
        "/textures/suzanne.headLight.png": {
            "md5": "25fba0b4536dbe669794876d51f1f3e4",
            "timestamp": 1780656891.8344836,
            "size": 25457
        },
        "/textures/books.png": {
            "md5": "38f8292a9f6313af474a977720cecef3",
            "timestamp": 1780656891.8214836,
            "size": 2584614
        },
        "/textures/Simulator_screen2.hdr": {
            "md5": "f0be817807b175eb5b2658e107afd7f3",
            "timestamp": 1780656891.7994838,
            "size": 6506069
        },
        "/textures/racetrack_day.jpg": {
            "md5": "1d0e7a820a6d63a7dc6190c696dbefb0",
            "timestamp": 1780656891.7474837,
            "size": 1157828
        },
        "/textures/GlovesNormal.png": {
            "md5": "81b2f7ea998b84fb51d5dc6a81b7f4a5",
            "timestamp": 1780656891.8064837,
            "size": 1387469
        },
        "/textures/city_evening.jpg": {
            "md5": "3458eba697329a503491c268e24fe5ac",
            "timestamp": 1780656891.7304838,
            "size": 3397892
        },
        "/textures/bed_texture.jpg": {
            "md5": "b17114ea6e5ef6bd76fc0a1d7f509a99",
            "timestamp": 1780656891.7194836,
            "size": 30168
        },
        "/textures/basketball.jpg": {
            "md5": "0b1890f5870224cd07ee5e98afb75103",
            "timestamp": 1780656891.8714836,
            "size": 75099
        },
        "/textures/Dani_Travis.png": {
            "md5": "58f00b86f8c907e0a877a12281380240",
            "timestamp": 1783972056.569589,
            "size": 361578
        },
        "/textures/DaniS_BED-c.png": {
            "md5": "ced3021514e06e84dfdd5e9f4de95979",
            "timestamp": 1780656891.8094838,
            "size": 65105
        },
        "/textures/Dani_Emo_01.png": {
            "md5": "fb0f00d52c8209c07a8109487892d05d",
            "timestamp": 1781791579.3159587,
            "size": 354225
        },
        "/textures/dirt.jpg": {
            "md5": "d5112bca719b21f080c7e54ac76c0166",
            "timestamp": 1780656891.7314837,
            "size": 73881
        },
        "/textures/black.png": {
            "md5": "cca283bf0345adb7d75197cc8c138dd6",
            "timestamp": 1780656891.7314837,
            "size": 568
        },
        "/textures/eyes.jpg": {
            "md5": "883bdd9c215ef22bf58d71ba25d8b26f",
            "timestamp": 1780656891.8344836,
            "size": 188611
        },
        "/textures/treerings.jpg": {
            "md5": "f2a85551943f479ad20f205455139922",
            "timestamp": 1780656891.8464837,
            "size": 96809
        },
        "/textures/money.png": {
            "md5": "514f6754b0977336a9c0ad385a975004",
            "timestamp": 1782163360.4944813,
            "size": 82903
        },
        "/textures/gnomeLogo.png": {
            "md5": "dfe6e3775128b7b1051c46250f2000b6",
            "timestamp": 1780656891.7334836,
            "size": 41130
        },
        "/textures/tuxwheel.png": {
            "md5": "e1de30dc7bb6457a6aaa2ee78606836c",
            "timestamp": 1780656891.8204837,
            "size": 1273503
        },
        "/textures/icons.png": {
            "md5": "eb37c5462c0f8337b78de287f40cac47",
            "timestamp": 1784556120.8199234,
            "size": 1403284
        },
        "/textures/racer_indicator.png": {
            "md5": "a0e8243a7b05f61771a90ccff7d83f9d",
            "timestamp": 1780656891.8234837,
            "size": 87030
        },
        "/textures/Bark_Tile.jpg": {
            "md5": "6c5a51ada2189c99cbb42f88d1b61012",
            "timestamp": 1780656891.7224836,
            "size": 764959
        },
        "/textures/Simulator_screen.hdr": {
            "md5": "4840bd72478d2b9b6932cf08f05efd6b",
            "timestamp": 1780656891.8454838,
            "size": 6451580
        },
        "/textures/gage.png": {
            "md5": "b7b8f47e2a454ae29f9eb2ba5a0758ee",
            "timestamp": 1780656891.8214836,
            "size": 588520
        },
        "/textures/front_part.png": {
            "md5": "d6114eccdb7b00719fe7d890b5196795",
            "timestamp": 1780656891.7224836,
            "size": 31994
        },
        "/textures/windows.png": {
            "md5": "5befda39db3d10974e6a34df51d9f6a2",
            "timestamp": 1780656891.8714836,
            "size": 666
        },
        "/textures/Dani_Metal_01.png": {
            "md5": "31e2cc52f965b1170ae25c4dde680141",
            "timestamp": 1781791896.4069755,
            "size": 417660
        },
        "/textures/leather.jpg": {
            "md5": "f4042158ad00d5b4e78deb5a1ab4c07b",
            "timestamp": 1780656891.8454838,
            "size": 65536
        },
        "/textures/racetrack_evening.jpg": {
            "md5": "422877aaa5e93d5b5486591d36ed6b55",
            "timestamp": 1780656891.7334836,
            "size": 4682832
        },
        "/textures/textures_licenses.txt": {
            "md5": "c54ed2e2cff1af6c2111c26b3a4c4c95",
            "timestamp": 1780656891.8204837,
            "size": 88
        },
        "/textures/icecream_shop.png": {
            "md5": "399d8097acd088a7d555dcb54696ea9f",
            "timestamp": 1781907270.3528047,
            "size": 27178
        },
        "/textures/city_morning.jpg": {
            "md5": "8a456e05f6d5e29259b7ce13a7cf4953",
            "timestamp": 1780656891.7344837,
            "size": 3429529
        },
        "/textures/Dani_Daniel.png": {
            "md5": "86d63a853777840a96a85142954b0806",
            "timestamp": 1784289773.5372791,
            "size": 406492
        },
        "/textures/underground_dots_lines.png": {
            "md5": "b286cff1da058d6cb0f069b846dfe2f0",
            "timestamp": 1780656891.8104837,
            "size": 473940
        },
        "/textures/hallway_images.jpg": {
            "md5": "5d50baf6179e3cebc2e884087bcba387",
            "timestamp": 1780656891.8004837,
            "size": 3349627
        },
        "/textures/screen.png": {
            "md5": "5b792b0f839407f128a4f019aaf52bfb",
            "timestamp": 1780656891.8234837,
            "size": 10811
        },
        "/textures/28.hdr": {
            "md5": "94566294debec09b9a044b626801141b",
            "timestamp": 1780656891.8344836,
            "size": 10285256
        },
        "/textures/Paps_Office_Graph.jpg": {
            "md5": "199f1fd5244b39bf0bbbe4266eb4e9fb",
            "timestamp": 1780656891.8224838,
            "size": 150160
        },
        "/textures/Light_dots.png": {
            "md5": "9af12b74dde2271bf2d8b1ea6ab103ce",
            "timestamp": 1780656891.8004837,
            "size": 94047
        },
        "/textures/arrows.png": {
            "md5": "1a8677d914c3b934ff9598b85601047e",
            "timestamp": 1780656891.7304838,
            "size": 55587
        },
        "/textures/Dani_Like_01.png": {
            "md5": "712906aee9bbafcb8c282fe956db4904",
            "timestamp": 1781873567.8830047,
            "size": 599688
        },
        "/textures/banner_full.jpg": {
            "md5": "3fc905b1b70d694f1f2691a6272b6095",
            "timestamp": 1780656891.8054836,
            "size": 1393518
        },
        "/textures/fire_element2.jpg": {
            "md5": "979d19e4d8b7208ff99ad10a30aa71df",
            "timestamp": 1780656891.8204837,
            "size": 61625
        },
        "/textures/sings.png": {
            "md5": "b06a6d069ca51702c7ee9cd6fac3157f",
            "timestamp": 1780656891.8204837,
            "size": 196920
        },
        "/textures/Dani_Chabad_01.png": {
            "md5": "1c6dafec5512945a1beb2ba542a7d456",
            "timestamp": 1781374748.7216976,
            "size": 260620
        },
        "/textures/screen_background.jpg": {
            "md5": "962122cf3e93cfcf3196ed75c8c38167",
            "timestamp": 1780656891.8454838,
            "size": 18361
        },
        "/textures/racers_wallapapers.png": {
            "md5": "89079a59834b78956b61013861f094d5",
            "timestamp": 1780656891.8704836,
            "size": 3305105
        },
        "/textures/racetrack_morning.jpg": {
            "md5": "9b0f90053bdb740f60c822d9843634c5",
            "timestamp": 1780656891.8024836,
            "size": 4731610
        },
        "/textures/dirt_road.jpg": {
            "md5": "5c120a17d01bf16cfc926abdb670268b",
            "timestamp": 1781016124.0276687,
            "size": 204874
        },
        "/textures/GlovesColor.png": {
            "md5": "f40965b05f4e14063c13da79d25a59f6",
            "timestamp": 1780656891.8464837,
            "size": 99080
        },
        "/textures/fire_element1.jpg": {
            "md5": "6b88db0ecfc9d0c12830e0ffbe985b0c",
            "timestamp": 1780656891.8194838,
            "size": 135855
        },
        "/textures/Kippa.png": {
            "md5": "d3a20bf4e6ae39fdc27ba29069ec3d0d",
            "timestamp": 1780656891.7394836,
            "size": 543769
        },
        "/textures/MoriasPijama.jpg": {
            "md5": "604f0b6098a74c80875c51d6ddc6658d",
            "timestamp": 1780656891.7194836,
            "size": 46955
        },
        "/textures/NeonSpeedster_leather.jpg": {
            "md5": "02bb21912dca6d862c5920cbf1cbf915",
            "timestamp": 1780656891.8064837,
            "size": 74824
        },
        "/textures/NightLightBake.jpg": {
            "md5": "e9f1e98c30f32c0c3ab67df23064f215",
            "timestamp": 1780656891.7474837,
            "size": 714588
        },
        "/textures/dirt_road_normal.jpg": {
            "md5": "04aa3010de958c13f7c13509f4eaf38c",
            "timestamp": 1781016366.7736816,
            "size": 301308
        },
        "/textures/blank_paper.png": {
            "md5": "42e65a532d98dd8c0da0815465af8851",
            "timestamp": 1780656891.8094838,
            "size": 13416
        },
        "/textures/Dani_Punk_shirt.png": {
            "md5": "fc4568bbe7a77cc959882ffaa097b8ff",
            "timestamp": 1781874131.7770348,
            "size": 158156
        },
        "/textures/palm_trunk.jpg": {
            "md5": "b9fd56e7195dee4da91c156885f795c1",
            "timestamp": 1780656891.8194838,
            "size": 112703
        },
        "/textures/300.png": {
            "md5": "49be47af4e32fce9f341ce072768c6df",
            "timestamp": 1780656891.8064837,
            "size": 50776
        },
        "/textures/paps_screen_background.jpg": {
            "md5": "0bae35cc344c40d1070261d7f44ab2b2",
            "timestamp": 1780656891.8624837,
            "size": 74087
        },
        "/textures/JacksBodyTexture.png": {
            "md5": "294ab70b1134043259295b7ab04fd45e",
            "timestamp": 1780656891.8094838,
            "size": 968590
        },
        "/textures/DaniS_BED-b.png": {
            "md5": "4787cedd6bc194622ae253870f8aebbd",
            "timestamp": 1780656891.8034837,
            "size": 216437
        },
        "/textures/computer_UI_mocks.xcf": {
            "md5": "6d8099e2ff267689ae393c5f6c5a67e3",
            "timestamp": 1780656891.8344836,
            "size": 313038
        },
        "/textures/Dani_Punk.png": {
            "md5": "ab523984b58ff227664352ff86be30af",
            "timestamp": 1782844213.6368427,
            "size": 387910
        },
        "/textures/JackFace.png": {
            "md5": "da37ce8c5d2e54e8a75d563060c3b048",
            "timestamp": 1780656891.7224836,
            "size": 2976540
        },
        "/textures/Logo.jpg": {
            "md5": "72607e8dbe95889a595664ee6ce29304",
            "timestamp": 1780656891.8094838,
            "size": 43808
        },
        "/textures/concrete_03.jpg": {
            "md5": "98ba4a82840f817470e58369998f5c54",
            "timestamp": 1780656891.7194836,
            "size": 7812479
        },
        "/textures/shrubbery.png": {
            "md5": "1f75076294857b0e39a933853c8cc499",
            "timestamp": 1780656891.8714836,
            "size": 838475
        },
        "/textures/boxify.png": {
            "md5": "f9dcdecd01095d6301a88d3077be9910",
            "timestamp": 1780656891.8454838,
            "size": 8322
        },
        "/textures/suzanne.stktex_monkey_a.png": {
            "md5": "e12d2f5f4c3d53be38c99fb31f6e1fe3",
            "timestamp": 1780656891.8234837,
            "size": 743903
        },
        "/textures/tux_body.png": {
            "md5": "e256f0860b320158d738a872175e6ab0",
            "timestamp": 1780656891.8044837,
            "size": 2771118
        },
        "/textures/tower_cutout.png": {
            "md5": "cf6ede4a3a20b45c95eb6e04dc04261f",
            "timestamp": 1780656891.8074837,
            "size": 108520
        },
        "/textures/DaniPhoneTexture.png": {
            "md5": "303fd208071f52524ed2429c845a605d",
            "timestamp": 1780656891.7314837,
            "size": 2985093
        },
        "/textures/oak-branch-c.png": {
            "md5": "487694bf0360b016607e2581e1caa3a1",
            "timestamp": 1780656891.8204837,
            "size": 180717
        },
        "/textures/computer_instructions.png": {
            "md5": "e695869af37481effd46a93bf54d90ff",
            "timestamp": 1780656891.8074837,
            "size": 72641
        },
        "/textures/tuxengine.png": {
            "md5": "d93082b87ad7ac5c1124567abb4667b9",
            "timestamp": 1780656891.8214836,
            "size": 1316840
        },
        "/textures/Simulator_screen_second_layer.png": {
            "md5": "8697cd028156b4b0c7a08963f14ec0a3",
            "timestamp": 1780656891.7324836,
            "size": 24932
        },
        "/textures/Ground.jpg": {
            "md5": "0f86ed8c181e609201167159530af8ec",
            "timestamp": 1780656891.7384837,
            "size": 7960300
        },
        "/textures/taxi.png": {
            "md5": "e7ae041a9c0bba96e977d07e9af9b355",
            "timestamp": 1780656891.8714836,
            "size": 2674
        },
        "/textures/oak-branch-a.png": {
            "md5": "607cda18613a61c788eb675abce34615",
            "timestamp": 1780656891.7394836,
            "size": 74104
        },
        "/textures/map.jpg": {
            "md5": "a7598db4fab79bd79efcc2a89a70ca26",
            "timestamp": 1783185847.826088,
            "size": 1657131
        },
        "/textures/Morias_BED-c.png": {
            "md5": "c06ae14248a5431e7fb7fb63f34d746f",
            "timestamp": 1780656891.7354836,
            "size": 64526
        },
        "/textures/palmleaf_managable.png": {
            "md5": "d68227f17713313a8302454d263626e5",
            "timestamp": 1780656891.8074837,
            "size": 505885
        },
        "/textures/drinks.png": {
            "md5": "6bae4db42f5704012ff77abbcad7cb44",
            "timestamp": 1781953561.6352768,
            "size": 135940
        },
        "/textures/Dani_Ozoned.png": {
            "md5": "8dccf2adbd40383940ad72e195b194f8",
            "timestamp": 1782844577.4098623,
            "size": 458035
        },
        "/textures/tuxkart.png": {
            "md5": "88fcdabcdac0238c43e9b0223222bd03",
            "timestamp": 1780656891.8454838,
            "size": 1341586
        },
        "/textures/FaceTextureCM1.png": {
            "md5": "c82285adf7d471794fefacc6d906e481",
            "timestamp": 1780656891.8104837,
            "size": 804336
        },
        "/textures/Bark_normal.png": {
            "md5": "21aa38eb43761f40e8e79f058a08c97f",
            "timestamp": 1780656891.8314836,
            "size": 4617093
        },
        "/textures/MoriasRacingOutfit.png": {
            "md5": "639fd6779e3ee3e3ba9661a382b95a0a",
            "timestamp": 1780656891.8194838,
            "size": 92827
        },
        "/textures/plastic_bullshit.jpg": {
            "md5": "f377b2cbe892ed3f796e44c28783ca2f",
            "timestamp": 1780656891.8024836,
            "size": 5939
        },
        "/textures/racetrack_night.jpg": {
            "md5": "eb9e632a3193ca8cdf10afadb4984855",
            "timestamp": 1780656891.8064837,
            "size": 1737007
        },
        "/textures/metal_fence.png": {
            "md5": "b6f9cae734d6fa2e69b74e314b4f36d0",
            "timestamp": 1780656891.8234837,
            "size": 166142
        },
        "/textures/satara_night_4k.exr": {
            "md5": "ecffa6df8be0620fecef90dfea5a3ae0",
            "timestamp": 1780656891.8624837,
            "size": 31958672
        },
        "/textures/Suzanne.Wheel.diffuse.jpg": {
            "md5": "4205c30e5c22b318a81fa6b6738dc778",
            "timestamp": 1780656891.7324836,
            "size": 42108
        },
        "/textures/cardboard.jpg": {
            "md5": "2c68b7a303e5cbb157c8ceb8dd3d8766",
            "timestamp": 1780656891.8714836,
            "size": 1320287
        },
        "/textures/Angry_Puruit.png": {
            "md5": "3d5d855a8ef27a8b4fa7fe6d948438a8",
            "timestamp": 1780656891.7994838,
            "size": 42905
        },
        "/textures/smoke_element1.jpg": {
            "md5": "7c187a8266c81c84f7b4218f87c9690f",
            "timestamp": 1780656891.8704836,
            "size": 30554
        },
        "/textures/Red_kiss_neon.png": {
            "md5": "f0266bac5e19bb733121ae4686551659",
            "timestamp": 1780656891.8224838,
            "size": 95602
        },
        "/textures/lightdots.png": {
            "md5": "3f006124a91ae1361868fb41f3de9741",
            "timestamp": 1780656891.8344836,
            "size": 23894
        },
        "/textures/colorwheel.png": {
            "md5": "c09b08a8a3ec135f8febff20f7e511d4",
            "timestamp": 1784413784.4943218,
            "size": 21289
        },
        "/textures/0026.jpg": {
            "md5": "3d43ca465326ed37f1680ce2114cca1d",
            "timestamp": 1780656891.8044837,
            "size": 848341
        },
        "/textures/tower_infographic.jpg": {
            "md5": "d170292cebda58c7da4be01934d153c6",
            "timestamp": 1780656891.8464837,
            "size": 1128607
        },
        "/textures/DanisFace.png": {
            "md5": "a167c9373e7f3c90a5d27442e3df5dc1",
            "timestamp": 1781376367.853784,
            "size": 943388
        },
        "/textures/nitros.jpg": {
            "md5": "bbb54a4c1a285e5b94a7ec9711bfdac1",
            "timestamp": 1780656891.8454838,
            "size": 47807
        },
        "/textures/computer_instructions.jpg": {
            "md5": "a1f5010d93b9d6ae97590770c85324c5",
            "timestamp": 1780656891.8464837,
            "size": 34914
        },
        "/textures/wood_fence.jpg": {
            "md5": "aad0167946cb6daf5b9ad86f8bcc134c",
            "timestamp": 1780656891.8054836,
            "size": 342096
        },
        "/textures/stk_screenshot.jpg": {
            "md5": "24da931ce62ec852125ccb123752dca3",
            "timestamp": 1780656891.7474837,
            "size": 308053
        },
        "/textures/bush.png": {
            "md5": "476676299f45696e28d9d5d81ae8b10e",
            "timestamp": 1780656891.8464837,
            "size": 162963
        },
        "/textures/green_tree_cutout.png": {
            "md5": "924d111bd085346911b2cebdfe2a64f4",
            "timestamp": 1780656891.8624837,
            "size": 373861
        },
        "/textures/PapsFaceTexture.png": {
            "md5": "4e8b79d85d1a118bf41ef8e32fd56e2e",
            "timestamp": 1780656891.7314837,
            "size": 1413405
        },
        "/textures/rug.jpg": {
            "md5": "9808f4b8d0e4bdd0572ba79f1cdf1d38",
            "timestamp": 1780656891.8234837,
            "size": 26795
        },
        "/textures/Suzanne.kart.diffuse.png": {
            "md5": "184636d8ada3e44ab34c1010ef02db6e",
            "timestamp": 1780656891.8224838,
            "size": 1953256
        },
        "/textures/wasted_screenshot.jpg": {
            "md5": "9e8d753ea0faa383c7c9c576433808b9",
            "timestamp": 1780656891.8054836,
            "size": 404386
        },
        "/textures/primary.png": {
            "md5": "8b98ea485147b6900d6eb117b0478cc0",
            "timestamp": 1780656891.7324836,
            "size": 559
        },
        "/textures/Normalmap.png": {
            "md5": "79c6f27f2fa53105bc719f6823c35430",
            "timestamp": 1780656891.8074837,
            "size": 2244765
        },
        "/textures/front_light.png": {
            "md5": "22822463674279b49a8fba73a428dbfa",
            "timestamp": 1780656891.8064837,
            "size": 28721
        },
        "/textures/ads.png": {
            "md5": "dfaa5fd7f8962d98342ca91c67f64495",
            "timestamp": 1782084322.9782603,
            "size": 6589295
        },
        "/textures/loading.jpg": {
            "md5": "7c027a916036df3f752a6364700c4a3a",
            "timestamp": 1780656891.7204835,
            "size": 1399824
        },
        "/textures/eyes_brown.jpg": {
            "md5": "a088140a507d18a92ddc01c20df8e841",
            "timestamp": 1780656891.8054836,
            "size": 205927
        },
        "/textures/policescreen.jpg": {
            "md5": "73d7fb4c5370f78050ed8f1863c4bf57",
            "timestamp": 1780656891.8214836,
            "size": 44554
        },
        "/textures/nitros.xcf": {
            "md5": "00be8ea2ff98bb9a2b22e56b63442a79",
            "timestamp": 1780656891.7314837,
            "size": 86546
        },
        "/textures/computericons/icons.png": {
            "md5": "89d53c0f91f3c20f08d05b2c49f46063",
            "timestamp": 1780656891.8714836,
            "size": 324700
        },
        "/textures/towers/tower_infographic_04.jpg": {
            "md5": "43ae66053f010b75598faa87d7ed3675",
            "timestamp": 1780656891.8724837,
            "size": 223785
        },
        "/textures/towers/tower_infographic_02.jpg": {
            "md5": "5a362fd0960941b0aff8029f5187a0e5",
            "timestamp": 1780656891.8724837,
            "size": 223659
        },
        "/textures/towers/tower_infographic_01.jpg": {
            "md5": "2ad12bb2818defdbd38a6c810d224d31",
            "timestamp": 1780656891.8714836,
            "size": 225412
        },
        "/textures/towers/tower_infographic_05.jpg": {
            "md5": "f5c2ae089c8510551d57bc5ff68c9b2b",
            "timestamp": 1780656891.8714836,
            "size": 223891
        },
        "/textures/towers/tower_infographic_03.jpg": {
            "md5": "b067a4d149601f211d847a12bc367d50",
            "timestamp": 1780656891.8724837,
            "size": 223105
        },
        "/textures/PHONE/normal.png": {
            "md5": "11e58c7d694203af8a26a37323546ad0",
            "timestamp": 1780656891.8904836,
            "size": 221941
        },
        "/textures/PHONE/screen.png": {
            "md5": "b2ea64618e95b391e985b4bfb618aa9c",
            "timestamp": 1780656891.8904836,
            "size": 15069
        },
        "/textures/PHONE/alpha.png": {
            "md5": "f2047667cbcff81523135e720455217a",
            "timestamp": 1780656891.8894837,
            "size": 14415
        },
        "/textures/PHONE/strips_of_light.png": {
            "md5": "749ac1aa1b208c767586fbd8555d8626",
            "timestamp": 1780656891.8904836,
            "size": 20964
        },
        "/textures/PHONE/color.png": {
            "md5": "2d5314c9088d4b5fa72e269587485439",
            "timestamp": 1780656891.8904836,
            "size": 550342
        },
        "/textures/PHONE/gloss.png": {
            "md5": "4f0c8981dd601192fe2dbd2f853cd03a",
            "timestamp": 1780656891.8904836,
            "size": 16636
        },
        "/textures/sky/city_night.jpg": {
            "md5": "0edab60d64cdc5d65af1f2321d8545c6",
            "timestamp": 1780656891.8854837,
            "size": 596434
        },
        "/textures/sky/city_day.jpg": {
            "md5": "12672bbe0c4bd0b2051570322af47bfd",
            "timestamp": 1780656891.8844836,
            "size": 3430059
        },
        "/textures/sky/racetrack_day.jpg": {
            "md5": "1d0e7a820a6d63a7dc6190c696dbefb0",
            "timestamp": 1780656891.8734837,
            "size": 1157828
        },
        "/textures/sky/city_evening.jpg": {
            "md5": "3458eba697329a503491c268e24fe5ac",
            "timestamp": 1780656891.8734837,
            "size": 3397892
        },
        "/textures/sky/racetrack_evening.jpg": {
            "md5": "422877aaa5e93d5b5486591d36ed6b55",
            "timestamp": 1780656891.8814836,
            "size": 4682832
        },
        "/textures/sky/city_morning.jpg": {
            "md5": "8a456e05f6d5e29259b7ce13a7cf4953",
            "timestamp": 1780656891.8824837,
            "size": 3429529
        },
        "/textures/sky/racetrack_morning.jpg": {
            "md5": "9b0f90053bdb740f60c822d9843634c5",
            "timestamp": 1780656891.8884838,
            "size": 4731610
        },
        "/textures/sky/racetrack_night.jpg": {
            "md5": "eb9e632a3193ca8cdf10afadb4984855",
            "timestamp": 1780656891.8814836,
            "size": 1737007
        },
        "/textures/wasted_kart/cardetails1.png": {
            "md5": "dc9d6761c746f01d77b254bb84fe6698",
            "timestamp": 1780656891.8894837,
            "size": 38687
        },
        "/textures/wasted_kart/carbody.png": {
            "md5": "99a4e9baa49173540868dd021e20cc3c",
            "timestamp": 1780656891.8894837,
            "size": 12509
        },
        "/textures/wasted_kart/cardetails2.png": {
            "md5": "346bbe41ae8d20024eddf856ac295571",
            "timestamp": 1780656891.8894837,
            "size": 40953
        },
        "/textures/wasted_kart/tailights.png": {
            "md5": "b0331bc3fbd9569e332a33951f13421f",
            "timestamp": 1780656891.8894837,
            "size": 16497
        },
        "/textures/wasted_kart/gigastires.png": {
            "md5": "2271424109e98072bf4683c9cdd9e766",
            "timestamp": 1780656891.8894837,
            "size": 9955
        },
        "/textures/wasted_kart/gigasrims.png": {
            "md5": "8f8f32efc915e2242109498f05706c6e",
            "timestamp": 1780656891.8894837,
            "size": 16497
        },
        "/configs/02_medium.json": {
            "md5": "fea96ba0d5b3b2f403fe47585511c18c",
            "timestamp": 1780656892.4794836,
            "size": 1375
        },
        "/configs/01_low.json": {
            "md5": "de37186207a5c620b10f3dab4eba1486",
            "timestamp": 1780656892.4794836,
            "size": 1324
        },
        "/configs/04_ultra.json": {
            "md5": "faa588cc08e7ba1641ed6d8a3bc02aed",
            "timestamp": 1780656892.4794836,
            "size": 1344
        },
        "/configs/00_potato.json": {
            "md5": "ebaae02493a368f169284b452b965462",
            "timestamp": 1780656892.4794836,
            "size": 1338
        },
        "/configs/03_high.json": {
            "md5": "849f2f9e82fce2c8396c829274bf26f8",
            "timestamp": 1780656892.4794836,
            "size": 1311
        },
        "/bgelogic/__init__.py": {
            "md5": "d41d8cd98f00b204e9800998ecf8427e",
            "timestamp": 1780656891.9284837,
            "size": 0
        },
        "/bgelogic/NLNodeTree.py": {
            "md5": "639005085d6df5305e3a72d538a51b3a",
            "timestamp": 1780656891.9294837,
            "size": 1990
        },
        "/ast/Shared_Materials.blend": {
            "md5": "2ba868ce2d90f83a418c6fc7cbf90fee",
            "timestamp": 1782911008.01141,
            "size": 1228900
        },
        "/ast/loc/city.blend": {
            "md5": "daa2bad8078309f1f203a3c012ea6bf7",
            "timestamp": 1780656892.0064836,
            "size": 76534384
        },
        "/ast/loc/City_source.blend": {
            "md5": "238358d4b4bf4c35dff080c1aefd5996",
            "timestamp": 1780656892.0464838,
            "size": 51363924
        },
        "/ast/loc/textures/cliff.jpg": {
            "md5": "417ceff26b4bb580671bb746fe83d8c0",
            "timestamp": 1780656892.1354837,
            "size": 679722
        },
        "/ast/loc/textures/dirt.jpg": {
            "md5": "e9925cc23c81371b1d6a82dfa134e4ca",
            "timestamp": 1780656892.1324837,
            "size": 87496
        },
        "/ast/loc/textures/sings.png": {
            "md5": "b06a6d069ca51702c7ee9cd6fac3157f",
            "timestamp": 1780656892.1344836,
            "size": 196920
        },
        "/ast/loc/textures/Ground.jpg": {
            "md5": "0f86ed8c181e609201167159530af8ec",
            "timestamp": 1780656892.1344836,
            "size": 7960300
        },
        "/ast/loc/textures/bush.png": {
            "md5": "476676299f45696e28d9d5d81ae8b10e",
            "timestamp": 1780656892.1354837,
            "size": 162963
        },
        "/ast/loc/textures/ads.png": {
            "md5": "66d07d279a6990303b443c894d1749ba",
            "timestamp": 1780656892.1324837,
            "size": 2952724
        },
        "/ast/chr/Moria.blend": {
            "md5": "655cfe1ce59f703320bed0f14f44d689",
            "timestamp": 1780656892.1454837,
            "size": 4171356
        },
        "/ast/chr/Paps.blend": {
            "md5": "3666b06af74d1a022e41dba4fba6f4bc",
            "timestamp": 1780656892.1444836,
            "size": 8886096
        },
        "/ast/chr/Jack.blend": {
            "md5": "d592f066fef4ad394d7623111fcb5f06",
            "timestamp": 1780656892.1614838,
            "size": 3216064
        },
        "/ast/chr/Man1.blend": {
            "md5": "7ac18797a1f80a9c6bb8a7e9effd972b",
            "timestamp": 1780656892.1644838,
            "size": 3331472
        },
        "/ast/veh/RedKiss.blend": {
            "md5": "7a761a2198f0bec93c0c8206dea3df69",
            "timestamp": 1780656892.1774838,
            "size": 3567785
        },
        "/ast/veh/NeonSpeedster.blend": {
            "md5": "557849aa84cebb9bb2d237a21caf4088",
            "timestamp": 1780656892.1854837,
            "size": 3267060
        },
        "/ast/veh/Truck.blend": {
            "md5": "1db16d66eb1cae9e14346b8cc875fff8",
            "timestamp": 1780656892.1734836,
            "size": 7213536
        },
        "/ast/veh/HatchBack01.blend": {
            "md5": "58a69db1d1155a181d3e240faf5ea918",
            "timestamp": 1780656892.1904836,
            "size": 2152392
        },
        "/ast/veh/DarkShadow.blend": {
            "md5": "79d20b3213cd9b0d71d056b924dd9bdd",
            "timestamp": 1780656892.1694837,
            "size": 2686620
        },
        "/ast/veh/HatchBack02.blend": {
            "md5": "a15be69ce7c80d08d318f6ce242732fa",
            "timestamp": 1780656892.1914837,
            "size": 2051544
        },
        "/ast/veh/Underground.blend": {
            "md5": "af2e7cea7d65fb917e65b275a5f1883a",
            "timestamp": 1780656892.1744838,
            "size": 3440551
        },
        "/ast/veh/Scooter.blend": {
            "md5": "ddf43354799083bc6905325b76d3a8a6",
            "timestamp": 1780656892.1874838,
            "size": 1885780
        },
        "/ast/veh/Kart.blend": {
            "md5": "5fc20ac31b244deb489cfdd7a31d6ca5",
            "timestamp": 1780656892.1864836,
            "size": 1723204
        },
        "/ast/veh/textures/Paps_Truck_Texture.png": {
            "md5": "14c19b7db234750aa081d05b520360af",
            "timestamp": 1780656892.2024837,
            "size": 5239263
        },
        "/ast/veh/textures/gear_lever.png": {
            "md5": "36b486f87800b4e979afaea77a1dd587",
            "timestamp": 1780656892.1924837,
            "size": 28314
        },
        "/ast/veh/textures/Front_lights.png": {
            "md5": "d8b41aeef4a3d967848f0aaf712b4b72",
            "timestamp": 1780656892.2024837,
            "size": 46939
        },
        "/ast/veh/textures/gear_mechanism.png": {
            "md5": "7f8e5a72a58db3d6b52475a49976aa6a",
            "timestamp": 1780656892.1924837,
            "size": 2527
        },
        "/ast/veh/textures/light_dots.png": {
            "md5": "a013a39f564c11ec084ffab6c32b9f3e",
            "timestamp": 1780656892.2034836,
            "size": 25997
        },
        "/ast/veh/textures/front_part.png": {
            "md5": "d6114eccdb7b00719fe7d890b5196795",
            "timestamp": 1780656892.2024837,
            "size": 31994
        },
        "/ast/veh/textures/leather.jpg": {
            "md5": "f4042158ad00d5b4e78deb5a1ab4c07b",
            "timestamp": 1780656892.2034836,
            "size": 65536
        },
        "/ast/veh/textures/tire_text.png": {
            "md5": "4111c922465d62a26eafc2bb2d5fb5b2",
            "timestamp": 1780656892.2024837,
            "size": 7838
        },
        "/ast/veh/textures/scren.png": {
            "md5": "95d2cb298a9a60fb8a49b625d2f86d4b",
            "timestamp": 1780656892.2024837,
            "size": 9522
        },
        "/ast/veh/textures/screen.png": {
            "md5": "5b792b0f839407f128a4f019aaf52bfb",
            "timestamp": 1780656892.2024837,
            "size": 10811
        },
        "/ast/veh/textures/Light_dots.png": {
            "md5": "9af12b74dde2271bf2d8b1ea6ab103ce",
            "timestamp": 1780656892.2024837,
            "size": 94047
        },
        "/ast/veh/textures/truck_map.jpg": {
            "md5": "43fb5607702a27970149b5893295b1f0",
            "timestamp": 1780656892.2024837,
            "size": 72560
        },
        "/ast/veh/textures/LightLInes.png": {
            "md5": "b9e12f4dc327744339263b55a606a4c5",
            "timestamp": 1780656892.2024837,
            "size": 100908
        },
        "/ast/veh/textures/map_UI_Over.png": {
            "md5": "b3fc4ceb7bb34fca92e27e9f7bc4122a",
            "timestamp": 1780656892.2034836,
            "size": 16445
        },
        "/ast/veh/textures/Paps_Truck_Texture_TEXT2.png": {
            "md5": "9a289ce09dbfda198a82c7150794681e",
            "timestamp": 1780656892.2024837,
            "size": 125047
        },
        "/ast/veh/textures/Paps_Truck_Texture_TEXT.png": {
            "md5": "1ef652a0e4c44ab00e9dd36d80df8daf",
            "timestamp": 1780656892.2024837,
            "size": 123486
        },
        "/ast/veh/textures/blue_kiss.jpg": {
            "md5": "7e0eb1a05e95b7249185e724cfd00a8c",
            "timestamp": 1780656892.2024837,
            "size": 70548
        },
        "/ast/veh/textures/Red_kiss_neon.png": {
            "md5": "f0266bac5e19bb733121ae4686551659",
            "timestamp": 1780656892.2024837,
            "size": 95602
        },
        "/ast/veh/textures/lightdots.png": {
            "md5": "3f006124a91ae1361868fb41f3de9741",
            "timestamp": 1780656892.2024837,
            "size": 23894
        },
        "/ast/veh/textures/map.png": {
            "md5": "b09e7f9d491f425906e375f11d6a75c2",
            "timestamp": 1780656892.1924837,
            "size": 335671
        },
        "/ast/veh/textures/front_light.png": {
            "md5": "22822463674279b49a8fba73a428dbfa",
            "timestamp": 1780656892.2034836,
            "size": 28721
        },
        "/ast/veh/bgelogic/__init__.py": {
            "md5": "d41d8cd98f00b204e9800998ecf8427e",
            "timestamp": 1780656892.2034836,
            "size": 0
        },
        "/ast/veh/bgelogic/NLNodeTree.py": {
            "md5": "639005085d6df5305e3a72d538a51b3a",
            "timestamp": 1780656892.2034836,
            "size": 1990
        },
        "/cardata/NeonSpeedsterBox.json": {
            "md5": "753937285f01077f3ae908fef654faf1",
            "timestamp": 1780741710.9550135,
            "size": 1789
        },
        "/cardata/HatchBack01Box.json": {
            "md5": "d08c52abecb5b01a83faa9ed1e782424",
            "timestamp": 1780745039.0991912,
            "size": 1604
        },
        "/cardata/HatchBack02Box.json": {
            "md5": "8a8ce298e744ac9a48464e7c90869e39",
            "timestamp": 1780745294.1312048,
            "size": 1617
        },
        "/cardata/TruckBox.json": {
            "md5": "a6dbe5a98c6382a0adb6bd5465ad3fec",
            "timestamp": 1780656892.2034836,
            "size": 2035
        },
        "/cardata/ScootBox.json": {
            "md5": "1f06db1b873bb6d6b49dca330186bfaa",
            "timestamp": 1780708264.9662273,
            "size": 1812
        },
        "/cardata/KartBox.json": {
            "md5": "d81745475d25e69b488100eaa6eb857e",
            "timestamp": 1780656892.2034836,
            "size": 1523
        },
        "/cardata/DarkShadowBox.json": {
            "md5": "c3e167fecbf0077308c80fb39c537366",
            "timestamp": 1780743099.6420877,
            "size": 1795
        },
        "/cardata/RedKissBox.json": {
            "md5": "6adfcdf5d6e52a35dac02e8b55b6e286",
            "timestamp": 1780740532.0999506,
            "size": 1801
        },
        "/cardata/UndergroundBox.json": {
            "md5": "f05b19dad26b0469dffbdb513eb4e933",
            "timestamp": 1780743191.0030925,
            "size": 1793
        },
        "/music/level_01.ogg": {
            "md5": "00a449f2eb52ee6804e3f74d35e382f8",
            "timestamp": 1780656891.9014838,
            "size": 11774424
        },
        "/music/licenses.md": {
            "md5": "508a88d9dcf65578b1cb8b7c7b96bb52",
            "timestamp": 1780656891.9154837,
            "size": 89
        },
        "/music/drums.ogg": {
            "md5": "75e11dc830d411dc9dbe04a332c21895",
            "timestamp": 1780656891.8904836,
            "size": 331308
        },
        "/music/level_02.ogg": {
            "md5": "5150d61f259f2087b8774c9a32a4d219",
            "timestamp": 1780656891.9044836,
            "size": 11547637
        },
        "/music/level_03.ogg": {
            "md5": "a4b7110d4cb03562ff628b064a692e96",
            "timestamp": 1780656891.9144835,
            "size": 11339045
        },
        "/music/level_04.ogg": {
            "md5": "50e2ff0aeaaf205d0b8514d94d6a297f",
            "timestamp": 1780656891.9284837,
            "size": 16306476
        },
        "/fonts/OFL.txt": {
            "md5": "a823ce5fe7b1e7054be5a477f67ff5e3",
            "timestamp": 1780656892.2044837,
            "size": 4549
        },
        "/fonts/Economica-Regular.ttf": {
            "md5": "cf6c76be23e40276a6dc88d315ea4199",
            "timestamp": 1780656892.2044837,
            "size": 25412
        },
        "/fonts/Economica-Italic.ttf": {
            "md5": "8d40caedd6e5b6a84d875056826e8f51",
            "timestamp": 1780656892.2044837,
            "size": 26364
        },
        "/fonts/Economica-BoldItalic.ttf": {
            "md5": "55c9edb637d6eaf29fe60e2295bde94e",
            "timestamp": 1780656892.2044837,
            "size": 25656
        },
        "/fonts/Economica-Bold.ttf": {
            "md5": "1d72c18e8a3355b4fcbbad37c4b11463",
            "timestamp": 1780656892.2044837,
            "size": 25852
        },
        "/ScreenPlay/ScriptSnippits.txt": {
            "md5": "e42ba34766773284b8a109e28089af33",
            "timestamp": 1780656891.7154837,
            "size": 6460
        },
        "/ScreenPlay/phrases.txt": {
            "md5": "78f7cd924c2f522222b684621fa9e188",
            "timestamp": 1780656891.7154837,
            "size": 163
        },
        "/ScreenPlay/scene3.fountain": {
            "md5": "c9ec41b5303ff3d2d42cbf90b1fd3928",
            "timestamp": 1780656891.7154837,
            "size": 4562
        },
        "/racedata/raceline_Race_Test.json": {
            "md5": "dc85aa0bd9a734c0af809ef830f3e5c8",
            "timestamp": 1780656892.2044837,
            "size": 75896
        },
        "/racedata/raceline_Race_ToRaceTrackAndBack.json": {
            "md5": "faa6119a124b798d532eeddf8b3f5bb4",
            "timestamp": 1780656892.2044837,
            "size": 52736
        },
        "/racedata/record_Race_3_Buildings.json": {
            "md5": "6c0f45b08125af1bc35ae1d23ed85ab8",
            "timestamp": 1780656892.2044837,
            "size": 2288
        },
        "/racedata/raceline_Scooter_Race.json": {
            "md5": "20f5bf4814abaaa836bb8bfff208f3da",
            "timestamp": 1780656892.2044837,
            "size": 64481
        },
        "/racedata/raceline_SkatePark_Race.json": {
            "md5": "0efbd6ec76d409818cc4913b3fe3fe9a",
            "timestamp": 1780670436.135207,
            "size": 39877
        },
        "/racedata/raceline_Mall_Skate_Race.json": {
            "md5": "80919127b4010ed206178d1c78250306",
            "timestamp": 1783890678.8642428,
            "size": 64419
        },
        "/racedata/raceline_Race_Highway.json": {
            "md5": "3fee934047f4298a4ab38592548d88f6",
            "timestamp": 1780656892.2044837,
            "size": 107859
        },
        "/racedata/raceline_Crazy_Stunt_Race.json": {
            "md5": "62e8bdff9308c2b23a6e353d6fd6ca84",
            "timestamp": 1783179494.6447487,
            "size": 88664
        },
        "/racedata/raceline_Race_DuneTown_Sign.json": {
            "md5": "e4c91a906b2bb0b5bfbb39330b683071",
            "timestamp": 1780667901.0840716,
            "size": 38352
        },
        "/racedata/raceline_Grove_Race_1.json": {
            "md5": "556fb22bae633d909d085ac7cedca7aa",
            "timestamp": 1780656892.2044837,
            "size": 38210
        },
        "/racedata/raceline_Race_Parking_Lot.json": {
            "md5": "1d8de9ad9e2de562dc0b21c392579a64",
            "timestamp": 1780656892.2044837,
            "size": 24846
        },
        "/racedata/old-data-01.json": {
            "md5": "c0920ad6b0d6dc030b05c1b32cad909f",
            "timestamp": 1780656892.2044837,
            "size": 5423
        },
        "/racedata/raceline_RacetrackRace.json": {
            "md5": "df921739ee7539d334c28abace6a9950",
            "timestamp": 1780656892.2044837,
            "size": 54496
        },
        "/racedata/race_targets_SkatePark_Race.json": {
            "md5": "e0e7563aed01fc4c3cc87bd75e0a40c2",
            "timestamp": 1780670279.2161987,
            "size": 3394
        },
        "/racedata/raceline_Hills_Street_Cars_Race.json": {
            "md5": "b4c716645ec1e6e8738446c0e0a0f167",
            "timestamp": 1782676375.9628794,
            "size": 6347
        },
        "/racedata/raceline_Green_House_Race.json": {
            "md5": "e82cfcbddf9e3aa75069728539701f0b",
            "timestamp": 1784467377.9531841,
            "size": 62203
        },
        "/racedata/raceline_Race_Spiral_Bottom.json": {
            "md5": "acd502a38d1b19112fe062853b3f7aee",
            "timestamp": 1780779741.2700446,
            "size": 12684
        },
        "/racedata/raceline_Race_BigBuilding.json": {
            "md5": "2c70ca6f69d915959791de3f5f646fcd",
            "timestamp": 1780656892.2044837,
            "size": 31320
        },
        "/racedata/raceline_Race_Pito.json": {
            "md5": "8c68a7ebc73fa7191ca2c5142e177811",
            "timestamp": 1780656892.2044837,
            "size": 22171
        },
        "/racedata/record_Race_Highway.json": {
            "md5": "966f07d0c77a2529cf2415e8e8bbb176",
            "timestamp": 1780656892.2044837,
            "size": 2712
        },
        "/racedata/raceline_Race_Around_Highway.json": {
            "md5": "52eae319daa624621f232a01f1ba5744",
            "timestamp": 1781106011.5064692,
            "size": 27953
        },
        "/racedata/raceline_Race_3_Buildings.json": {
            "md5": "1b1da39d8be04973be622118b44165a8",
            "timestamp": 1780697183.3476355,
            "size": 84688
        },
        "/racedata/Race_Test_stupid-01.json": {
            "md5": "0cabdcde080b715e8515f850fe23e05f",
            "timestamp": 1780656892.2044837,
            "size": 5374
        },
        "/racedata/Race_ToRaceTrackAndBack/data-01.json": {
            "md5": "ed63d197f5e677910f25a7468e9770d5",
            "timestamp": 1780656892.2044837,
            "size": 5955
        },
        "/racedata/Race_Pito/data-01.json": {
            "md5": "db74f90ee83fda28f50455014ecf3b35",
            "timestamp": 1780656892.2044837,
            "size": 2501
        },
        "/racedata/Race_Test/stupid-02.json": {
            "md5": "c66bb496fdcaa96e98f2b03eaaea53d4",
            "timestamp": 1780656892.2054837,
            "size": 5424
        },
        "/racedata/Race_Highway/race_targets_Race_Highway.json": {
            "md5": "0134ef89c3ea7383630fb89f47989eda",
            "timestamp": 1780656892.2054837,
            "size": 13335
        },
        "/racedata/Race_BigBuilding/data_01.json": {
            "md5": "11e7cbf11b1c8574eaa6316e04ca7d2b",
            "timestamp": 1780656892.2054837,
            "size": 2560
        },
        "/racedata/Race_Parking_Lot/race_targets_Race_Parking_Lot.json": {
            "md5": "45ba64ac0ebc4560beba21818dbca6da",
            "timestamp": 1780656892.2054837,
            "size": 3701
        },
        "/racedata/RacetrackRace/data-01.json": {
            "md5": "3dc266d16b3c03a7c656574edaa57426",
            "timestamp": 1780656892.2054837,
            "size": 8706
        },
        "/sfx/hit.ogg": {
            "md5": "5803533bebbc46a5d72eff39c804e294",
            "timestamp": 1780656892.2244837,
            "size": 32506
        },
        "/sfx/grind.ogg": {
            "md5": "c0a1e92c9d81bdaa0bb3d79affc76550",
            "timestamp": 1780656892.2234836,
            "size": 1449433
        },
        "/sfx/nitro.ogg": {
            "md5": "35e8436c787ebb9661cdbac161cdb511",
            "timestamp": 1780656892.2054837,
            "size": 91365
        },
        "/sfx/horn.ogg": {
            "md5": "85cca6d14031fd2dc04a6c5a1bc49e28",
            "timestamp": 1780656892.2234836,
            "size": 17660
        },
        "/sfx/police.ogg": {
            "md5": "f1a71db74ac9745a4e5d0d3b1277a298",
            "timestamp": 1780656892.2054837,
            "size": 157344
        },
        "/sfx/home_door.ogg": {
            "md5": "362521737598767428dc187b583792c3",
            "timestamp": 1780656892.2244837,
            "size": 61158
        },
        "/sfx/gravel.ogg": {
            "md5": "06ec89beebdac7e97c11ed7c443c31ed",
            "timestamp": 1781005552.446104,
            "size": 140272
        },
        "/sfx/checkpoint.ogg": {
            "md5": "24e582207dfe35fee9649cbbf1e2888d",
            "timestamp": 1780656892.2234836,
            "size": 42556
        },
        "/sfx/money.ogg": {
            "md5": "9215e0ec2c4d3543c3a67081ba46e5b5",
            "timestamp": 1780656892.2234836,
            "size": 26798
        },
        "/sfx/splash.ogg": {
            "md5": "a980e9c342165764b2a161f0f4f828c5",
            "timestamp": 1780656892.2054837,
            "size": 43259
        },
        "/sfx/swoosh.ogg": {
            "md5": "f84127e063f8cdde7af4372f789faf82",
            "timestamp": 1780656892.2244837,
            "size": 35328
        },
        "/sfx/heart.ogg": {
            "md5": "bca65d2f393802403ec404cf07025e24",
            "timestamp": 1780656892.2934837,
            "size": 116724
        },
        "/sfx/rocket_launch.ogg": {
            "md5": "1eeeab53b479e064590ad5224b88f1d9",
            "timestamp": 1781527171.5698378,
            "size": 33314
        },
        "/sfx/.xdp-telephone_EQ.png-R2HduU": {
            "md5": "b4907a3b1d050a83ddaa37e7fa86c5e3",
            "timestamp": 1780656892.2234836,
            "size": 26274
        },
        "/sfx/wood.ogg": {
            "md5": "156ee1e5c52c2abe4955354917fff7d8",
            "timestamp": 1780656892.2234836,
            "size": 13146
        },
        "/sfx/fixtool.ogg": {
            "md5": "810064ac6da13f36c33eeb38a73ad21a",
            "timestamp": 1780656892.2234836,
            "size": 39915
        },
        "/sfx/glass.ogg": {
            "md5": "9a3d88396a853aaa0da500093a305c9a",
            "timestamp": 1780656892.2054837,
            "size": 34171
        },
        "/sfx/active.ogg": {
            "md5": "50ea0c0fb96298136ff65da3bfae3267",
            "timestamp": 1780656892.2234836,
            "size": 49330
        },
        "/sfx/gear_shit.ogg": {
            "md5": "f8ced51ad630fe515995957b8a5a9484",
            "timestamp": 1780656892.2234836,
            "size": 19725
        },
        "/sfx/map.xcf": {
            "md5": "b109c2d1483a945d711f3d509a979d3f",
            "timestamp": 1780656892.2224836,
            "size": 35183332
        },
        "/sfx/scrape.ogg": {
            "md5": "9c4ba930712f1d2f9b59dc781c31edee",
            "timestamp": 1780656892.2234836,
            "size": 30823
        },
        "/sfx/door.ogg": {
            "md5": "2c69cd3c818fed36e91a28c101d66fd5",
            "timestamp": 1780656892.2234836,
            "size": 31914
        },
        "/sfx/boom.ogg": {
            "md5": "4d82da2feaefa3105169d578fbc01c11",
            "timestamp": 1781816668.7812986,
            "size": 75948
        },
        "/sfx/drift.ogg": {
            "md5": "2ea90354f657b9ed90bf97b0d7931347",
            "timestamp": 1780656892.2054837,
            "size": 56648
        },
        "/sfx/air_decompressed.ogg": {
            "md5": "326fe5fd2c69c9d9f0142c5bdf6fce4b",
            "timestamp": 1780656892.2244837,
            "size": 21798
        },
        "/sfx/tire_pop.ogg": {
            "md5": "9b5223d7186dc4f62d3cab4eb80b2726",
            "timestamp": 1780656892.2234836,
            "size": 148692
        },
        "/sfx/rocket_lockon.ogg": {
            "md5": "4fdcd5538de7d400c22dd0b4f4897105",
            "timestamp": 1781462451.7893813,
            "size": 80493
        },
        "/sfx/boom_far.ogg": {
            "md5": "b5996d301c65704235493fbf6e1d1ab2",
            "timestamp": 1781530079.648993,
            "size": 57940
        },
        "/sfx/redline.ogg": {
            "md5": "b64ae5a6dd84bae9d414fa3b26b4e5c9",
            "timestamp": 1780656892.2054837,
            "size": 20509
        },
        "/sfx/horn_skate.ogg": {
            "md5": "2209438aff632df9c58d9d18f9afe833",
            "timestamp": 1780673572.9403746,
            "size": 30686
        },
        "/sfx/painttool.ogg": {
            "md5": "489adb62521d5fe0be1ba791ae4f2031",
            "timestamp": 1780656892.2234836,
            "size": 28371
        },
        "/sfx/weapon_reload.ogg": {
            "md5": "0919c4534c681a15ae2a6ccca0f2c27a",
            "timestamp": 1782224546.951749,
            "size": 29772
        },
        "/sfx/music/ringtone.ogg": {
            "md5": "09af968b970f115f7cfe7a79a2a4a852",
            "timestamp": 1780656892.2244837,
            "size": 860954
        },
        "/sfx/engines/regular.ogg": {
            "md5": "3ed2c6ca2475c50e51c6db0e4dd16c2e",
            "timestamp": 1780656892.2254837,
            "size": 722515
        },
        "/sfx/engines/scooter.ogg": {
            "md5": "b48a688f07bf8a807079bcb2e7fc7660",
            "timestamp": 1780656892.2244837,
            "size": 303567
        },
        "/sfx/engines/redkiss.ogg": {
            "md5": "aff7a2a288b332804d011391efa973b2",
            "timestamp": 1780656892.2244837,
            "size": 392480
        },
        "/sfx/engines/truck.ogg": {
            "md5": "69d6cbcdd5f141472d016794d71c223f",
            "timestamp": 1780656892.2254837,
            "size": 659758
        },
        "/sfx/engines/neonspeedster.ogg": {
            "md5": "41834df766cf5e6fa389a9438045cc21",
            "timestamp": 1780656892.2254837,
            "size": 810359
        },
        "/sfx/sources/scene_02_03.aup": {
            "md5": "b34053c33bcfc7c42263ed8c22bfa9f4",
            "timestamp": 1780656892.2254837,
            "size": 5409
        },
        "/sfx/sources/scene_02_02.aup": {
            "md5": "6cb122fc749672359504f201592314a2",
            "timestamp": 1780656892.2254837,
            "size": 4403
        },
        "/sfx/sources/scene_02.aup": {
            "md5": "839c2ecc378d37c520f89df88697ad85",
            "timestamp": 1780656892.2254837,
            "size": 6843
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1fb00.au": {
            "md5": "f2572ecf66d29ef222efd19fa1b51be8",
            "timestamp": 1780656892.2354836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f6f8.au": {
            "md5": "6a9c679495ba1f837520cac992016de3",
            "timestamp": 1780656892.2334838,
            "size": 652368
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1fe6a.au": {
            "md5": "dd37bb26cce1255253d9d94c874e4320",
            "timestamp": 1780656892.2364836,
            "size": 164000
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1fd51.au": {
            "md5": "8c3a82840840f633bf91cf2300e10acc",
            "timestamp": 1780656892.2264836,
            "size": 625540
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f340.au": {
            "md5": "81190f75da1f760dc86f7abee3a47e9a",
            "timestamp": 1780656892.2374837,
            "size": 775248
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f9aa.au": {
            "md5": "cce8c2128e8d89be4deded0f64ecf864",
            "timestamp": 1780656892.2374837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f0b3.au": {
            "md5": "eac8656a4458a13dc7709ee57576e74b",
            "timestamp": 1780656892.2354836,
            "size": 576592
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1fa55.au": {
            "md5": "068d3448cdf420f0973f02ea467f013d",
            "timestamp": 1780656892.2264836,
            "size": 106808
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f539.au": {
            "md5": "c42d2120e0363ea4f337559765f58692",
            "timestamp": 1780656892.2354836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1fdee.au": {
            "md5": "f257eab68cdff5e97165b554c361204f",
            "timestamp": 1780656892.2384837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f8ed.au": {
            "md5": "ca648d8ab0c30dffd9996ac55f2e5a37",
            "timestamp": 1780656892.2334838,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f6c0.au": {
            "md5": "50937531aa07ce016bfbb96189cf0c10",
            "timestamp": 1780656892.2364836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f078.au": {
            "md5": "ccadf62db7d2faedada7f60cdfa53b75",
            "timestamp": 1780656892.2364836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f69c.au": {
            "md5": "f9a8e62939a1c24593f301cb1c711717",
            "timestamp": 1780656892.2364836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f967.au": {
            "md5": "8ea2018c33e56df29a6aed1f53ab7f49",
            "timestamp": 1780656892.2384837,
            "size": 962652
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1faf9.au": {
            "md5": "61a50ad6c5b238f83a61d6c3fe097ff7",
            "timestamp": 1780656892.2384837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f6c9.au": {
            "md5": "12fdce3e981022943d796ef28b15fd59",
            "timestamp": 1780656892.2344837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f1f5.au": {
            "md5": "82fe62e2d35a01088b2dc492e725dcf2",
            "timestamp": 1780656892.2334838,
            "size": 619600
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f2d0.au": {
            "md5": "6f1436be1b114a8c4195da9090eea3a5",
            "timestamp": 1780656892.2334838,
            "size": 625544
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f8c9.au": {
            "md5": "42a904433e1e59d6ab11dc37b03f9d0f",
            "timestamp": 1780656892.2254837,
            "size": 101044
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1fffd.au": {
            "md5": "c19db2fe36227cbbbde8486c6be6aa43",
            "timestamp": 1780656892.2334838,
            "size": 101432
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f82a.au": {
            "md5": "9df80df55ab7e3588bbcd006c6631162",
            "timestamp": 1780656892.2374837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_data/eff/d1f/eff1f090.au": {
            "md5": "ae1e90bb08dbb7a2513ec172592da03b",
            "timestamp": 1780656892.2344837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1fd42.au": {
            "md5": "adcfd8c853a572ffbaac3d44a6b083fe",
            "timestamp": 1780656892.2504838,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f670.au": {
            "md5": "a893980befab80d91d09b3dac46eeabb",
            "timestamp": 1780656892.2554836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1fcf9.au": {
            "md5": "8d280a39e7f7e94314213f02cd0cc9a0",
            "timestamp": 1780656892.2494836,
            "size": 86692
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f50c.au": {
            "md5": "1b65c45528b557340ea93a9762f03bae",
            "timestamp": 1780656892.2564838,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f43b.au": {
            "md5": "7e17ab443b1dc45ccae7a78645ab6eb9",
            "timestamp": 1780656892.2514837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f8d8.au": {
            "md5": "2de308bea24e18fa1626b0557328189b",
            "timestamp": 1780656892.2514837,
            "size": 425136
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f0b4.au": {
            "md5": "5aff33ff852033729fcc8b90b4c03834",
            "timestamp": 1780656892.2534838,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f686.au": {
            "md5": "df4ea4d70486cde81ea874105d509692",
            "timestamp": 1780656892.2494836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f300.au": {
            "md5": "0cdae78b06cb2cc3aa9cca06772bf454",
            "timestamp": 1780656892.2404838,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1fa59.au": {
            "md5": "e8ff426910e467f42223269d4cce9a75",
            "timestamp": 1780656892.2394836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f89e.au": {
            "md5": "01388f934982e38a94d3a1760dc251b0",
            "timestamp": 1780656892.2504838,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1ff46.au": {
            "md5": "9bbd7ac184183ab5eeaf6715b4247cc4",
            "timestamp": 1780656892.2564838,
            "size": 857800
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f30c.au": {
            "md5": "4724bc4c8fb154f099273b3f5e064f5f",
            "timestamp": 1780656892.2394836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f087.au": {
            "md5": "2802484cc04b7f00f0b862cb7d65373b",
            "timestamp": 1780656892.2544837,
            "size": 608956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1fd30.au": {
            "md5": "e70385e49a0ef275afff980ef00741b2",
            "timestamp": 1780656892.2524836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_02_data/eff/d1f/eff1f540.au": {
            "md5": "e5b8e64ffc0fea869ba15f011c56e0e1",
            "timestamp": 1780656892.2544837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f9ca.au": {
            "md5": "c5543a2d4dc491488eb94001b4250a01",
            "timestamp": 1780656892.2674837,
            "size": 788404
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f750.au": {
            "md5": "c164daef91b05d8da996b4c530b44d6b",
            "timestamp": 1780656892.2684836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f27a.au": {
            "md5": "c21bb3bf42ecd28a48bd6b8d367881b0",
            "timestamp": 1780656892.2674837,
            "size": 794364
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1fb0d.au": {
            "md5": "a45c9fdbe076c05846ed2895040685c6",
            "timestamp": 1780656892.2714837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f662.au": {
            "md5": "f0019a7f721348b9bb60e2fadc57c0e3",
            "timestamp": 1780656892.2674837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f4b5.au": {
            "md5": "ffce5697ed936fb97c57cb2ee2eee05b",
            "timestamp": 1780656892.2694836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1ffd8.au": {
            "md5": "164e49f197d21282e96a17ae7c783423",
            "timestamp": 1780656892.2684836,
            "size": 788400
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f495.au": {
            "md5": "608444d0a0dc8d69971fbca782365998",
            "timestamp": 1780656892.2584836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f2a4.au": {
            "md5": "b34b1ee7ebd65fd77ace3cd199aaaae7",
            "timestamp": 1780656892.2694836,
            "size": 794360
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f799.au": {
            "md5": "0c7f6fcd87393e8e7d4f038f206d995c",
            "timestamp": 1780656892.2714837,
            "size": 871284
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1fb08.au": {
            "md5": "18a9fca34ac17d5011131f29b17bd93a",
            "timestamp": 1780656892.2584836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f043.au": {
            "md5": "a8279a54549e195611d292d84d925611",
            "timestamp": 1780656892.2584836,
            "size": 794364
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f397.au": {
            "md5": "080bdaa7249c9415fdf1e3d9a9d62f69",
            "timestamp": 1780656892.2714837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f6e3.au": {
            "md5": "c0fc4022ec1efe9be82318a39af5af46",
            "timestamp": 1780656892.2704837,
            "size": 862240
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f714.au": {
            "md5": "e9b6ff03cfebc194951b3e6013d295c0",
            "timestamp": 1780656892.2704837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1fa3e.au": {
            "md5": "469b667ea878a90bdd806c3165b32efc",
            "timestamp": 1780656892.2684836,
            "size": 871288
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f769.au": {
            "md5": "1d02e54ffce6e22a8fb0e77a1f9b7ca9",
            "timestamp": 1780656892.2724836,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f4b0.au": {
            "md5": "918a85ae01571dcec82cab2330189c6a",
            "timestamp": 1780656892.2724836,
            "size": 862240
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f8f8.au": {
            "md5": "0fa23490116bffbc2f49a5ef4ddef0ab",
            "timestamp": 1780656892.2704837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f9e7.au": {
            "md5": "efdf80ac0d4984be2195da1e77284656",
            "timestamp": 1780656892.2694836,
            "size": 862244
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1f9ff.au": {
            "md5": "9cafaf191bdce7f6e231df41314e20e9",
            "timestamp": 1780656892.2574837,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1fd2d.au": {
            "md5": "7b550cc4ce3d288e761b0e684445c7d3",
            "timestamp": 1780656892.2664838,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1fbf5.au": {
            "md5": "48df48ac0325ba9190f163d525cf3847",
            "timestamp": 1780656892.2664838,
            "size": 1060956
        },
        "/sfx/sources/scene_02_03_data/eff/d1f/eff1fa89.au": {
            "md5": "63a2f55a694c0e53b1a611685432d912",
            "timestamp": 1780656892.2684836,
            "size": 75424
        },
        "/sfx/phone/calling.ogg": {
            "md5": "33ad47052c639884b70ca258661323d8",
            "timestamp": 1780656892.2934837,
            "size": 33243
        },
        "/sfx/phone/failed.ogg": {
            "md5": "d7437c8fdaa4b1ceb064d348bc90a9c2",
            "timestamp": 1780656892.2934837,
            "size": 10150
        },
        "/sfx/voices/dani/ohgod.ogg": {
            "md5": "3ab828477a553df103d950d430b89ac9",
            "timestamp": 1780656892.2764838,
            "size": 19372
        },
        "/sfx/voices/dani/yelling.ogg": {
            "md5": "3393a2f1ce14eb67384e6880e8d1b763",
            "timestamp": 1780656892.2764838,
            "size": 136419
        },
        "/sfx/voices/dani/land.ogg": {
            "md5": "e41154095029496e7a0bc9ad54417d30",
            "timestamp": 1780656892.2764838,
            "size": 28888
        },
        "/sfx/voices/dani/entering.ogg": {
            "md5": "bba7e57c3c15e73b002388b1a54e608b",
            "timestamp": 1780656892.2764838,
            "size": 151149
        },
        "/sfx/voices/dani/walk.ogg": {
            "md5": "52dca5417ceb21114b78494632d5b7d4",
            "timestamp": 1780656892.2764838,
            "size": 44876
        },
        "/sfx/voices/dani/jump.ogg": {
            "md5": "61ffc8b4d6d7f805ef58aaaa52be4053",
            "timestamp": 1780656892.2764838,
            "size": 30693
        },
        "/sfx/voices/dani/wearesinking.ogg": {
            "md5": "1289b4550852b1aeb793501b44848fe9",
            "timestamp": 1780656892.2764838,
            "size": 36236
        },
        "/sfx/voices/dani/ohnoindeed.ogg": {
            "md5": "e4e09b5a0d46e06b8e7caac7da401145",
            "timestamp": 1780656892.2764838,
            "size": 57474
        },
        "/sfx/voices/dani/ohno.ogg": {
            "md5": "926d4bb75f0cd681cd434ff95dd3546e",
            "timestamp": 1780656892.2764838,
            "size": 29873
        },
        "/sfx/voices/angry_pursuit/hit_01.ogg": {
            "md5": "58c8b53ed18b06fa65f4770827c2ed64",
            "timestamp": 1780656892.2774837,
            "size": 33458
        },
        "/sfx/voices/angry_pursuit/start_02.ogg": {
            "md5": "151a5a575c8fe67be02f83b4db5ec805",
            "timestamp": 1780656892.2774837,
            "size": 74162
        },
        "/sfx/voices/angry_pursuit/start_05.ogg": {
            "md5": "9a3f2a7535a2947e78301d01e040a649",
            "timestamp": 1780656892.2774837,
            "size": 43273
        },
        "/sfx/voices/angry_pursuit/hit_05.ogg": {
            "md5": "9e299d775beb6407ab4649a8358e45c8",
            "timestamp": 1780656892.2774837,
            "size": 40930
        },
        "/sfx/voices/angry_pursuit/hit_02.ogg": {
            "md5": "4c56c251a2c0840f0cb4b834e186aecd",
            "timestamp": 1780656892.2764838,
            "size": 33696
        },
        "/sfx/voices/angry_pursuit/hit_03.ogg": {
            "md5": "c1a6537d0e13c8d81ca018958ef62572",
            "timestamp": 1780656892.2764838,
            "size": 35616
        },
        "/sfx/voices/angry_pursuit/start_08.ogg": {
            "md5": "c1ad74588ba71423e2c8be45f2c23156",
            "timestamp": 1780656892.2774837,
            "size": 34789
        },
        "/sfx/voices/angry_pursuit/start_03.ogg": {
            "md5": "9134528ef46a244546d31259b06603ac",
            "timestamp": 1780656892.2764838,
            "size": 51104
        },
        "/sfx/voices/angry_pursuit/start_07.ogg": {
            "md5": "0e0a556413ba5ac5c43a725f260b9cc2",
            "timestamp": 1780656892.2774837,
            "size": 41190
        },
        "/sfx/voices/angry_pursuit/start_01.ogg": {
            "md5": "1b4df0e25802ad9e086fb92d414ea788",
            "timestamp": 1780656892.2764838,
            "size": 35931
        },
        "/sfx/voices/angry_pursuit/start_04.ogg": {
            "md5": "ec54514b8e9cea2f5c16a61587396cd6",
            "timestamp": 1780656892.2774837,
            "size": 58349
        },
        "/sfx/voices/angry_pursuit/start_06.ogg": {
            "md5": "b06a9bf75faaf5a1b838e94f8775042d",
            "timestamp": 1780656892.2764838,
            "size": 43321
        },
        "/sfx/voices/angry_pursuit/hit_04.ogg": {
            "md5": "1332a3871158e05a5097959e308e567c",
            "timestamp": 1780656892.2764838,
            "size": 24951
        },
        "/sfx/voices/Dani_Box/fall1.ogg": {
            "md5": "15e5c4297c3e082b959ec054847e521c",
            "timestamp": 1780656892.2724836,
            "size": 24333
        },
        "/sfx/voices/Dani_Box/yelling1.ogg": {
            "md5": "3393a2f1ce14eb67384e6880e8d1b763",
            "timestamp": 1780656892.2724836,
            "size": 136419
        },
        "/sfx/voices/Dani_Box/ohgod1.ogg": {
            "md5": "3ab828477a553df103d950d430b89ac9",
            "timestamp": 1780656892.2724836,
            "size": 19372
        },
        "/sfx/voices/Dani_Box/fall2.ogg": {
            "md5": "4c81151b111b1a88017ca48e25d62dc3",
            "timestamp": 1780656892.2724836,
            "size": 13200
        },
        "/sfx/voices/Police_Radio/pito_statue3.ogg": {
            "md5": "6da9d66dde6d7ad4966ddfc3a65e2e3b",
            "timestamp": 1780656892.2754836,
            "size": 63315
        },
        "/sfx/voices/Police_Radio/unfinished_bridge2.ogg": {
            "md5": "636e9ed396a6f38bb23a44685a50b5d9",
            "timestamp": 1780656892.2754836,
            "size": 81842
        },
        "/sfx/voices/Police_Radio/Pass1.ogg": {
            "md5": "d749dfb4e6a0d02bb23ac876c214f503",
            "timestamp": 1780656892.2734838,
            "size": 76418
        },
        "/sfx/voices/Police_Radio/RaceAboutToStart4.ogg": {
            "md5": "56820cb428846d0c19bcd865c5740993",
            "timestamp": 1780656892.2744837,
            "size": 205285
        },
        "/sfx/voices/Police_Radio/grove_suspended_building2.ogg": {
            "md5": "0be3b1914230b9513fe74748809af326",
            "timestamp": 1780656892.2754836,
            "size": 68175
        },
        "/sfx/voices/Police_Radio/racetrack3.ogg": {
            "md5": "22b33b11b86a9ab3175c4dc5f27b9da9",
            "timestamp": 1780656892.2754836,
            "size": 65689
        },
        "/sfx/voices/Police_Radio/racetrack2.ogg": {
            "md5": "75c5a9421a9d9c03bf3abf755e136cdc",
            "timestamp": 1780656892.2754836,
            "size": 71721
        },
        "/sfx/voices/Police_Radio/Carnage3.ogg": {
            "md5": "b9a2b4bf2a05f212debeb0071ddb27cd",
            "timestamp": 1780656892.2734838,
            "size": 52294
        },
        "/sfx/voices/Police_Radio/RaceAboutToStart.ogg": {
            "md5": "180a558c6a60e14a5679b1dd49b7a900",
            "timestamp": 1780656892.2744837,
            "size": 162863
        },
        "/sfx/voices/Police_Radio/BreakFence3.ogg": {
            "md5": "c82d0c343ab66d746fb9e286be52376f",
            "timestamp": 1780656892.2734838,
            "size": 120738
        },
        "/sfx/voices/Police_Radio/grove_suspended_building3.ogg": {
            "md5": "6e88f26b60a08c7ec44de24bbff06364",
            "timestamp": 1780656892.2754836,
            "size": 82542
        },
        "/sfx/voices/Police_Radio/man_down1.ogg": {
            "md5": "99e2455b02c09b8befc3ef3dff2d9bf0",
            "timestamp": 1783853465.515143,
            "size": 82797
        },
        "/sfx/voices/Police_Radio/grove_pond2.ogg": {
            "md5": "0d999f2a3eb21f7e6c71715dcb0ad36b",
            "timestamp": 1780656892.2744837,
            "size": 56273
        },
        "/sfx/voices/Police_Radio/SeeSuspect.ogg": {
            "md5": "dc2381a35a644f28c5c101e98e42fa7b",
            "timestamp": 1780656892.2734838,
            "size": 85058
        },
        "/sfx/voices/Police_Radio/Carnage2.ogg": {
            "md5": "14dfb2d55e21241f80e4d10a741af013",
            "timestamp": 1780656892.2744837,
            "size": 63608
        },
        "/sfx/voices/Police_Radio/grove_pond1.ogg": {
            "md5": "c11d4db3bfb7c3f4258502f7a8263aa5",
            "timestamp": 1780656892.2734838,
            "size": 74692
        },
        "/sfx/voices/Police_Radio/RaceAboutToStart3.ogg": {
            "md5": "5c7c16703c7b343e2003a7befb031352",
            "timestamp": 1780656892.2744837,
            "size": 133251
        },
        "/sfx/voices/Police_Radio/karting_club2.ogg": {
            "md5": "8fe8124ad6609ebd7f4acffe857bdfa0",
            "timestamp": 1780656892.2754836,
            "size": 71364
        },
        "/sfx/voices/Police_Radio/pito_statue2.ogg": {
            "md5": "6157e8a6d8c422b93a46b6be97e9172f",
            "timestamp": 1780656892.2754836,
            "size": 68806
        },
        "/sfx/voices/Police_Radio/SuspectBoom.ogg": {
            "md5": "3ff09fdd3b5906c8b7d36133c6e1891f",
            "timestamp": 1780656892.2734838,
            "size": 180691
        },
        "/sfx/voices/Police_Radio/racetrack.ogg": {
            "md5": "1e11fab63b5952dc206818a7aa5a05ec",
            "timestamp": 1780656892.2754836,
            "size": 74812
        },
        "/sfx/voices/Police_Radio/RaceStart2.ogg": {
            "md5": "582a720806d69bfdcd7f34b33148429b",
            "timestamp": 1780656892.2744837,
            "size": 88732
        },
        "/sfx/voices/Police_Radio/RaceStart.ogg": {
            "md5": "320fbf0ef51e930010c21564c2b5a597",
            "timestamp": 1780656892.2734838,
            "size": 107739
        },
        "/sfx/voices/Police_Radio/Carnage1.ogg": {
            "md5": "f782e9ed6c379fc59af30267e890fd7d",
            "timestamp": 1780656892.2734838,
            "size": 65919
        },
        "/sfx/voices/Police_Radio/BreakFence4.ogg": {
            "md5": "6e1dd981bd957468e36442cda714b1b1",
            "timestamp": 1780656892.2734838,
            "size": 101202
        },
        "/sfx/voices/Police_Radio/man_down3.ogg": {
            "md5": "046fa6d0d1e8732000d8362a05db01d2",
            "timestamp": 1783853500.6561449,
            "size": 87618
        },
        "/sfx/voices/Police_Radio/karting_club.ogg": {
            "md5": "4cc685eb0df593cbe9dae4440d37c3f1",
            "timestamp": 1780656892.2754836,
            "size": 45298
        },
        "/sfx/voices/Police_Radio/gta3.ogg": {
            "md5": "eac896352243af0a3e690a90a4e33891",
            "timestamp": 1780656892.2764838,
            "size": 130734
        },
        "/sfx/voices/Police_Radio/grove_street3.ogg": {
            "md5": "4422349d6f0188e0cc7297d2f43616dd",
            "timestamp": 1780656892.2744837,
            "size": 64903
        },
        "/sfx/voices/Police_Radio/karting_club3.ogg": {
            "md5": "7b0df81ea4342ebf97694fb0a2e86ac1",
            "timestamp": 1780656892.2764838,
            "size": 66640
        },
        "/sfx/voices/Police_Radio/grove_skate_park1.ogg": {
            "md5": "a48f23b57fd6459e56f4c08916d44ac2",
            "timestamp": 1780656892.2744837,
            "size": 58322
        },
        "/sfx/voices/Police_Radio/unfinished_bridge3.ogg": {
            "md5": "8e2bb28369ff955224a943fa394c674b",
            "timestamp": 1780656892.2754836,
            "size": 88479
        },
        "/sfx/voices/Police_Radio/police_station.ogg": {
            "md5": "24883821d54e9269acc63b4c0760a6bb",
            "timestamp": 1780656892.2754836,
            "size": 93847
        },
        "/sfx/voices/Police_Radio/gta1.ogg": {
            "md5": "87d8338853ea6dad2471c7ffab960003",
            "timestamp": 1780656892.2724836,
            "size": 128526
        },
        "/sfx/voices/Police_Radio/green_house2.ogg": {
            "md5": "2c6eb730a5f9f475e6f9393ac24ed2e1",
            "timestamp": 1783852913.7081134,
            "size": 83667
        },
        "/sfx/voices/Police_Radio/grove_skate_park2.ogg": {
            "md5": "3a16abc2d3d59feed69d33b74d720ba7",
            "timestamp": 1780656892.2754836,
            "size": 77446
        },
        "/sfx/voices/Police_Radio/police_station2.ogg": {
            "md5": "64ff824b022dc08741b628ebe9651e7c",
            "timestamp": 1780656892.2754836,
            "size": 96446
        },
        "/sfx/voices/Police_Radio/RaceStart4.ogg": {
            "md5": "8969b455879402e20f33d8b19c85bad1",
            "timestamp": 1780656892.2744837,
            "size": 95792
        },
        "/sfx/voices/Police_Radio/Collision.ogg": {
            "md5": "986e01ae6055e976569b3231a7fec6d1",
            "timestamp": 1780656892.2734838,
            "size": 173583
        },
        "/sfx/voices/Police_Radio/grove_pond3.ogg": {
            "md5": "66e13f2806109276ca3e219d33dff94f",
            "timestamp": 1780656892.2744837,
            "size": 62998
        },
        "/sfx/voices/Police_Radio/grove_suspended_building1.ogg": {
            "md5": "5128997cfef63f7436684269f8bc5a50",
            "timestamp": 1780656892.2754836,
            "size": 75162
        },
        "/sfx/voices/Police_Radio/grove_street2.ogg": {
            "md5": "e979983f8aa1128db95179f2b761a8f5",
            "timestamp": 1780656892.2744837,
            "size": 72290
        },
        "/sfx/voices/Police_Radio/RaceStart3.ogg": {
            "md5": "f7826e5901a0d0c747b7e4d69da315ba",
            "timestamp": 1780656892.2744837,
            "size": 91755
        },
        "/sfx/voices/Police_Radio/Speeding.ogg": {
            "md5": "e13470040ccbbc4395519fadd9e2521f",
            "timestamp": 1780656892.2734838,
            "size": 95982
        },
        "/sfx/voices/Police_Radio/green_house3.ogg": {
            "md5": "25e5f47be98e0733519f1734682aec9b",
            "timestamp": 1783852931.6721144,
            "size": 93601
        },
        "/sfx/voices/Police_Radio/the_mall1.ogg": {
            "md5": "ad022ae74a2e8b53a20b049f75a14252",
            "timestamp": 1783852700.848102,
            "size": 58818
        },
        "/sfx/voices/Police_Radio/pito_statue.ogg": {
            "md5": "3afb895c270289694de4df1b2b425624",
            "timestamp": 1780656892.2754836,
            "size": 73147
        },
        "/sfx/voices/Police_Radio/Pass2.ogg": {
            "md5": "60f7b3f3836a5b2cbf313d391a20f201",
            "timestamp": 1780656892.2734838,
            "size": 106168
        },
        "/sfx/voices/Police_Radio/man_down2.ogg": {
            "md5": "60d29e4df112b2f8b7b121065332d743",
            "timestamp": 1783853483.386144,
            "size": 101567
        },
        "/sfx/voices/Police_Radio/Carnage5.ogg": {
            "md5": "6a625921d3eac50dafef4dc055342822",
            "timestamp": 1780656892.2744837,
            "size": 73304
        },
        "/sfx/voices/Police_Radio/grove_street1.ogg": {
            "md5": "6cd6065655395d8c4e6e6fe540d00bb9",
            "timestamp": 1780656892.2744837,
            "size": 70645
        },
        "/sfx/voices/Police_Radio/Carnage4.ogg": {
            "md5": "ec40fcb85f87f815cdb20c2b3d0d69dd",
            "timestamp": 1780656892.2744837,
            "size": 74473
        },
        "/sfx/voices/Police_Radio/the_mall2.ogg": {
            "md5": "387b459bb4bbda3add144b809a1f69a3",
            "timestamp": 1783852716.014103,
            "size": 51463
        },
        "/sfx/voices/Police_Radio/Pursuit.ogg": {
            "md5": "b86863b8f98e347860008b386f6bd884",
            "timestamp": 1780656892.2734838,
            "size": 65415
        },
        "/sfx/voices/Police_Radio/the_mall3.ogg": {
            "md5": "7f5789890b5b75b79369bba0d392a66f",
            "timestamp": 1783852734.418104,
            "size": 57696
        },
        "/sfx/voices/Police_Radio/RaceAboutToStart2.ogg": {
            "md5": "97f8d0f837bcab1be5ee4ad105ac590f",
            "timestamp": 1780656892.2744837,
            "size": 201566
        },
        "/sfx/voices/Police_Radio/Pass3.ogg": {
            "md5": "7291020650d6ed39e538fd917c513c85",
            "timestamp": 1780656892.2734838,
            "size": 91980
        },
        "/sfx/voices/Police_Radio/LostVisual.ogg": {
            "md5": "f168c0dbf0bcdf88138a72eb10405bfb",
            "timestamp": 1780656892.2734838,
            "size": 57145
        },
        "/sfx/voices/Police_Radio/police_station3.ogg": {
            "md5": "2ee73e1197f2e0452bb51ebfbd221da0",
            "timestamp": 1780656892.2754836,
            "size": 88604
        },
        "/sfx/voices/Police_Radio/grove_skate_park3.ogg": {
            "md5": "245e0e9c913a0040d9f876f8195c7789",
            "timestamp": 1780656892.2754836,
            "size": 64343
        },
        "/sfx/voices/Police_Radio/BreakFence.ogg": {
            "md5": "e817332eb4cb0191dd582ddacb6d75b5",
            "timestamp": 1780656892.2734838,
            "size": 141751
        },
        "/sfx/voices/Police_Radio/gta2.ogg": {
            "md5": "84d3a1ea13ffdf0c7f98c2db6264c7df",
            "timestamp": 1780656892.2764838,
            "size": 82058
        },
        "/sfx/voices/Police_Radio/green_house1.ogg": {
            "md5": "80131676eecb8459290a4cce536d7c81",
            "timestamp": 1783852858.7351105,
            "size": 62900
        },
        "/sfx/voices/Police_Radio/unfinished_bridge1.ogg": {
            "md5": "000c5f959b050e453ac00adefa1021fd",
            "timestamp": 1780656892.2754836,
            "size": 80806
        },
        "/sfx/voices/Police_Radio/BreakFence2.ogg": {
            "md5": "ced794b8118f91483286421e3f097379",
            "timestamp": 1780656892.2734838,
            "size": 74562
        },
        "/sfx/voices/PapsBox/bored1.ogg": {
            "md5": "6ce39245b074685a011a0ede266894a0",
            "timestamp": 1780656892.2924836,
            "size": 49152
        },
        "/sfx/voices/Regular_Radio/host11.ogg": {
            "md5": "1775e5f02d1c0cb4d35e3621e5f223de",
            "timestamp": 1783299007.9099424,
            "size": 1567087
        },
        "/sfx/voices/Regular_Radio/host10.ogg": {
            "md5": "927c16d90d4b37c8def99133dec45b1d",
            "timestamp": 1783298903.935937,
            "size": 789522
        },
        "/sfx/voices/Regular_Radio/host02.ogg": {
            "md5": "7d9efa3cc089e5964f57e8b17c697893",
            "timestamp": 1783298466.6449137,
            "size": 367419
        },
        "/sfx/voices/Regular_Radio/host_ad1.ogg": {
            "md5": "7730d8294bde31645d596da6020a43c9",
            "timestamp": 1783854291.413187,
            "size": 3029276
        },
        "/sfx/voices/Regular_Radio/host04.ogg": {
            "md5": "1edb82564a7795eaca85af9ba883f84f",
            "timestamp": 1783298560.2929187,
            "size": 592494
        },
        "/sfx/voices/Regular_Radio/script.txt": {
            "md5": "88973ecfd2b92367d3ffbf50ebdbf403",
            "timestamp": 1783297379.0208554,
            "size": 846
        },
        "/sfx/voices/Regular_Radio/host09.ogg": {
            "md5": "15ec8ab2cf86256e06fcea059412ff5e",
            "timestamp": 1783298823.0239327,
            "size": 606134
        },
        "/sfx/voices/Regular_Radio/host07.ogg": {
            "md5": "55b8453fb99d02eb6f002106b6e3cac1",
            "timestamp": 1783298735.082928,
            "size": 904216
        },
        "/sfx/voices/Regular_Radio/host03.ogg": {
            "md5": "f25eb1271123a8db759c958e374a1f91",
            "timestamp": 1783298499.1239152,
            "size": 452283
        },
        "/sfx/voices/Regular_Radio/host08.ogg": {
            "md5": "7aa756c2ff2d8a413f63b0691a744ad7",
            "timestamp": 1783298790.537931,
            "size": 575633
        },
        "/sfx/voices/Regular_Radio/host01.ogg": {
            "md5": "5c038c6f9b57fd3f8335b6dc8c5618c4",
            "timestamp": 1783298413.8819108,
            "size": 675482
        },
        "/sfx/voices/Regular_Radio/ad02.ogg": {
            "md5": "131347d3ad3714bac09b3f9b07c8da7f",
            "timestamp": 1783294832.2847195,
            "size": 1664069
        },
        "/sfx/voices/Regular_Radio/host_ad3.ogg": {
            "md5": "cf9875fa2dc01b82b3ddac90cfd4ee2a",
            "timestamp": 1783854802.6712143,
            "size": 3098486
        },
        "/sfx/voices/Regular_Radio/host05.ogg": {
            "md5": "a9d826149b67955fc4075f1461d33373",
            "timestamp": 1783298591.4509203,
            "size": 389071
        },
        "/sfx/voices/Regular_Radio/host06.ogg": {
            "md5": "a740f88c1bdd756d31b6cb446953f4ac",
            "timestamp": 1783298674.7929246,
            "size": 1711194
        },
        "/sfx/voices/Regular_Radio/noise.ogg": {
            "md5": "0a97ef9ec90560734cc324524ecdc065",
            "timestamp": 1783380420.3582904,
            "size": 591316
        },
        "/sfx/voices/Regular_Radio/host_ad2.ogg": {
            "md5": "a8375e14151069438559277e4cf966fa",
            "timestamp": 1783854536.1512,
            "size": 3437807
        },
        "/sfx/voices/Regular_Radio/ad03.ogg": {
            "md5": "c2c00d616551f7d4e436374e8e8c8662",
            "timestamp": 1783297835.38688,
            "size": 1031934
        },
        "/sfx/voices/Regular_Radio/ad01.ogg": {
            "md5": "f6050977eaabea0a8b1c3f299e058654",
            "timestamp": 1783293444.1796453,
            "size": 931129
        },
        "/sfx/voices/Man1Box/fall5.ogg": {
            "md5": "4164e5080246df424a8aa6b4f27f9ca1",
            "timestamp": 1780656892.2924836,
            "size": 21286
        },
        "/sfx/voices/Man1Box/taxi_grove_skate_park_1.ogg": {
            "md5": "b2dd5ab85321d295ca77c7724f7484d9",
            "timestamp": 1783857230.583344,
            "size": 75166
        },
        "/sfx/voices/Man1Box/taxi_missed2.ogg": {
            "md5": "6b2bd4c37ecb0fb9d3db1fa54f1e8d8d",
            "timestamp": 1783856104.642284,
            "size": 89140
        },
        "/sfx/voices/Man1Box/taxi_pito_statue_1.ogg": {
            "md5": "68e27ba2f030fb7f2bbdd37a464e8700",
            "timestamp": 1783857487.9723577,
            "size": 92521
        },
        "/sfx/voices/Man1Box/fall3.ogg": {
            "md5": "4b4be96b20a1dab250856d5406d2bc1c",
            "timestamp": 1780656892.2924836,
            "size": 16422
        },
        "/sfx/voices/Man1Box/voices_script.txt": {
            "md5": "65bbe8cf730de86f7ec7586ec57c70fc",
            "timestamp": 1780656892.2924836,
            "size": 3313
        },
        "/sfx/voices/Man1Box/scared2.ogg": {
            "md5": "267ada89e6dea0b6ffb60d62c07f181f",
            "timestamp": 1780656892.2924836,
            "size": 35102
        },
        "/sfx/voices/Man1Box/speed5.ogg": {
            "md5": "c8273087a18cbaa26eae532fda20e664",
            "timestamp": 1783849806.8189476,
            "size": 75880
        },
        "/sfx/voices/Man1Box/taxi_police_station_1.ogg": {
            "md5": "a7a2e7eabd6b1d3545f52c5592b7a82a",
            "timestamp": 1783857564.4583619,
            "size": 214410
        },
        "/sfx/voices/Man1Box/scared4.ogg": {
            "md5": "5d0790955001cfae4f2b06165e087e25",
            "timestamp": 1780656892.2924836,
            "size": 39639
        },
        "/sfx/voices/Man1Box/taxi_unfinished_bridge_2.ogg": {
            "md5": "32cea790c454d99c5b85610d50e7dea5",
            "timestamp": 1783857460.4263563,
            "size": 228157
        },
        "/sfx/voices/Man1Box/taxi_missed3.ogg": {
            "md5": "8408a77ab35fd3cbd22ec4601760e75d",
            "timestamp": 1783856121.8832848,
            "size": 91744
        },
        "/sfx/voices/Man1Box/taxi_karting_club_1.ogg": {
            "md5": "37a85a1de3fc003be9cd133013ee096a",
            "timestamp": 1783857628.9433653,
            "size": 168054
        },
        "/sfx/voices/Man1Box/taxi_grove_skate_park_2.ogg": {
            "md5": "831372ad4d3c0439a550b01cf070f7ec",
            "timestamp": 1783857253.9033453,
            "size": 130334
        },
        "/sfx/voices/Man1Box/taxi_grove_street_1.ogg": {
            "md5": "655dead4ceebd19317e3e0b0da746571",
            "timestamp": 1783857168.4273407,
            "size": 264178
        },
        "/sfx/voices/Man1Box/taxi_grove_suspended_building_1.ogg": {
            "md5": "65a6b8a8fe55956159fdc4228074cee7",
            "timestamp": 1783857293.3723474,
            "size": 210555
        },
        "/sfx/voices/Man1Box/scared3.ogg": {
            "md5": "dd9ba00af516636b00a6a496e56372fd",
            "timestamp": 1780656892.2924836,
            "size": 47746
        },
        "/sfx/voices/Man1Box/taxi_unfinished_bridge_1.ogg": {
            "md5": "cc191075aa889a2ea1de7b207278685a",
            "timestamp": 1783857429.5333548,
            "size": 197909
        },
        "/sfx/voices/Man1Box/scared1.ogg": {
            "md5": "cba5c752981bec47af6a2c326a055889",
            "timestamp": 1780656892.2924836,
            "size": 53816
        },
        "/sfx/voices/Man1Box/taxi_grove_pond_1.ogg": {
            "md5": "c02f27a5f7a8b3065edc578194a22461",
            "timestamp": 1783857071.6413355,
            "size": 161331
        },
        "/sfx/voices/Man1Box/fall1.ogg": {
            "md5": "bb1c6d64dc59c8d5db4817bc8e653db8",
            "timestamp": 1780656892.2924836,
            "size": 17368
        },
        "/sfx/voices/Man1Box/police_incar.ogg": {
            "md5": "cf2c10fb18726c5e4f1bb1aa40156782",
            "timestamp": 1780656892.2924836,
            "size": 197916
        },
        "/sfx/voices/Man1Box/crash3.ogg": {
            "md5": "4b7cfc658b9d239113bcf4fcf55ebef4",
            "timestamp": 1783849022.6149056,
            "size": 63591
        },
        "/sfx/voices/Man1Box/crash5.ogg": {
            "md5": "6b4d92ffbb8030e47a88b7912f354f77",
            "timestamp": 1783849243.8179176,
            "size": 58448
        },
        "/sfx/voices/Man1Box/near3.ogg": {
            "md5": "6c8051d3a440492e47894b57446f872c",
            "timestamp": 1783849925.658954,
            "size": 122135
        },
        "/sfx/voices/Man1Box/police_code6.ogg": {
            "md5": "3062054aead1ce567f0e73bb26662818",
            "timestamp": 1780656892.2924836,
            "size": 69365
        },
        "/sfx/voices/Man1Box/speed3.ogg": {
            "md5": "9ba0329e4c26b351ef6fb290a2afe2f1",
            "timestamp": 1783849363.686924,
            "size": 75933
        },
        "/sfx/voices/Man1Box/fall4.ogg": {
            "md5": "256e0e81eda02dab7af239aa7f2f4740",
            "timestamp": 1780656892.2924836,
            "size": 20680
        },
        "/sfx/voices/Man1Box/speed4.ogg": {
            "md5": "c5bf76e723d0cc9506693657507cb2ca",
            "timestamp": 1783849387.5279253,
            "size": 95298
        },
        "/sfx/voices/Man1Box/wait2.ogg": {
            "md5": "8a062dc06033a424c8bc15ad343c8f0e",
            "timestamp": 1780656892.2914836,
            "size": 40504
        },
        "/sfx/voices/Man1Box/taxi_karting_club_2.ogg": {
            "md5": "20c2d95b4b4918821333912b84316d4b",
            "timestamp": 1783857663.152367,
            "size": 275414
        },
        "/sfx/voices/Man1Box/wait1.ogg": {
            "md5": "ae548dd2ef2bbb97d1fe1b71f07cfe1e",
            "timestamp": 1780656892.2914836,
            "size": 82601
        },
        "/sfx/voices/Man1Box/wait3.ogg": {
            "md5": "96350a4994d639420e2a809cbf0a92c5",
            "timestamp": 1780656892.2914836,
            "size": 34718
        },
        "/sfx/voices/Man1Box/taxi_pito_statue_2.ogg": {
            "md5": "f3b90356fd146e17d7d9b080b7cd87e4",
            "timestamp": 1783857521.6813595,
            "size": 310907
        },
        "/sfx/voices/Man1Box/taxi_grove_street_2.ogg": {
            "md5": "1a683d027cc6e4d82294517fd8486220",
            "timestamp": 1783857202.3733425,
            "size": 139902
        },
        "/sfx/voices/Man1Box/bored3.ogg": {
            "md5": "6d8582d8bfe96db87bba1cb02668d820",
            "timestamp": 1780656892.2924836,
            "size": 35695
        },
        "/sfx/voices/Man1Box/crash4.ogg": {
            "md5": "a65a479737b0fa4967716b1ee95cd70e",
            "timestamp": 1783849060.5409076,
            "size": 61235
        },
        "/sfx/voices/Man1Box/taxi_grove_suspended_building_2.ogg": {
            "md5": "bd5341e863ef50c8ea28e3eea7515fb4",
            "timestamp": 1783857332.4933496,
            "size": 366299
        },
        "/sfx/voices/Man1Box/taxi_racetrack_2.ogg": {
            "md5": "475b46e1bf82e0e18401bfcaf3272df3",
            "timestamp": 1783857388.0863523,
            "size": 132144
        },
        "/sfx/voices/Man1Box/crash2.ogg": {
            "md5": "3d40b03a88378aa8145beaa9d8ade53a",
            "timestamp": 1783848960.2819023,
            "size": 47458
        },
        "/sfx/voices/Man1Box/taxi_the_mall_1.ogg": {
            "md5": "d1536e154cd9068dedca91eff27851b7",
            "timestamp": 1783857719.28637,
            "size": 286673
        },
        "/sfx/voices/Man1Box/police_miranda.ogg": {
            "md5": "ae6f9faa020770f72a37f105019428ed",
            "timestamp": 1780656892.2924836,
            "size": 163859
        },
        "/sfx/voices/Man1Box/near1.ogg": {
            "md5": "e2b28da8b4f13c8e599ac99dd48a2df6",
            "timestamp": 1783849855.7259502,
            "size": 77289
        },
        "/sfx/voices/Man1Box/speed2.ogg": {
            "md5": "40ce0877e7724b3998279a1ce326a154",
            "timestamp": 1783849339.7249227,
            "size": 96581
        },
        "/sfx/voices/Man1Box/bored2.ogg": {
            "md5": "dbcce3ee8297117e784fa8b6b8b36920",
            "timestamp": 1780656892.2924836,
            "size": 33911
        },
        "/sfx/voices/Man1Box/taxi_green_house_2.ogg": {
            "md5": "5e4ad091365daf4b7f0db1856f405842",
            "timestamp": 1783857827.779376,
            "size": 116928
        },
        "/sfx/voices/Man1Box/taxi_green_house_1.ogg": {
            "md5": "e3a007ccf653833c6d65bb0b8eb9f98a",
            "timestamp": 1783857804.4393747,
            "size": 333955
        },
        "/sfx/voices/Man1Box/taxi_missed.ogg": {
            "md5": "8ca757d587672d405f29f23b92a1c0c1",
            "timestamp": 1783856065.8722818,
            "size": 76124
        },
        "/sfx/voices/Man1Box/taxi_racetrack_1.ogg": {
            "md5": "189680ca65d2b64769a3f1a1ebf1d854",
            "timestamp": 1783857364.025351,
            "size": 82998
        },
        "/sfx/voices/Man1Box/taxi_grove_pond_2.ogg": {
            "md5": "53659383a17d999ae3fd2416e0d7fd2c",
            "timestamp": 1783857124.2303383,
            "size": 219138
        },
        "/sfx/voices/Man1Box/taxi_the_mall_2.ogg": {
            "md5": "d08ae59c5132b0bc41966534e1b3d2bc",
            "timestamp": 1783857754.917372,
            "size": 288591
        },
        "/sfx/voices/Man1Box/crash1.ogg": {
            "md5": "497830dee065ef9e4ee5c81d3f55d60f",
            "timestamp": 1783848920.4579003,
            "size": 55495
        },
        "/sfx/voices/Man1Box/taxi_police_station_2.ogg": {
            "md5": "fa34a37fab81473f6fc56cb3093aab06",
            "timestamp": 1783857595.9493635,
            "size": 269498
        },
        "/sfx/voices/Man1Box/bored1.ogg": {
            "md5": "6ce39245b074685a011a0ede266894a0",
            "timestamp": 1780656892.2914836,
            "size": 49152
        },
        "/sfx/voices/Man1Box/near2.ogg": {
            "md5": "b0e45edf3935d4b7da0ae37eacac113b",
            "timestamp": 1783849880.1109514,
            "size": 84474
        },
        "/sfx/voices/Man1Box/fall2.ogg": {
            "md5": "61adb582fe2d53b5d5aed6d4ca7a1843",
            "timestamp": 1780656892.2924836,
            "size": 20826
        },
        "/sfx/voices/Man1Box/speed1.ogg": {
            "md5": "385c0c8b59862f46365047714ec0ebcb",
            "timestamp": 1783849280.3889194,
            "size": 72910
        },
        "/sfx/voices/scenes/03_Karting_Lessons/talk_in_car.ogg": {
            "md5": "7358ca81e5f12e0651cb30d588422095",
            "timestamp": 1780656892.2834837,
            "size": 1498774
        },
        "/sfx/voices/scenes/03_Karting_Lessons/win2.ogg": {
            "md5": "df84a2bc51eefafb3455438dd160ea71",
            "timestamp": 1780656892.2914836,
            "size": 767547
        },
        "/sfx/voices/scenes/03_Karting_Lessons/brief.ogg": {
            "md5": "db56609ecbb27553bb2eb5756a1780a7",
            "timestamp": 1780656892.2834837,
            "size": 1207913
        },
        "/sfx/voices/scenes/03_Karting_Lessons/come.ogg": {
            "md5": "7dd91dc563edb2afa52f09e8e0fd9575",
            "timestamp": 1780656892.2834837,
            "size": 38976
        },
        "/sfx/voices/scenes/03_Karting_Lessons/go_race.ogg": {
            "md5": "b20b511265dfb90578efa20052a1e5a9",
            "timestamp": 1780656892.2834837,
            "size": 402250
        },
        "/sfx/voices/scenes/03_Karting_Lessons/win1.ogg": {
            "md5": "e6583ac39548bb4e714047b13d284e46",
            "timestamp": 1780656892.2914836,
            "size": 524873
        },
        "/sfx/voices/scenes/03_Karting_Lessons/01.ogg": {
            "md5": "52c044bb75236e13dde2dd9c1e3ff2bf",
            "timestamp": 1780656892.2814837,
            "size": 1023429
        },
        "/sfx/voices/scenes/03_Karting_Lessons/dani_I_said_5_minutes.ogg": {
            "md5": "0e3e42a7f4789db9833c604170ff89e6",
            "timestamp": 1780656892.2824836,
            "size": 178636
        },
        "/sfx/voices/scenes/03_Karting_Lessons/paps_ad.ogg": {
            "md5": "a9ad01a851c6fbbc0ff69ee3a38d7d6f",
            "timestamp": 1780656892.2824836,
            "size": 1884021
        },
        "/sfx/voices/scenes/03_Karting_Lessons/01_raw.ogg": {
            "md5": "d322a893890c4c45b0e9a6b9354cfcc8",
            "timestamp": 1780656892.2814837,
            "size": 1580361
        },
        "/sfx/voices/scenes/03_Karting_Lessons/lose.ogg": {
            "md5": "c0ae7460f0ed5046f294cf98ae19348b",
            "timestamp": 1780656892.2914836,
            "size": 383184
        },
        "/sfx/voices/scenes/03_Karting_Lessons/get_in_Dani.ogg": {
            "md5": "e008278e320dd701d678f06186ca7f0c",
            "timestamp": 1780656892.2834837,
            "size": 60444
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/final_paps.ogg": {
            "md5": "2a4f199fa61bf672d53bfc9b1429756f",
            "timestamp": 1780656892.2804837,
            "size": 1247857
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/take_this_power_wrench.ogg": {
            "md5": "ed3299db8a4ce95958df18ca9083ffb3",
            "timestamp": 1780656892.2784836,
            "size": 207605
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/brief.ogg": {
            "md5": "deb9b61de025438a23145ef3bb32a2a1",
            "timestamp": 1780656892.2784836,
            "size": 1080799
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/after_race_brief.ogg": {
            "md5": "ebf415b0dfb8715d6c8138df1121aabf",
            "timestamp": 1780656892.2804837,
            "size": 448944
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/seems_we_have_everything.ogg": {
            "md5": "8b4812ecc35c47b26b3b3edaa9354c81",
            "timestamp": 1780656892.2784836,
            "size": 65966
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/d1.ogg": {
            "md5": "32782752a2942031c251b18e87ca6949",
            "timestamp": 1780656892.2804837,
            "size": 74944
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/tidy_from_below.ogg": {
            "md5": "78199af1baf296c5fdb4c293af0709c5",
            "timestamp": 1780656892.2784836,
            "size": 126056
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/twist.ogg": {
            "md5": "9d79d791b9f0c88d4833ae99de1f43a1",
            "timestamp": 1780656892.2784836,
            "size": 299028
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/get_the_car_out_here.ogg": {
            "md5": "5db4b0ed5821bb5b0fe670af6810c6bc",
            "timestamp": 1780656892.2804837,
            "size": 62194
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/no_pick_up_the_car.ogg": {
            "md5": "8743aace14c975e5f0c514f6f690e33e",
            "timestamp": 1780656892.2784836,
            "size": 76603
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/d2.ogg": {
            "md5": "6d786bbfbb5d9e8ceb7b13a73e29a614",
            "timestamp": 1780656892.2794838,
            "size": 1193487
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/final_jack.ogg": {
            "md5": "6881958e9d0c8b34928da881e9ff52d4",
            "timestamp": 1780656892.2794838,
            "size": 687330
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/yes.ogg": {
            "md5": "b38ba6a176f63c9a7fbc84955f48d123",
            "timestamp": 1780656892.2804837,
            "size": 21433
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/pick_up_the_car.ogg": {
            "md5": "e820f9d664ee809321d2b72a6d5744e1",
            "timestamp": 1780656892.2804837,
            "size": 43023
        },
        "/sfx/voices/scenes/02_Bring_Truck_To_House/final_dani.ogg": {
            "md5": "df063aafb2a9813c2187359d20ade90a",
            "timestamp": 1780656892.2804837,
            "size": 98701
        },
        "/sfx/voices/scenes/01_Bring_Neonspeedster_To_Racetrack/brief.ogg": {
            "md5": "9c6e54c4c8b267e6f05ca3b24396ac06",
            "timestamp": 1780656892.2804837,
            "size": 374290
        },
        "/sfx/voices/scenes/01_Bring_Neonspeedster_To_Racetrack/win.ogg": {
            "md5": "0c1c250a7077c1bcd7dacc0c468a0e92",
            "timestamp": 1780656892.2804837,
            "size": 185446
        },
        "/sfx/voices/scenes/01_Bring_Neonspeedster_To_Racetrack/01.ogg": {
            "md5": "c35c0d35824f96bf0d1aac171f72085c",
            "timestamp": 1780656892.2804837,
            "size": 285506
        },
        "/sfx/voices/scenes/01_Bring_Neonspeedster_To_Racetrack/lose.ogg": {
            "md5": "46001242810cf4d7d3acc6954522b064",
            "timestamp": 1780656892.2804837,
            "size": 162841
        },
        "/sfx/voices/JackBox/speed5.ogg": {
            "md5": "01191b65ba5543d74f597ebbf8b91541",
            "timestamp": 1780656892.2774837,
            "size": 27900
        },
        "/sfx/voices/JackBox/speed6.ogg": {
            "md5": "0c1e05a9fe6dfa564c1f3fee34c0e821",
            "timestamp": 1780656892.2774837,
            "size": 32613
        },
        "/sfx/voices/JackBox/speed7.ogg": {
            "md5": "fad12a44202e0d58169a9aeb07082064",
            "timestamp": 1780656892.2774837,
            "size": 34776
        },
        "/sfx/voices/JackBox/crash3.ogg": {
            "md5": "0306a0e7bdff4a61b7f3b8e532e8cd98",
            "timestamp": 1780656892.2784836,
            "size": 45695
        },
        "/sfx/voices/JackBox/crash5.ogg": {
            "md5": "1831d28b695c554cd44e07e46ed9e245",
            "timestamp": 1780656892.2774837,
            "size": 43839
        },
        "/sfx/voices/JackBox/speed8.ogg": {
            "md5": "cd8246d4628a238f80b53338adb52e11",
            "timestamp": 1780656892.2784836,
            "size": 42900
        },
        "/sfx/voices/JackBox/near3.ogg": {
            "md5": "84a2ea2f3ffd147dd02ccb5ebc0259b5",
            "timestamp": 1780656892.2774837,
            "size": 42712
        },
        "/sfx/voices/JackBox/speed3.ogg": {
            "md5": "503dcd5e898103ec9964684b27482458",
            "timestamp": 1780656892.2774837,
            "size": 64277
        },
        "/sfx/voices/JackBox/speed4.ogg": {
            "md5": "031e78ebcbb5865710fdbb232c0d1355",
            "timestamp": 1780656892.2774837,
            "size": 33399
        },
        "/sfx/voices/JackBox/bored3.ogg": {
            "md5": "6d8582d8bfe96db87bba1cb02668d820",
            "timestamp": 1780656892.2784836,
            "size": 35695
        },
        "/sfx/voices/JackBox/crash4.ogg": {
            "md5": "1a4270d370f1327d58638f3598c87a30",
            "timestamp": 1780656892.2774837,
            "size": 37352
        },
        "/sfx/voices/JackBox/crash2.ogg": {
            "md5": "b67d4936efc81a8451efe73b8e954133",
            "timestamp": 1780656892.2774837,
            "size": 53964
        },
        "/sfx/voices/JackBox/near1.ogg": {
            "md5": "f9eaed397ee38469c18921140ce7b72d",
            "timestamp": 1780656892.2774837,
            "size": 72421
        },
        "/sfx/voices/JackBox/speed2.ogg": {
            "md5": "847ee7cc5fba31ca2677375362fd12af",
            "timestamp": 1780656892.2774837,
            "size": 48717
        },
        "/sfx/voices/JackBox/crash1.ogg": {
            "md5": "7f3d45a00cf126de72144bcca831624e",
            "timestamp": 1780656892.2774837,
            "size": 51624
        },
        "/sfx/voices/JackBox/near2.ogg": {
            "md5": "b3f42cc5c32b198c549ed8b0498b4a7c",
            "timestamp": 1780656892.2774837,
            "size": 42410
        },
        "/sfx/voices/JackBox/speed1.ogg": {
            "md5": "397a0528ae383f3351f965b29403df1b",
            "timestamp": 1780656892.2774837,
            "size": 26650
        },
        "/sfx/ambiance/forest.ogg": {
            "md5": "2b5df276ac1bc60232c66a0858efe1b5",
            "timestamp": 1780656892.2934837,
            "size": 240801
        },
        "/sfx/ambiance/water.ogg": {
            "md5": "9aff987cc7d6cd9fdb9ead9eb16d7ada",
            "timestamp": 1780656892.2934837,
            "size": 391391
        },
        "/Scripts/Music.py": {
            "md5": "e7df59fd027cee78ddaa338370e97acd",
            "timestamp": 1783722771.1691632,
            "size": 8608
        },
        "/Scripts/Common.py": {
            "md5": "9eb2a0870809ad384f9ee35ba12ed56e",
            "timestamp": 1784117809.872373,
            "size": 5332
        },
        "/Scripts/Minigames.py": {
            "md5": "4595ac1e12b2db7b1277561811b79706",
            "timestamp": 1780656892.2954836,
            "size": 1381
        },
        "/Scripts/Race_Manager.py": {
            "md5": "060f24d07306a9acb25655eed6fa136e",
            "timestamp": 1785236627.4822664,
            "size": 35491
        },
        "/Scripts/Script.py": {
            "md5": "55c486ed27c40d25fb4369540b51dfb7",
            "timestamp": 1784807783.1833637,
            "size": 59715
        },
        "/Scripts/dumpBlend.py": {
            "md5": "a4c73e855247913cf9aacb0aa5c5abbf",
            "timestamp": 1785332319.0683768,
            "size": 969
        },
        "/Scripts/Reuse.py": {
            "md5": "9cacba7eae2122209594ec8969feb068",
            "timestamp": 1780665354.6179357,
            "size": 7470
        },
        "/Scripts/Outfits.py": {
            "md5": "ef7669bd4cb1bae416c24cca2a57fb9f",
            "timestamp": 1784289941.0842881,
            "size": 7188
        },
        "/Scripts/UI.py": {
            "md5": "4e8da0301b22cd5c52382a9a266d749e",
            "timestamp": 1784142963.0327163,
            "size": 2997
        },
        "/Scripts/Character.py": {
            "md5": "eec64c19ac4b38cd5d78365d5c84f991",
            "timestamp": 1785226764.0227396,
            "size": 106222
        },
        "/Scripts/LEGACY_Car_controll.py": {
            "md5": "9f909d78ec4e26cab2d070f71b2a1e84",
            "timestamp": 1780656892.2954836,
            "size": 66811
        },
        "/Scripts/Hints.py": {
            "md5": "e02aa9e8e9b1af0e3c82528002e85ac7",
            "timestamp": 1780656892.2954836,
            "size": 3411
        },
        "/Scripts/Opt_Old.py": {
            "md5": "0d29bcb3fd3d88d63434da9d879c72dd",
            "timestamp": 1780656892.2944837,
            "size": 17758
        },
        "/Scripts/Racing.py": {
            "md5": "fa2c81cf8db81dfda2f2863ae07ee12a",
            "timestamp": 1784812317.2656057,
            "size": 38332
        },
        "/Scripts/Money.py": {
            "md5": "b060c5cb2f19bf13de3ab5f4b701bd8c",
            "timestamp": 1780656892.2944837,
            "size": 1315
        },
        "/Scripts/Character_Controll.py": {
            "md5": "9a3c6195db287ffe92181f50ae30f306",
            "timestamp": 1780656892.2954836,
            "size": 39582
        },
        "/Scripts/Navigation.py": {
            "md5": "b58cd52cebc1b1039ec154c2d57a0240",
            "timestamp": 1783721215.46108,
            "size": 11156
        },
        "/Scripts/Online.py": {
            "md5": "c6c82201edf47d11449a3e27418f7c4d",
            "timestamp": 1784811603.3225677,
            "size": 4091
        },
        "/Scripts/Garage.py": {
            "md5": "3de5e4ee1a12ad9edf936d5188d3a5a4",
            "timestamp": 1784806682.8573048,
            "size": 22785
        },
        "/Scripts/Map.py": {
            "md5": "dfbb8ea1187a1cadb52d170c89e1a22a",
            "timestamp": 1783200619.8698769,
            "size": 9555
        },
        "/Scripts/Destruction.py": {
            "md5": "7c2b0cf3526249f7b733e24e07e105fd",
            "timestamp": 1785238686.5773764,
            "size": 40095
        },
        "/Scripts/Main_update.py": {
            "md5": "923637fc4dd275894b7a0eb84fb2431f",
            "timestamp": 1785346220.8941193,
            "size": 25481
        },
        "/Scripts/Doors.py": {
            "md5": "935968e404e87b8fd12db585dcdb02c3",
            "timestamp": 1780656892.2954836,
            "size": 5841
        },
        "/Scripts/Input.py": {
            "md5": "578654d4194495da5863ce4ca962f981",
            "timestamp": 1784290028.3552928,
            "size": 37427
        },
        "/Scripts/CodeManager.py": {
            "md5": "49c34394d95b47cad683538597a2a3f8",
            "timestamp": 1785337628.6206603,
            "size": 21207
        },
        "/Scripts/Opt.py": {
            "md5": "d370b8231aed5bb6ae0340a11417b6c4",
            "timestamp": 1782641451.9780142,
            "size": 33878
        },
        "/Scripts/Mouse.py": {
            "md5": "686a663b0635b35331f49b5e3333fd40",
            "timestamp": 1781385303.7542613,
            "size": 3426
        },
        "/Scripts/Settings.py": {
            "md5": "e23010b2cf462ffcbf01858cef5326ac",
            "timestamp": 1785346479.7451332,
            "size": 9056
        },
        "/Scripts/GameTime.py": {
            "md5": "cb9047945b5c87461385123725ea6adc",
            "timestamp": 1784887384.355615,
            "size": 5164
        },
        "/Scripts/Phone.py": {
            "md5": "ed72ce08450154536a3fc1bfa48ff195",
            "timestamp": 1784805478.6882405,
            "size": 61409
        },
        "/Scripts/Elevators.py": {
            "md5": "22a9ae10f5b7de5dab9d24f7c3ebfe6b",
            "timestamp": 1780656892.2954836,
            "size": 4807
        },
        "/Scripts/Cinema.py": {
            "md5": "b12c508669ba0ba8e2ecb9d28d1e6c67",
            "timestamp": 1780656892.2944837,
            "size": 6202
        },
        "/Scripts/Vehicle.py": {
            "md5": "d49e796f759b63562ffb528ea6561c55",
            "timestamp": 1785355966.2386398,
            "size": 238567
        },
        "/Scripts/Tools.py": {
            "md5": "83651477876ad235d0b8a4418b26f595",
            "timestamp": 1784569678.8706474,
            "size": 39372
        },
        "/Scripts/Multiplayer/client.py": {
            "md5": "e2405f106ecf8097face7f30015adeb0",
            "timestamp": 1784496090.6187174,
            "size": 12099
        },
        "/Scripts/Multiplayer/handler.py": {
            "md5": "f8713d54f5cfaa50b78a7ee28ecdd7da",
            "timestamp": 1780656892.2964838,
            "size": 3836
        },
        "/Scripts/Multiplayer/__init__.py": {
            "md5": "d41d8cd98f00b204e9800998ecf8427e",
            "timestamp": 1780656892.2954836,
            "size": 0
        },
        "/animdata/chr/JackBox.json": {
            "md5": "4989f62d59673421bdc34a4a3b938bfc",
            "timestamp": 1780656892.4744837,
            "size": 252
        },
        "/animdata/chr/Other_DaniBox.json": {
            "md5": "f090a21bf9bd36cbe0e0a9ddc18647d9",
            "timestamp": 1783532853.0644312,
            "size": 1740
        },
        "/animdata/chr/PapsBox.json": {
            "md5": "39b98bf3505017411de9386e07fb586d",
            "timestamp": 1780656892.4744837,
            "size": 318
        },
        "/animdata/chr/MoriaBox.json": {
            "md5": "79dd02b85ae9d3f155dcf0f52a023c9f",
            "timestamp": 1780656892.4744837,
            "size": 157
        },
        "/animdata/chr/Dani_Box.json": {
            "md5": "f090a21bf9bd36cbe0e0a9ddc18647d9",
            "timestamp": 1783264575.2172925,
            "size": 1740
        },
        "/animdata/chr/Man1Box.json": {
            "md5": "48b61a6a772cbd92b3e2b64437e7a63a",
            "timestamp": 1780656892.4744837,
            "size": 218
        },
        "/sounds/hit.ogg": {
            "md5": "5803533bebbc46a5d72eff39c804e294",
            "timestamp": 1780656892.4744837,
            "size": 32506
        },
        "/sounds/wood.ogg": {
            "md5": "156ee1e5c52c2abe4955354917fff7d8",
            "timestamp": 1780656892.4744837,
            "size": 13146
        },
        "/sounds/scrape.ogg": {
            "md5": "9c4ba930712f1d2f9b59dc781c31edee",
            "timestamp": 1780656892.4744837,
            "size": 30823
        },
        "/races/Scooter_Race.json": {
            "md5": "b91be963b42cadfd8ee1c81849a834f5",
            "timestamp": 1785355988.4906409,
            "size": 85271
        },
        "/races/Race_Pito.json": {
            "md5": "99a37a4acf6ec9fd4e92c9bbc0bb98f5",
            "timestamp": 1785355988.498641,
            "size": 43509
        },
        "/races/Race_Spiral_Bottom.json": {
            "md5": "b0728edb2f13acac01375b69b89a99a1",
            "timestamp": 1785355988.483641,
            "size": 23444
        },
        "/races/Race_Around_Highway.json": {
            "md5": "e093ba5b630f3f7ddfdca7d2967708e0",
            "timestamp": 1785355988.4716408,
            "size": 44332
        },
        "/races/Grove_Race_1.json": {
            "md5": "fa5ce4f1a9c0080a76f92b8468afc851",
            "timestamp": 1785355988.485641,
            "size": 63715
        },
        "/races/Race_DuneTown_Sign.json": {
            "md5": "db8dd7863adaa2edd26b95ef4de58427",
            "timestamp": 1785355988.481641,
            "size": 60037
        },
        "/races/Hills_Street_Cars_Race.json": {
            "md5": "d1a95490f4e75508ff91a92cd6b2eacd",
            "timestamp": 1785355988.485641,
            "size": 12679
        },
        "/races/Race_Parking_Lot.json": {
            "md5": "d064cc97e29b5768b3f08d421252bd95",
            "timestamp": 1785355988.482641,
            "size": 45079
        },
        "/races/Race_BigBuilding.json": {
            "md5": "6fc7af4d5d72fb5ab714c701497be737",
            "timestamp": 1785355988.503641,
            "size": 54873
        },
        "/races/Race_Karting.json": {
            "md5": "7e9beebf2e4255b4965ae6f5481e1563",
            "timestamp": 1785355988.505641,
            "size": 62659
        },
        "/races/Green_House_Race.json": {
            "md5": "8695dba91bbf7c73a54dc5886832b26e",
            "timestamp": 1785355988.488641,
            "size": 95794
        },
        "/races/SkatePark_Race.json": {
            "md5": "4850bfccf2cde9f95d251dce1e5cdcb4",
            "timestamp": 1785355988.492641,
            "size": 57010
        },
        "/races/Race_3_Buildings.json": {
            "md5": "11ae624a1993724fb46bc8bd86f34a33",
            "timestamp": 1785355988.476641,
            "size": 129003
        },
        "/races/Race_ToRaceTrackAndBack.json": {
            "md5": "d04fe67025baa7e01500c2b40ab8789b",
            "timestamp": 1785355988.4976408,
            "size": 102608
        },
        "/races/Race_Test.json": {
            "md5": "7ae47515eda4da7778bf4cbeedb25f1f",
            "timestamp": 1785355988.465641,
            "size": 126619
        },
        "/races/Mall_Skate_Race.json": {
            "md5": "2644a15aa49df4a23739ebd5eb86a057",
            "timestamp": 1785355988.4946408,
            "size": 84857
        },
        "/races/Crazy_Stunt_Race.json": {
            "md5": "9f2e0f69eeff47916c10081c0e7d968b",
            "timestamp": 1785355988.479641,
            "size": 133275
        },
        "/races/RacetrackRace.json": {
            "md5": "a0257cabb3aa052d07c07ea655e16215",
            "timestamp": 1785355988.501641,
            "size": 122988
        },
        "/races/Race_Highway.json": {
            "md5": "86a011e56cf7bdc16eb7daaa9fb652b8",
            "timestamp": 1785355988.470641,
            "size": 182643
        },
        "/SettingUI/banner.jpg": {
            "md5": "dfa7fae2cb014ca0bee5cbd1585e5de9",
            "timestamp": 1780656892.4754837,
            "size": 565078
        },
        "/SettingUI/banner.png": {
            "md5": "df6ba6e733cffdbbeed81b597591585d",
            "timestamp": 1780656892.4754837,
            "size": 386035
        },
        "/SettingUI/icon.png": {
            "md5": "cbc6b7115ab3c70d2296e6ca3715a379",
            "timestamp": 1782640834.9559813,
            "size": 4145
        },
        "/SettingUI/icons/longest-walk_gold.png": {
            "md5": "01b1f263c983164b9958a6c5935b8675",
            "timestamp": 1783961550.0410278,
            "size": 3539
        },
        "/SettingUI/icons/most-police-stars_gold.png": {
            "md5": "56251c8e2e882201d12079e66c670e2e",
            "timestamp": 1783961550.0430279,
            "size": 4669
        },
        "/SettingUI/icons/Dani_Franzo.png": {
            "md5": "b2a6996af37cada75bcd7ae3acbecaf5",
            "timestamp": 1783961550.036028,
            "size": 2541
        },
        "/SettingUI/icons/most-nice-driving-money_gold.png": {
            "md5": "dcf6867a967a2cc726865b17c8fd2344",
            "timestamp": 1783961550.0430279,
            "size": 4840
        },
        "/SettingUI/icons/longest-gameplay_gold.png": {
            "md5": "6df1269cf549077b443f1a94793a7313",
            "timestamp": 1783961550.0410278,
            "size": 5148
        },
        "/SettingUI/icons/Dani_Travis.png": {
            "md5": "7a72b076fba17cce422b1cb917a06418",
            "timestamp": 1783973432.5386624,
            "size": 2798
        },
        "/SettingUI/icons/money.png": {
            "md5": "5efdbafd203920f3d220e2df507236e4",
            "timestamp": 1783961550.042028,
            "size": 3604
        },
        "/SettingUI/icons/time-played_gold.png": {
            "md5": "051868e25dd9e9092b154022c5f07598",
            "timestamp": 1783961550.0440278,
            "size": 3558
        },
        "/SettingUI/icons/Dani_Daniel.png": {
            "md5": "7a513fa6e01b9fd17ba4b9c23a30a9d9",
            "timestamp": 1784291899.8223927,
            "size": 2404
        },
        "/SettingUI/icons/Dani_Pijamas.png": {
            "md5": "acd9dc4224b5aaedbcda18f748eeb2dd",
            "timestamp": 1783961550.039028,
            "size": 2584
        },
        "/SettingUI/icons/most-nice-driving-money.png": {
            "md5": "44e4308278c3834398ae4be8378bb596",
            "timestamp": 1783961550.0430279,
            "size": 4169
        },
        "/SettingUI/icons/Dani_Like_01.png": {
            "md5": "d654c20d7c01e44e3887a0b70b8a8402",
            "timestamp": 1783961550.0370278,
            "size": 3011
        },
        "/SettingUI/icons/Dani_Chabad_01.png": {
            "md5": "d551bb9b2d90d21654626d995a64fc7a",
            "timestamp": 1783961550.0350277,
            "size": 2615
        },
        "/SettingUI/icons/time-played.png": {
            "md5": "b01a0bf3d411520726a8164d844a3b4b",
            "timestamp": 1783961550.0430279,
            "size": 2364
        },
        "/SettingUI/icons/Dani_Punk.png": {
            "md5": "26feb5f25947c5a96c1eaef54026fc13",
            "timestamp": 1783961550.039028,
            "size": 3468
        },
        "/SettingUI/icons/longest-gameplay.png": {
            "md5": "e77aacd0be11803ec62defc2a2122928",
            "timestamp": 1783961550.0400279,
            "size": 4163
        },
        "/SettingUI/icons/longest-walk.png": {
            "md5": "33f0c9fc827065ca56daf484109d82f3",
            "timestamp": 1783961550.0410278,
            "size": 2378
        },
        "/SettingUI/icons/most-on-time-taxi-deliveries_gold.png": {
            "md5": "1a9836539c257ffb974f8d878d22b1c3",
            "timestamp": 1783971040.6595347,
            "size": 3968
        },
        "/SettingUI/icons/Dani_METAL.png": {
            "md5": "90d602217e37e520a6702eac0ff1d8f9",
            "timestamp": 1783961550.0370278,
            "size": 2881
        },
        "/SettingUI/icons/most-on-time-taxi-deliveries.png": {
            "md5": "dab5ce0862d6cdaba6893c77c840f5da",
            "timestamp": 1783971040.6595347,
            "size": 3445
        },
        "/SettingUI/icons/longest-drive_gold.png": {
            "md5": "90af09976d22379186ac1d78d918a14d",
            "timestamp": 1783961550.0400279,
            "size": 4447
        },
        "/SettingUI/icons/Dani_GOTH.png": {
            "md5": "ba996f29d26c331827684b8b169fc368",
            "timestamp": 1783961550.036028,
            "size": 2521
        },
        "/SettingUI/icons/Dani_Ozoned.png": {
            "md5": "7025eb619eb2da7d705549befbee6e5b",
            "timestamp": 1783961550.0380278,
            "size": 2205
        },
        "/SettingUI/icons/longest-drive.png": {
            "md5": "fd53efb41dc8556851dedfa88fd7510c",
            "timestamp": 1783961550.0400279,
            "size": 3464
        },
        "/SettingUI/icons/most-police-stars.png": {
            "md5": "94b2272e3d2d98019c8cca937f491546",
            "timestamp": 1783961550.0430279,
            "size": 4047
        },
        "/SettingUI/icons/Dani_EMO_01.png": {
            "md5": "e4f69252d01224815b1bfa9e7ff68ddb",
            "timestamp": 1783961550.036028,
            "size": 3295
        },
        "/SettingUI/icons/money_gold.png": {
            "md5": "f61b0b7ac0d660f6d306255d25abd0bb",
            "timestamp": 1783961550.0430279,
            "size": 4723
        }
    },
    "history": {
        "1778099933": {
            "added": [
                "/assembly_copy.blend",
                "/raceline_Race_Test.json",
                "/DanisRace Debug.txt",
                "/notgit.py",
                "/run.py",
                "/SOUNDLICENSES",
                "/http_server.py",
                "/grabbed.txt",
                "/Tux_license.txt",
                "/logo.png",
                "/assembly.blend",
                "/names.json",
                "/search.py",
                "/Update_Force.py",
                "/ScriptSnippits.txt",
                "/#checklist.org#",
                "/depsgraph_research.blend",
                "/LICENSE",
                "/checklist.org",
                "/textures/palm_cutout.png",
                "/textures/MoriasFace.png",
                "/textures/top_left_corner.png",
                "/textures/grey_black.jpg",
                "/textures/city_night.jpg",
                "/textures/islands_foam.png",
                "/textures/city_day.jpg",
                "/textures/crash_3000_light_dots.png",
                "/textures/Underground_front_screen.png",
                "/textures/dirt_normal.jpg",
                "/textures/wheel-board.png",
                "/textures/LogoHat.png",
                "/textures/Shoenormal.png",
                "/textures/karting_place_screen.jpg",
                "/textures/fence.blend",
                "/textures/cliff.jpg",
                "/textures/suzanne.headLight.png",
                "/textures/books.png",
                "/textures/Simulator_screen2.hdr",
                "/textures/racetrack_day.jpg",
                "/textures/GlovesNormal.png",
                "/textures/city_evening.jpg",
                "/textures/bed_texture.jpg",
                "/textures/DaniS_BED-c.png",
                "/textures/dirt.jpg",
                "/textures/black.png",
                "/textures/eyes.jpg",
                "/textures/kloppenheim_06_puresky_4k.exr",
                "/textures/treerings.jpg",
                "/textures/gnomeLogo.png",
                "/textures/tuxwheel.png",
                "/textures/icons.png",
                "/textures/racer_indicator.png",
                "/textures/Bark_Tile.jpg",
                "/textures/Simulator_screen.hdr",
                "/textures/gage.png",
                "/textures/front_part.png",
                "/textures/windows.png",
                "/textures/leather.jpg",
                "/textures/racetrack_evening.jpg",
                "/textures/textures_licenses.txt",
                "/textures/city_morning.jpg",
                "/textures/underground_dots_lines.png",
                "/textures/hallway_images.jpg",
                "/textures/screen.png",
                "/textures/28.hdr",
                "/textures/Paps_Office_Graph.jpg",
                "/textures/Light_dots.png",
                "/textures/arrows.png",
                "/textures/banner_full.jpg",
                "/textures/fire_element2.jpg",
                "/textures/sings.png",
                "/textures/screen_background.jpg",
                "/textures/racers_wallapapers.png",
                "/textures/racetrack_morning.jpg",
                "/textures/GlovesColor.png",
                "/textures/fire_element1.jpg",
                "/textures/Kippa.png",
                "/textures/MoriasPijama.jpg",
                "/textures/NeonSpeedster_leather.jpg",
                "/textures/NightLightBake.jpg",
                "/textures/blank_paper.png",
                "/textures/palm_trunk.jpg",
                "/textures/300.png",
                "/textures/paps_screen_background.jpg",
                "/textures/JacksBodyTexture.png",
                "/textures/DaniS_BED-b.png",
                "/textures/computer_UI_mocks.xcf",
                "/textures/JackFace.png",
                "/textures/Logo.jpg",
                "/textures/boxify.png",
                "/textures/suzanne.stktex_monkey_a.png",
                "/textures/tux_body.png",
                "/textures/tower_cutout.png",
                "/textures/DaniPhoneTexture.png",
                "/textures/oak-branch-c.png",
                "/textures/computer_instructions.png",
                "/textures/tuxengine.png",
                "/textures/Simulator_screen_second_layer.png",
                "/textures/Ground.jpg",
                "/textures/taxi.png",
                "/textures/oak-branch-a.png",
                "/textures/map.jpg",
                "/textures/Morias_BED-c.png",
                "/textures/palmleaf_managable.png",
                "/textures/tuxkart.png",
                "/textures/FaceTextureCM1.png",
                "/textures/Bark_normal.png",
                "/textures/MoriasRacingOutfit.png",
                "/textures/plastic_bullshit.jpg",
                "/textures/racetrack_night.jpg",
                "/textures/metal_fence.png",
                "/textures/satara_night_4k.exr",
                "/textures/Suzanne.Wheel.diffuse.jpg",
                "/textures/cardboard.jpg",
                "/textures/Angry_Puruit.png",
                "/textures/smoke_element1.jpg",
                "/textures/Red_kiss_neon.png",
                "/textures/lightdots.png",
                "/textures/0026.jpg",
                "/textures/tower_infographic.jpg",
                "/textures/DanisFace.png",
                "/textures/nitros.jpg",
                "/textures/computer_instructions.jpg",
                "/textures/wood_fence.jpg",
                "/textures/stk_screenshot.jpg",
                "/textures/bush.png",
                "/textures/green_tree_cutout.png",
                "/textures/PapsFaceTexture.png",
                "/textures/rug.jpg",
                "/textures/Suzanne.kart.diffuse.png",
                "/textures/wasted_screenshot.jpg",
                "/textures/primary.png",
                "/textures/Normalmap.png",
                "/textures/front_light.png",
                "/textures/ads.png",
                "/textures/loading.jpg",
                "/textures/eyes_brown.jpg",
                "/textures/policescreen.jpg",
                "/textures/nitros.xcf",
                "/textures/computericons/icons.png",
                "/textures/towers/tower_infographic_04.jpg",
                "/textures/towers/tower_infographic_02.jpg",
                "/textures/towers/tower_infographic_01.jpg",
                "/textures/towers/tower_infographic_05.jpg",
                "/textures/towers/tower_infographic_03.jpg",
                "/textures/PHONE/normal.png",
                "/textures/PHONE/screen.png",
                "/textures/PHONE/alpha.png",
                "/textures/PHONE/strips_of_light.png",
                "/textures/PHONE/color.png",
                "/textures/PHONE/gloss.png",
                "/textures/sky/city_night.jpg",
                "/textures/sky/city_day.jpg",
                "/textures/sky/racetrack_day.jpg",
                "/textures/sky/city_evening.jpg",
                "/textures/sky/racetrack_evening.jpg",
                "/textures/sky/city_morning.jpg",
                "/textures/sky/racetrack_morning.jpg",
                "/textures/sky/racetrack_night.jpg",
                "/textures/wasted_kart/cardetails1.png",
                "/textures/wasted_kart/carbody.png",
                "/textures/wasted_kart/cardetails2.png",
                "/textures/wasted_kart/tailights.png",
                "/textures/wasted_kart/gigastires.png",
                "/textures/wasted_kart/gigasrims.png",
                "/configs/02_medium.json",
                "/configs/01_low.json",
                "/configs/04_ultra.json",
                "/configs/00_potato.json",
                "/configs/03_high.json",
                "/bgelogic/__init__.py",
                "/bgelogic/NLNodeTree.py",
                "/ast/Shared_Materials.blend",
                "/ast/loc/city.blend",
                "/ast/loc/City_source.blend",
                "/ast/loc/textures/cliff.jpg",
                "/ast/loc/textures/dirt.jpg",
                "/ast/loc/textures/sings.png",
                "/ast/loc/textures/Ground.jpg",
                "/ast/loc/textures/bush.png",
                "/ast/loc/textures/ads.png",
                "/ast/chr/Moria.blend",
                "/ast/chr/Paps.blend",
                "/ast/chr/Jack.blend",
                "/ast/chr/Man1.blend",
                "/ast/veh/RedKiss.blend",
                "/ast/veh/NeonSpeedster.blend",
                "/ast/veh/Truck.blend",
                "/ast/veh/HatchBack01.blend",
                "/ast/veh/DarkShadow.blend",
                "/ast/veh/HatchBack02.blend",
                "/ast/veh/Underground.blend",
                "/ast/veh/Scooter.blend",
                "/ast/veh/Kart.blend",
                "/ast/veh/textures/Paps_Truck_Texture.png",
                "/ast/veh/textures/gear_lever.png",
                "/ast/veh/textures/Front_lights.png",
                "/ast/veh/textures/gear_mechanism.png",
                "/ast/veh/textures/light_dots.png",
                "/ast/veh/textures/front_part.png",
                "/ast/veh/textures/leather.jpg",
                "/ast/veh/textures/tire_text.png",
                "/ast/veh/textures/scren.png",
                "/ast/veh/textures/screen.png",
                "/ast/veh/textures/Light_dots.png",
                "/ast/veh/textures/truck_map.jpg",
                "/ast/veh/textures/LightLInes.png",
                "/ast/veh/textures/map_UI_Over.png",
                "/ast/veh/textures/Paps_Truck_Texture_TEXT2.png",
                "/ast/veh/textures/Paps_Truck_Texture_TEXT.png",
                "/ast/veh/textures/blue_kiss.jpg",
                "/ast/veh/textures/Red_kiss_neon.png",
                "/ast/veh/textures/lightdots.png",
                "/ast/veh/textures/map.png",
                "/ast/veh/textures/front_light.png",
                "/ast/veh/bgelogic/__init__.py",
                "/ast/veh/bgelogic/NLNodeTree.py",
                "/cardata/NeonSpeedsterBox.json",
                "/cardata/HatchBack01Box.json",
                "/cardata/HatchBack02Box.json",
                "/cardata/TruckBox.json",
                "/cardata/ScootBox.json",
                "/cardata/KartBox.json",
                "/cardata/DarkShadowBox.json",
                "/cardata/RedKissBox.json",
                "/cardata/UndergroundBox.json",
                "/music/level_01.ogg",
                "/music/licenses.md",
                "/music/drums.ogg",
                "/music/level_02.ogg",
                "/music/level_03.ogg",
                "/music/level_04.ogg",
                "/fonts/OFL.txt",
                "/fonts/Economica-Regular.ttf",
                "/fonts/Economica-Italic.ttf",
                "/fonts/Economica-BoldItalic.ttf",
                "/fonts/Economica-Bold.ttf",
                "/ScreenPlay/ScriptSnippits.txt",
                "/ScreenPlay/phrases.txt",
                "/ScreenPlay/scene3.fountain",
                "/racedata/raceline_Race_Test.json",
                "/racedata/raceline_Race_ToRaceTrackAndBack.json",
                "/racedata/raceline_Scooter_Race.json",
                "/racedata/raceline_Race_Highway.json",
                "/racedata/raceline_Race_Parking_Lot.json",
                "/racedata/old-data-01.json",
                "/racedata/raceline_RacetrackRace.json",
                "/racedata/raceline_Race_BigBuilding.json",
                "/racedata/raceline_Race_Pito.json",
                "/racedata/record_Race_Highway.json",
                "/racedata/Race_Test_stupid-01.json",
                "/racedata/Race_ToRaceTrackAndBack/data-01.json",
                "/racedata/Race_Pito/data-01.json",
                "/racedata/Race_Test/stupid-02.json",
                "/racedata/Race_Highway/race_targets_Race_Highway.json",
                "/racedata/Race_BigBuilding/data_01.json",
                "/racedata/Race_Parking_Lot/race_targets_Race_Parking_Lot.json",
                "/racedata/RacetrackRace/data-01.json",
                "/sfx/hit.ogg",
                "/sfx/grind.ogg",
                "/sfx/nitro.ogg",
                "/sfx/horn.ogg",
                "/sfx/police.ogg",
                "/sfx/home_door.ogg",
                "/sfx/checkpoint.ogg",
                "/sfx/money.ogg",
                "/sfx/splash.ogg",
                "/sfx/heart.ogg",
                "/sfx/.xdp-telephone_EQ.png-R2HduU",
                "/sfx/wood.ogg",
                "/sfx/fixtool.ogg",
                "/sfx/glass.ogg",
                "/sfx/active.ogg",
                "/sfx/gear_shit.ogg",
                "/sfx/map.xcf",
                "/sfx/scrape.ogg",
                "/sfx/door.ogg",
                "/sfx/boom.ogg",
                "/sfx/drift.ogg",
                "/sfx/air_decompressed.ogg",
                "/sfx/tire_pop.ogg",
                "/sfx/redline.ogg",
                "/sfx/painttool.ogg",
                "/sfx/music/ringtone.ogg",
                "/sfx/engines/regular.ogg",
                "/sfx/engines/scooter.ogg",
                "/sfx/engines/redkiss.ogg",
                "/sfx/engines/truck.ogg",
                "/sfx/engines/neonspeedster.ogg",
                "/sfx/sources/scene_02_03.aup",
                "/sfx/sources/scene_02_02.aup",
                "/sfx/sources/scene_02.aup",
                "/sfx/sources/scene_02_data/eff/d1f/eff1fb00.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f6f8.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1fe6a.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1fd51.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f340.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f9aa.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f0b3.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1fa55.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f539.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1fdee.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f8ed.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f6c0.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f078.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f69c.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f967.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1faf9.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f6c9.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f1f5.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f2d0.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f8c9.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1fffd.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f82a.au",
                "/sfx/sources/scene_02_data/eff/d1f/eff1f090.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1fd42.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f670.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1fcf9.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f50c.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f43b.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f8d8.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f0b4.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f686.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f300.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1fa59.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f89e.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1ff46.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f30c.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f087.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1fd30.au",
                "/sfx/sources/scene_02_02_data/eff/d1f/eff1f540.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f9ca.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f750.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f27a.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1fb0d.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f662.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f4b5.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1ffd8.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f495.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f2a4.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f799.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1fb08.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f043.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f397.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f6e3.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f714.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1fa3e.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f769.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f4b0.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f8f8.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f9e7.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1f9ff.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1fd2d.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1fbf5.au",
                "/sfx/sources/scene_02_03_data/eff/d1f/eff1fa89.au",
                "/sfx/phone/calling.ogg",
                "/sfx/phone/failed.ogg",
                "/sfx/voices/dani/ohgod.ogg",
                "/sfx/voices/dani/yelling.ogg",
                "/sfx/voices/dani/land.ogg",
                "/sfx/voices/dani/entering.ogg",
                "/sfx/voices/dani/walk.ogg",
                "/sfx/voices/dani/jump.ogg",
                "/sfx/voices/dani/wearesinking.ogg",
                "/sfx/voices/dani/ohnoindeed.ogg",
                "/sfx/voices/dani/ohno.ogg",
                "/sfx/voices/angry_pursuit/hit_01.ogg",
                "/sfx/voices/angry_pursuit/start_02.ogg",
                "/sfx/voices/angry_pursuit/start_05.ogg",
                "/sfx/voices/angry_pursuit/hit_05.ogg",
                "/sfx/voices/angry_pursuit/hit_02.ogg",
                "/sfx/voices/angry_pursuit/hit_03.ogg",
                "/sfx/voices/angry_pursuit/start_08.ogg",
                "/sfx/voices/angry_pursuit/start_03.ogg",
                "/sfx/voices/angry_pursuit/start_07.ogg",
                "/sfx/voices/angry_pursuit/start_01.ogg",
                "/sfx/voices/angry_pursuit/start_04.ogg",
                "/sfx/voices/angry_pursuit/start_06.ogg",
                "/sfx/voices/angry_pursuit/hit_04.ogg",
                "/sfx/voices/PapsBox/bored1.ogg",
                "/sfx/voices/Man1Box/voices_script.txt",
                "/sfx/voices/Man1Box/scared2.ogg",
                "/sfx/voices/Man1Box/scared4.ogg",
                "/sfx/voices/Man1Box/scared3.ogg",
                "/sfx/voices/Man1Box/scared1.ogg",
                "/sfx/voices/Man1Box/wait2.ogg",
                "/sfx/voices/Man1Box/wait1.ogg",
                "/sfx/voices/Man1Box/wait3.ogg",
                "/sfx/voices/Man1Box/bored3.ogg",
                "/sfx/voices/Man1Box/bored2.ogg",
                "/sfx/voices/Man1Box/bored1.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/talk_in_car.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/win2.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/brief.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/come.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/go_race.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/win1.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/01.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/dani_I_said_5_minutes.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/paps_ad.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/01_raw.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/lose.ogg",
                "/sfx/voices/scenes/03_Karting_Lessons/get_in_Dani.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/final_paps.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/take_this_power_wrench.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/brief.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/after_race_brief.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/seems_we_have_everything.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/d1.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/tidy_from_below.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/twist.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/get_the_car_out_here.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/no_pick_up_the_car.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/d2.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/final_jack.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/yes.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/pick_up_the_car.ogg",
                "/sfx/voices/scenes/02_Bring_Truck_To_House/final_dani.ogg",
                "/sfx/voices/scenes/01_Bring_Neonspeedster_To_Racetrack/brief.ogg",
                "/sfx/voices/scenes/01_Bring_Neonspeedster_To_Racetrack/win.ogg",
                "/sfx/voices/scenes/01_Bring_Neonspeedster_To_Racetrack/01.ogg",
                "/sfx/voices/scenes/01_Bring_Neonspeedster_To_Racetrack/lose.ogg",
                "/sfx/voices/JackBox/speed5.ogg",
                "/sfx/voices/JackBox/speed6.ogg",
                "/sfx/voices/JackBox/speed7.ogg",
                "/sfx/voices/JackBox/crash3.ogg",
                "/sfx/voices/JackBox/crash5.ogg",
                "/sfx/voices/JackBox/speed8.ogg",
                "/sfx/voices/JackBox/near3.ogg",
                "/sfx/voices/JackBox/speed3.ogg",
                "/sfx/voices/JackBox/speed4.ogg",
                "/sfx/voices/JackBox/bored3.ogg",
                "/sfx/voices/JackBox/crash4.ogg",
                "/sfx/voices/JackBox/crash2.ogg",
                "/sfx/voices/JackBox/near1.ogg",
                "/sfx/voices/JackBox/speed2.ogg",
                "/sfx/voices/JackBox/crash1.ogg",
                "/sfx/voices/JackBox/near2.ogg",
                "/sfx/voices/JackBox/speed1.ogg",
                "/sfx/ambiance/forest.ogg",
                "/sfx/ambiance/water.ogg",
                "/Scripts/Music.py",
                "/Scripts/Common.py",
                "/Scripts/Script.py",
                "/Scripts/Reuse.py",
                "/Scripts/UI.py",
                "/Scripts/Character.py",
                "/Scripts/LEGACY_Car_controll.py",
                "/Scripts/Hints.py",
                "/Scripts/Opt_Old.py",
                "/Scripts/Racing.py",
                "/Scripts/Money.py",
                "/Scripts/Character_Controll.py",
                "/Scripts/Navigation.py",
                "/Scripts/Garage.py",
                "/Scripts/Map.py",
                "/Scripts/Destruction.py",
                "/Scripts/Main_update.py",
                "/Scripts/Doors.py",
                "/Scripts/Input.py",
                "/Scripts/Opt.py",
                "/Scripts/Mouse.py",
                "/Scripts/Settings.py",
                "/Scripts/GameTime.py",
                "/Scripts/Phone.py",
                "/Scripts/Elevators.py",
                "/Scripts/Cinema.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py",
                "/Scripts/Multiplayer/client.py",
                "/Scripts/Multiplayer/handler.py",
                "/Scripts/Multiplayer/__init__.py",
                "/tests/acceleration_mimatching_test.blend",
                "/tests/try_to_break_light_and_Physics.blend",
                "/tests/cleapnups.blend",
                "/tests/graphic_changes_in_force_for_FPS.ods",
                "/tests/kloppenheim_06_puresky_4k.exr",
                "/tests/grid.png",
                "/tests/parenting_bones.blend",
                "/tests/Racetrack.blend",
                "/tests/ragdol.blend",
                "/tests/deletion_detection.blend",
                "/tests/depsgraph_research.blend",
                "/tests/path_finder.blend",
                "/tests/car_test.blend",
                "/tests/race_conditions.py",
                "/tests/depsgraph_variables.blend",
                "/tests/bgelogic/NLLogic.py",
                "/tests/bgelogic/__init__.py",
                "/tests/bgelogic/NLNodeTree.py",
                "/tests/fileIgot/car.blend",
                "/tests/fileIgot/scripts.py",
                "/animdata/chr/JackBox.json",
                "/animdata/chr/PapsBox.json",
                "/animdata/chr/MoriaBox.json",
                "/animdata/chr/Dani_Box.json",
                "/animdata/chr/Man1Box.json",
                "/sounds/hit.ogg",
                "/sounds/wood.ogg",
                "/sounds/scrape.ogg",
                "/races/Scooter_Race.json",
                "/races/Race_Pito.json",
                "/races/Race_Parking_Lot.json",
                "/races/Race_BigBuilding.json",
                "/races/Race_Karting.json",
                "/races/Race_ToRaceTrackAndBack.json",
                "/races/Race_Test.json",
                "/races/RacetrackRace.json",
                "/races/Race_Highway.json",
                "/SettingUI/banner.jpg",
                "/SettingUI/banner.png",
                "/SettingUI/icon.png",
                "/python_dumpster/Multiplayer_Server.py",
                "/python_dumpster/Multiplayer_Client.py",
                "/python_dumpster/Multiplayer_Shared.py",
                "/python_dumpster/Main_update_v22-02-2024.py"
            ],
            "changed": [],
            "text": "Initiating the Notgit history."
        },
        "1778100041": {
            "added": [],
            "changed": [
                "/notgit.py",
                "/Scripts/Phone.py"
            ],
            "text": "Test commit. Should record changes to Phone.py"
        },
        "1778163305": {
            "added": [],
            "changed": [
                "/notgit.py",
                "/grabbed.txt",
                "/assembly.blend",
                "/Scripts/Phone.py"
            ],
            "text": "I guess I fixed the race not starting bug."
        },
        "1778172734": {
            "added": [
                "//raceline_Race_Test.json",
                "//DanisRace Debug.txt",
                "//notgit.py",
                "//run.py",
                "//SOUNDLICENSES",
                "//http_server.py",
                "//grabbed.txt",
                "//Tux_license.txt",
                "//logo.png",
                "//assembly.blend",
                "//names.json",
                "//search.py",
                "//Update_Force.py",
                "//ScriptSnippits.txt",
                "//#checklist.org#",
                "//depsgraph_research.blend",
                "//#notgit.py#",
                "//LICENSE",
                "//checklist.org"
            ],
            "changed": [],
            "text": "Half working notgit.py"
        },
        "1778175282": {
            "added": [
                "//DanisRaceDebug.txt"
            ],
            "changed": [
                "//notgit.py"
            ],
            "text": "Tweaking notgit.py"
        },
        "1778175344": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Tweaking notgit.py more"
        },
        "1778175398": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Tweaking notgit.py more aaaa"
        },
        "1778180094": {
            "added": [],
            "changed": [
                "//notgit.py",
                "//run.py"
            ],
            "text": "Made an updater that somewhat works."
        },
        "1778180820": {
            "added": [],
            "changed": [
                "//run.py"
            ],
            "text": "Made updater more humanlike."
        },
        "1778189592": {
            "added": [],
            "changed": [
                "//notgit.py",
                "//grabbed.txt"
            ],
            "text": "Commiting for Joe"
        },
        "1778271689": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed the racing Rescue bug."
        },
        "1778274084": {
            "added": [],
            "changed": [
                "/Scripts/Character.py"
            ],
            "text": "Made Ragdoll Camera Less Shitty."
        },
        "1778339565": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/ads.png"
            ],
            "text": "Added a Firesidefedi.live ad. Not sponsored."
        },
        "1778340774": {
            "added": [],
            "changed": [
                "/SettingUI/banner.jpg"
            ],
            "text": "Changed Banner to 'Road Rage'"
        },
        "1778346521": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Destruction.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made a shootable missile with 'SHOT' cheatcode."
        },
        "1778348483": {
            "added": [],
            "changed": [
                "/textures/ads.png",
                "/Scripts/Input.py"
            ],
            "text": "Fixed a typo."
        },
        "1778430773": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Garage.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py"
            ],
            "text": "Basic freepositioned attachments working."
        },
        "1778436307": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Garage.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "A New Kit for Neonspeedster to make it look cool."
        },
        "1778446336": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Garage.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py"
            ],
            "text": "Made Kit Parts breakable / tuned the 6C spoiler."
        },
        "1778518948": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Tools.py"
            ],
            "text": "Implemented basic kit bashing Snapping."
        },
        "1778522470": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Garage.py"
            ],
            "text": "Turbo Intake (muscle car type) for Dark Shadow"
        },
        "1778596582": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/cardata/HatchBack01Box.json",
                "/cardata/HatchBack02Box.json"
            ],
            "text": "Made Hatchbacks not as slow. Now they are a bit more fun."
        },
        "1778680103": {
            "added": [],
            "changed": [
                "/Scripts/Garage.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed a few annoyances: Cars spawn with driver and teleportation into nothing."
        },
        "1778685434": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Garage.py"
            ],
            "text": "Added Kit 2 Bumper for Neonspeedster."
        },
        "1778702426": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Garage.py"
            ],
            "text": "Finished Kit 2 fo Neonspeedster"
        },
        "1778766776": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made so you get a bonus for speed as a taxi driver."
        },
        "1778876071": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Racing.py",
                "/Scripts/Phone.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Time Trial Mode ( with ghosts and everything )."
        },
        "1778923551": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Opt.py"
            ],
            "text": "Slightly Less Flickery Scenery."
        },
        "1778930704": {
            "added": [
                "/Scripts/Race_Manager.py"
            ],
            "changed": [
                "//run.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "More optimized files for records."
        },
        "1778934213": {
            "added": [],
            "changed": [
                "//run.py",
                "/Scripts/Common.py",
                "/Scripts/Race_Manager.py"
            ],
            "text": "Basic Scoreboard."
        },
        "1778934423": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "Basic Scoreboard."
        },
        "1778938200": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "Made so could view the racelines of various recordings in scoreboard."
        },
        "1778942016": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Race_Manager.py",
                "/Scripts/Racing.py"
            ],
            "text": "Added data to scoreboard for those that want to share records."
        },
        "1778943791": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py"
            ],
            "text": "Changes to records."
        },
        "1778951612": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Racing.py"
            ],
            "text": "Made area between highway and groove prettier / fixed reverse records."
        },
        "1778951915": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "Added reverse to the score board."
        },
        "1778954017": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend"
            ],
            "text": "Sorry camera... lol"
        },
        "1778955551": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Racing.py"
            ],
            "text": "Sorry my bad. Error in code of precalculation."
        },
        "1779026132": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed Kart not recording a race-record."
        },
        "1779030618": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Racing.py"
            ],
            "text": "Fixed Karting track not working in reverse."
        },
        "1779038108": {
            "added": [
                "/racedata/raceline_Grove_Race_1.json",
                "/races/Grove_Race_1.json"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py",
                "/races/Race_Parking_Lot.json"
            ],
            "text": "Added Grove Race for Hatchbacks"
        },
        "1779038950": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py",
                "/races/Grove_Race_1.json"
            ],
            "text": "Made cops angry when people use nitro."
        },
        "1779050548": {
            "added": [
                "/racedata/record_Race_3_Buildings.json",
                "/races/Race_3_Buildings.json"
            ],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Added 3 buildings race."
        },
        "1779123644": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/races/Race_3_Buildings.json"
            ],
            "text": "Underground Spirals WTF"
        },
        "1779305889": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Navigation.py"
            ],
            "text": "Fixed bug, pathfinding not working in standalone ( rewrote pathfinder, a bit broken )"
        },
        "1779318060": {
            "added": [],
            "changed": [
                "/Scripts/Navigation.py"
            ],
            "text": "Fixed pathfinding. Now not as broken."
        },
        "1779361264": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/map.jpg",
                "/Scripts/Navigation.py",
                "/Scripts/Phone.py"
            ],
            "text": "Fixed pathfinding. Even less boken / map update."
        },
        "1779368156": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Navigation.py",
                "/Scripts/Phone.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Pursuit that is a bit more tenacious."
        },
        "1779455581": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Main_update.py",
                "/Scripts/Input.py",
                "/Scripts/Opt.py"
            ],
            "text": "Made game pretty: Dense forest without much FPS impact + FOG!"
        },
        "1779546052": {
            "added": [
                "/textures/shrubbery.png"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Main_update.py",
                "/Scripts/Opt.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Shrubbery!"
        },
        "1779550899": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Stupider NPC drivers!"
        },
        "1779553407": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaked Car Camera."
        },
        "1779556015": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Slightly less stupid, stupid NPCs"
        },
        "1779564746": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Added an option to make NPC turn less stupidly."
        },
        "1779598729": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Experimenting with authenticifiying keyboard controls."
        },
        "1779628950": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Slightly less shitty car controls."
        },
        "1779636628": {
            "added": [],
            "changed": [
                "/Scripts/Navigation.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made NPC actually kind of nice."
        },
        "1779637683": {
            "added": [],
            "changed": [
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "STUPIDNPCS cheatcode ( makes NPCs go FAST! )"
        },
        "1779708332": {
            "added": [
                "/sfx/voices/Dani_Box/fall1.ogg",
                "/sfx/voices/Dani_Box/yelling1.ogg",
                "/sfx/voices/Dani_Box/ohgod1.ogg",
                "/sfx/voices/Dani_Box/fall2.ogg",
                "/sfx/voices/Man1Box/fall5.ogg",
                "/sfx/voices/Man1Box/fall3.ogg",
                "/sfx/voices/Man1Box/fall1.ogg",
                "/sfx/voices/Man1Box/fall4.ogg",
                "/sfx/voices/Man1Box/fall2.ogg"
            ],
            "changed": [
                "/cardata/ScootBox.json",
                "/Scripts/Music.py",
                "/Scripts/Character.py",
                "/Scripts/Main_update.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made scooter less broken + Yelling"
        },
        "1779708488": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaked Camera"
        },
        "1779709435": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "NPCs now can open the damn racetrack gates themselves."
        },
        "1779711466": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweak spawn system so it would seem like there are more cars on the roads."
        },
        "1779712594": {
            "added": [],
            "changed": [
                "/cardata/ScootBox.json",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaked scooter some more."
        },
        "1779727086": {
            "added": [
                "/textures/concrete_03.jpg"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Racing.py",
                "/Scripts/Opt.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Added a skatepark for the scooter."
        },
        "1779745193": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "You can lean the scoote using walk controls."
        },
        "1780070387": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Music.py",
                "/Scripts/Character.py"
            ],
            "text": "Made shutup function able to shutup specific phrases."
        },
        "1780071357": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Cops spawn at police station."
        },
        "1780085202": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Racing.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py",
                "/animdata/chr/Dani_Box.json",
                "/races/Race_Karting.json"
            ],
            "text": "Now Dani can grab things / Fixed Kart race."
        },
        "1780085731": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py"
            ],
            "text": "Now Dani's telekenezis."
        },
        "1780095955": {
            "added": [
                "/Scripts/Minigames.py"
            ],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Bouncy ball figuring out."
        },
        "1780097053": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Minigames.py"
            ],
            "text": "Bouncy ball."
        },
        "1780141615": {
            "added": [
                "/textures/basketball.jpg"
            ],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Input.py"
            ],
            "text": "Tweaked picking up / Added Dropping ( with throw-charge )."
        },
        "1780178166": {
            "added": [
                "/sfx/swoosh.ogg"
            ],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "New Oh"
        },
        "1780229077": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Destruction.py",
                "/Scripts/Main_update.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Refactored Police Heat."
        },
        "1780243444": {
            "added": [
                "/sfx/voices/Police_Radio/SeeSuspect.ogg",
                "/sfx/voices/Police_Radio/SuspectBoom.ogg",
                "/sfx/voices/Police_Radio/Collision.ogg",
                "/sfx/voices/Police_Radio/Speeding.ogg",
                "/sfx/voices/Police_Radio/Pursuit.ogg",
                "/sfx/voices/Police_Radio/LostVisual.ogg",
                "/sfx/voices/Police_Radio/BreakFence.ogg",
                "/sfx/voices/Man1Box/police_incar.ogg",
                "/sfx/voices/Man1Box/police_code6.ogg",
                "/sfx/voices/Man1Box/police_miranda.ogg"
            ],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Police Pursuit Refactor. Better chasing. Police Radio."
        },
        "1780246332": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaked Police Spawning"
        },
        "1780253368": {
            "added": [],
            "changed": [
                "/cardata/HatchBack01Box.json",
                "/cardata/HatchBack02Box.json",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaked Spawning In General"
        },
        "1780257665": {
            "added": [
                "/sfx/voices/Police_Radio/Pass1.ogg",
                "/sfx/voices/Police_Radio/Carnage3.ogg",
                "/sfx/voices/Police_Radio/BreakFence3.ogg",
                "/sfx/voices/Police_Radio/Carnage2.ogg",
                "/sfx/voices/Police_Radio/Carnage1.ogg",
                "/sfx/voices/Police_Radio/BreakFence4.ogg",
                "/sfx/voices/Police_Radio/Pass2.ogg",
                "/sfx/voices/Police_Radio/Carnage5.ogg",
                "/sfx/voices/Police_Radio/Carnage4.ogg",
                "/sfx/voices/Police_Radio/Pass3.ogg",
                "/sfx/voices/Police_Radio/BreakFence2.ogg"
            ],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Added more calls to Police Radio."
        },
        "1780266198": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "police chase you if you police too."
        },
        "1780267871": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "text": "Ubreak the code."
        },
        "1780331911": {
            "added": [
                "/sfx/voices/Police_Radio/RaceAboutToStart4.ogg",
                "/sfx/voices/Police_Radio/RaceAboutToStart.ogg",
                "/sfx/voices/Police_Radio/RaceAboutToStart3.ogg",
                "/sfx/voices/Police_Radio/RaceStart2.ogg",
                "/sfx/voices/Police_Radio/RaceStart.ogg",
                "/sfx/voices/Police_Radio/RaceStart4.ogg",
                "/sfx/voices/Police_Radio/RaceStart3.ogg",
                "/sfx/voices/Police_Radio/RaceAboutToStart2.ogg"
            ],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Racing.py",
                "/races/Scooter_Race.json",
                "/races/Race_Pito.json",
                "/races/Grove_Race_1.json",
                "/races/Race_Parking_Lot.json",
                "/races/Race_BigBuilding.json",
                "/races/Race_Karting.json",
                "/races/Race_3_Buildings.json",
                "/races/Race_ToRaceTrackAndBack.json",
                "/races/Race_Test.json",
                "/races/RacetrackRace.json",
                "/races/Race_Highway.json"
            ],
            "text": "Illegal races."
        },
        "1780410424": {
            "added": [
                "/sfx/voices/Police_Radio/pito_statue3.ogg",
                "/sfx/voices/Police_Radio/unfinished_bridge2.ogg",
                "/sfx/voices/Police_Radio/grove_suspended_building2.ogg",
                "/sfx/voices/Police_Radio/racetrack3.ogg",
                "/sfx/voices/Police_Radio/racetrack2.ogg",
                "/sfx/voices/Police_Radio/grove_suspended_building3.ogg",
                "/sfx/voices/Police_Radio/grove_pond2.ogg",
                "/sfx/voices/Police_Radio/grove_pond1.ogg",
                "/sfx/voices/Police_Radio/karting_club2.ogg",
                "/sfx/voices/Police_Radio/pito_statue2.ogg",
                "/sfx/voices/Police_Radio/racetrack.ogg",
                "/sfx/voices/Police_Radio/karting_club.ogg",
                "/sfx/voices/Police_Radio/grove_street3.ogg",
                "/sfx/voices/Police_Radio/karting_club3.ogg",
                "/sfx/voices/Police_Radio/grove_skate_park1.ogg",
                "/sfx/voices/Police_Radio/unfinished_bridge3.ogg",
                "/sfx/voices/Police_Radio/police_station.ogg",
                "/sfx/voices/Police_Radio/grove_skate_park2.ogg",
                "/sfx/voices/Police_Radio/police_station2.ogg",
                "/sfx/voices/Police_Radio/grove_pond3.ogg",
                "/sfx/voices/Police_Radio/grove_suspended_building1.ogg",
                "/sfx/voices/Police_Radio/grove_street2.ogg",
                "/sfx/voices/Police_Radio/pito_statue.ogg",
                "/sfx/voices/Police_Radio/grove_street1.ogg",
                "/sfx/voices/Police_Radio/police_station3.ogg",
                "/sfx/voices/Police_Radio/grove_skate_park3.ogg",
                "/sfx/voices/Police_Radio/unfinished_bridge1.ogg"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Map.py",
                "/Scripts/Destruction.py"
            ],
            "text": "Fixed randomly superhard fences / added area names."
        },
        "1780420422": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Adjusted police chase targetting."
        },
        "1780422238": {
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made so jumping out of police car when detained, will not confuse the officer."
        },
        "1780422448": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Slightly unstupidified police."
        },
        "1780423719": {
            "added": [],
            "changed": [
                "/Scripts/Character.py"
            ],
            "text": "Unsuccessfully tried to destupidify police."
        },
        "1780513236": {
            "added": [
                "/sfx/voices/Police_Radio/gta3.ogg",
                "/sfx/voices/Police_Radio/gta1.ogg",
                "/sfx/voices/Police_Radio/gta2.ogg"
            ],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Main_update.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Destupidifying police."
        },
        "1780569744": {
            "added": [],
            "changed": [
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "TIME cheats response is now immediate."
        },
        "1780570153": {
            "added": [],
            "changed": [
                "/Scripts/Input.py"
            ],
            "text": "GIVEMECOPS cheatcode"
        },
        "1780577565": {
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Slightly Less Stupid Human NPCs"
        },
        "1780582438": {
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed Dani goes to Jail."
        },
        "1780586861": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Map.py",
                "/Scripts/Phone.py"
            ],
            "text": "Simple 3D aid for navigation."
        },
        "1780590215": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Racing.py",
                "/Scripts/Map.py"
            ],
            "text": "3D aid for raceline."
        },
        "1780593574": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Did something, too tired to remember what."
        },
        "1780650463": {
            "added": [],
            "changed": [
                "/cardata/ScootBox.json",
                "/Scripts/Vehicle.py"
            ],
            "text": "3D Drag forces!"
        },
        "1780655933": {
            "added": [],
            "changed": [],
            "text": "Test"
        },
        "1780656111": {
            "added": [],
            "changed": [],
            "text": "Testing this bad boy 1"
        },
        "1780656991": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Testing something"
        },
        "1780657692": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Diffs?"
        },
        "1780657765": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Diffs?"
        },
        "1780658008": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Test comment"
        },
        "1780658073": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Another comment"
        },
        "1780658183": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Another comment again"
        },
        "1780658229": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Removed the test comments"
        },
        "1780658498": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Removed uneccesary commented line in one file."
        },
        "1780658647": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Still testing something"
        },
        "1780658698": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Okay it seems like it works."
        },
        "1780663284": {
            "added": [],
            "changed": [
                "/cardata/ScootBox.json",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made scooter easier to control on high speeds."
        },
        "1780665419": {
            "added": [],
            "changed": [
                "/Scripts/Reuse.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "On any Car cheatcode, remove idle cars from memory."
        },
        "1780669140": {
            "added": [
                "/racedata/raceline_Race_DuneTown_Sign.json",
                "/races/Race_DuneTown_Sign.json"
            ],
            "changed": [
                "//notgit.py",
                "//assembly.blend",
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Added Dune Town Sign race."
        },
        "1780673728": {
            "added": [
                "/racedata/raceline_SkatePark_Race.json",
                "/racedata/race_targets_SkatePark_Race.json",
                "/sfx/horn_skate.ogg",
                "/races/SkatePark_Race.json"
            ],
            "changed": [
                "//assembly.blend",
                "/cardata/ScootBox.json",
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py",
                "/races/Race_DuneTown_Sign.json"
            ],
            "text": "Skate Park: Race, Playing Children, Scooter Horn"
        },
        "1780680430": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Re-introducing bug A to fix bug B"
        },
        "1780680492": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "AAAA"
        },
        "1780681071": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "BBBB?"
        },
        "1780694917": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Looks like dramatically improved handling. O.o"
        },
        "1780696621": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed race spawn-pile bug."
        },
        "1780698364": {
            "added": [
                "/racedata/raceline_Race_3_Buildings.json"
            ],
            "changed": [
                "/Scripts/Vehicle.py",
                "/races/Race_3_Buildings.json"
            ],
            "text": "Tweaked steering."
        },
        "1780698512": {
            "added": [],
            "changed": [
                "/Scripts/Destruction.py"
            ],
            "text": "Fixed Dani getting out of car on explosions."
        },
        "1780707325": {
            "added": [],
            "changed": [
                "/cardata/DarkShadowBox.json",
                "/cardata/UndergroundBox.json",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made drifting a tid bit more exiting."
        },
        "1780708588": {
            "added": [],
            "changed": [
                "/cardata/ScootBox.json",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaking Drift"
        },
        "1780741356": {
            "added": [],
            "changed": [
                "/cardata/DarkShadowBox.json",
                "/cardata/RedKissBox.json",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaking Drift More"
        },
        "1780743796": {
            "added": [],
            "changed": [
                "/cardata/NeonSpeedsterBox.json",
                "/cardata/DarkShadowBox.json",
                "/cardata/UndergroundBox.json",
                "/Scripts/Vehicle.py"
            ],
            "text": "Perfecting Drift"
        },
        "1780745154": {
            "added": [],
            "changed": [
                "/cardata/HatchBack01Box.json"
            ],
            "text": "Perfecting Drift: Hatchback1"
        },
        "1780745386": {
            "added": [],
            "changed": [
                "/cardata/HatchBack02Box.json"
            ],
            "text": "Perfecting Drift: Hatchback2"
        },
        "1780747819": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Perfecting Drift Camera"
        },
        "1780758421": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaking Drift to Feel Bette"
        },
        "1780759957": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaking Drift to Feel Better"
        },
        "1780762905": {
            "added": [],
            "changed": [
                "/Scripts/Main_update.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "UNBREAKABLE and HIREGOODLAWYER cheats"
        },
        "1780768418": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Dialing in collisions with other cars."
        },
        "1780769148": {
            "added": [],
            "changed": [
                "/Scripts/Main_update.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Adjusted Police Spawning"
        },
        "1780772129": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Dialing in collisions with other cars."
        },
        "1780780315": {
            "added": [
                "/racedata/raceline_Race_Spiral_Bottom.json",
                "/races/Race_Spiral_Bottom.json"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Input.py",
                "/races/SkatePark_Race.json"
            ],
            "text": "Spiral Race 1"
        },
        "1780861734": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Adjusting Collision for more Arcadiness."
        },
        "1780875941": {
            "added": [
                "/textures/driftsmoke.png"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Map.py",
                "/Scripts/Opt.py",
                "/Scripts/Vehicle.py",
                "/races/Race_Spiral_Bottom.json"
            ],
            "text": "Trying to make it understand which material is where. Not working"
        },
        "1780894060": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Map.py",
                "/Scripts/Opt.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Drift Smoke!"
        },
        "1781004702": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made dirt physics different from road."
        },
        "1781007483": {
            "added": [
                "/sfx/gravel.ogg"
            ],
            "changed": [
                "//SOUNDLICENSES",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tuned dirt physics + gravel sound."
        },
        "1781009164": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Tuning broken endgine sound."
        },
        "1781022410": {
            "added": [
                "/textures/dirt_road.jpg",
                "/textures/dirt_road_normal.jpg",
                "/racedata/raceline_Race_Around_Highway.json",
                "/races/Race_Around_Highway.json"
            ],
            "changed": [
                "//run.py",
                "//assembly.blend",
                "/Scripts/Map.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Offroad Race + Optional Driveline."
        },
        "1781106743": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/racedata/raceline_Race_Around_Highway.json",
                "/races/Race_Around_Highway.json"
            ],
            "text": "Dudes, made Offroad race, more streamlined, Dudes!"
        },
        "1781177153": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Common.py",
                "/Scripts/Main_update.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py",
                "/races/Race_Around_Highway.json"
            ],
            "text": "Basic Controller support for cars."
        },
        "1781185301": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Impoving tactile feeling of the controller vibrator"
        },
        "1781266114": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Common.py",
                "/Scripts/Character.py",
                "/Scripts/Input.py",
                "/Scripts/Mouse.py",
                "/Scripts/Phone.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Added character controller controls"
        },
        "1781290739": {
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Input.py",
                "/Scripts/Mouse.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Smoothefied controller."
        },
        "1781292266": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made collision feedback Stereo"
        },
        "1781363929": {
            "added": [
                "/textures/Dani_Like_01.png"
            ],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Input.py"
            ],
            "text": "Added OUTFITLIKE1 to Dani's Outfits."
        },
        "1781367316": {
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Input.py",
                "/Scripts/Settings.py"
            ],
            "text": "Picking up things with controller."
        },
        "1781372790": {
            "added": [
                "/textures/Dani_Emo_01.png"
            ],
            "changed": [
                "//assembly.blend",
                "/textures/Dani_Like_01.png",
                "/Scripts/Character.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Added OUTFITEMO1 to Dani's Outfits."
        },
        "1781376387": {
            "added": [
                "/textures/Dani_Chabad_01.png"
            ],
            "changed": [
                "//assembly.blend",
                "/textures/Dani_Emo_01.png",
                "/textures/DanisFace.png",
                "/Scripts/Input.py"
            ],
            "text": "Something something or something."
        },
        "1781384033": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Garage.py",
                "/Scripts/Main_update.py",
                "/Scripts/Opt.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Am... Rocket Launcher!!!"
        },
        "1781386186": {
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Mouse.py",
                "/Scripts/Phone.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed, game not working without controller. lol"
        },
        "1781435114": {
            "added": [],
            "changed": [
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Adjusting Missile explosions for stronger fun."
        },
        "1781448210": {
            "added": [],
            "changed": [
                "/Scripts/Opt.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Figured out why police dont respawn when blown up."
        },
        "1781448960": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "More rocket launchers means more frequent shooting."
        },
        "1781458154": {
            "added": [],
            "changed": [
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Smarter rockets. Auto-aim and stuff."
        },
        "1781463608": {
            "added": [
                "/sfx/rocket_lockon.ogg"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Destruction.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Police Shoot You in Return"
        },
        "1781467307": {
            "added": [],
            "changed": [
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Interscepting Rockets"
        },
        "1781474804": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Racing with Rockets"
        },
        "1781483177": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/UI.py",
                "/Scripts/Destruction.py",
                "/Scripts/Main_update.py"
            ],
            "text": "Now Interscepting Rockets actually work."
        },
        "1781521405": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/UI.py",
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tuned police rocket attacking."
        },
        "1781529092": {
            "added": [
                "/sfx/rocket_launch.ogg",
                "/sfx/boom_far.ogg"
            ],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Rocket sounds and stuff."
        },
        "1781530372": {
            "added": [],
            "changed": [
                "/sfx/boom_far.ogg",
                "/Scripts/Destruction.py"
            ],
            "text": "Speed of sound delayed explosions for far away explosions."
        },
        "1781542893": {
            "added": [],
            "changed": [
                "//run.py",
                "//assembly.blend",
                "/Scripts/UI.py",
                "/Scripts/Destruction.py",
                "/Scripts/Settings.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Added an option to customize shooting button."
        },
        "1781544519": {
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt"
            ],
            "text": "Fetch updates now doesn't freeze the window."
        },
        "1781549421": {
            "added": [
                "//default_config.json",
                "//build.py"
            ],
            "changed": [
                "//notgit.py",
                "//run.py",
                "//grabbed.txt"
            ],
            "text": "Made a simple builder."
        },
        "1781716626": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/textures/ads.png"
            ],
            "text": "Added WASTED! ad."
        },
        "1781720817": {
            "added": [
                "/textures/Dani_Franzo.png"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Input.py"
            ],
            "text": "Added Franzo / Wasted Skin!"
        },
        "1781733140": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made spawning a little bit more better probably I guess."
        },
        "1781786524": {
            "added": [
                "/Scripts/Outfits.py"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Settings.py"
            ],
            "text": "First Functional Outfits Store."
        },
        "1781789129": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Outfits.py",
                "/Scripts/Input.py"
            ],
            "text": "Gothic outfit."
        },
        "1781792308": {
            "added": [
                "/textures/Dani_Metal_01.png"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Outfits.py",
                "/Scripts/Input.py"
            ],
            "text": "Metalhead outfit"
        },
        "1781796730": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Eh?"
        },
        "1781798641": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Opt.py"
            ],
            "text": "Changed LOD system to use a different mesh update method."
        },
        "1781819515": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/sfx/boom.ogg",
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Tweaked police rocket fight."
        },
        "1781866804": {
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "text": "Scooter controller controls"
        },
        "1781875060": {
            "added": [
                "/textures/Dani_Punk_shirt.png",
                "/textures/Dani_Punk.png"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Outfits.py",
                "/Scripts/Input.py"
            ],
            "text": "Punk Outfit"
        },
        "1781880754": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Main_update.py",
                "/Scripts/Opt.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "NPC characters spawn system"
        },
        "1781885536": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Input.py"
            ],
            "text": "Made crowds a bit more optimized?"
        },
        "1781889659": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/ads.png"
            ],
            "text": "A Bookstore in the mall."
        },
        "1781892405": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Added pretty entrace to the mall."
        },
        "1781905096": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "GOLD Jewelry Store at Mall."
        },
        "1781909422": {
            "added": [
                "/textures/icecream_shop.png"
            ],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Ice and Cream in the Mall."
        },
        "1781915785": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Outfits.py",
                "/Scripts/Character.py",
                "/Scripts/Phone.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed some storymode bugs."
        },
        "1781916044": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Fixed garage stuff visible before you buy it bug."
        },
        "1781949404": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Improvements for the Mall at Night."
        },
        "1781954698": {
            "added": [
                "/textures/drinks.png"
            ],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Kosher Burger."
        },
        "1781974284": {
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Improved Character navigation."
        },
        "1781980515": {
            "added": [],
            "changed": [
                "/Scripts/Navigation.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Reimplemented Pathfinding. I think it's proper A* now..."
        },
        "1781992903": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Script.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Trying to fix weird bugs about autopilot"
        },
        "1781996152": {
            "added": [],
            "changed": [
                "/Scripts/Script.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Trying to fix weird bugs about autopilot...2"
        },
        "1782041319": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Outfits.py"
            ],
            "text": "Kosher Pizza"
        },
        "1782063640": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Kosher Hotdogs"
        },
        "1782078865": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "Mall toilet + mirror"
        },
        "1782082108": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Main_update.py",
                "/Scripts/Input.py",
                "/Scripts/Opt.py"
            ],
            "text": "Mirror Optimization."
        },
        "1782085081": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/ads.png"
            ],
            "text": "More ads."
        },
        "1782169949": {
            "added": [
                "/textures/money.png"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Main_update.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py"
            ],
            "text": "Money item + Robbing people ( by running them over )"
        },
        "1782172433": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Tools.py"
            ],
            "text": "Items respawn system + a lot more hidden money around the map."
        },
        "1782210786": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Tools.py"
            ],
            "text": "Despaghettified tools code."
        },
        "1782214369": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Tools.py"
            ],
            "text": "Redesigned picking up tools, now you can pick up more than one tool."
        },
        "1782217897": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Tools.py",
                "/animdata/chr/Dani_Box.json"
            ],
            "text": "Garage tools work with controller."
        },
        "1782219226": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Garage.py",
                "/Scripts/Tools.py"
            ],
            "text": "Working Bazooka tool."
        },
        "1782232052": {
            "added": [
                "/sfx/weapon_reload.ogg"
            ],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Destruction.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py"
            ],
            "text": "Changed code so Bazooking will be fun."
        },
        "1782233799": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Tools.py"
            ],
            "text": "Finalizing Bazooka"
        },
        "1782257728": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Finalizing Bazook"
        },
        "1782413271": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Balancing Pursuit"
        },
        "1782421248": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "I think I balanced the cops finally. OMG"
        },
        "1782495051": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Finishing touches to cops balancing."
        },
        "1782512638": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Character.py",
                "/Scripts/Racing.py",
                "/Scripts/Phone.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed racing maybe I guess I dunno"
        },
        "1782516581": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py"
            ],
            "text": "I fixed the racing bug."
        },
        "1782517050": {
            "added": [],
            "changed": [
                "/Scripts/Character.py"
            ],
            "text": "Fixed the not being able to see messages while in pursuit."
        },
        "1782562658": {
            "added": [],
            "changed": [
                "/Scripts/Input.py",
                "/Scripts/Settings.py"
            ],
            "text": "Make game record stuff like time-spends and last session into the save-file."
        },
        "1782569205": {
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt",
                "/Scripts/Settings.py"
            ],
            "text": "Multiple savefiles."
        },
        "1782569432": {
            "added": [],
            "changed": [
                "//run.py"
            ],
            "text": "Multiple savefiles."
        },
        "1782572552": {
            "added": [],
            "changed": [
                "//run.py"
            ],
            "text": "Info about savefiles."
        },
        "1782573887": {
            "added": [],
            "changed": [
                "//grabbed.txt"
            ],
            "text": "Stuff?"
        },
        "1782578435": {
            "added": [],
            "changed": [
                "//notgit.py",
                "//run.py",
                "//grabbed.txt"
            ],
            "text": "Added basic netbased GameID to notgit.py"
        },
        "1782585556": {
            "added": [
                "/Scripts/Online.py"
            ],
            "changed": [
                "//run.py",
                "//grabbed.txt",
                "/Scripts/Main_update.py",
                "/Scripts/Settings.py"
            ],
            "text": "Leaderboard upload works."
        },
        "1782596841": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py",
                "/Scripts/Online.py",
                "/Scripts/Input.py",
                "/Scripts/Settings.py"
            ],
            "text": "Leaderboard race upload ( and basic scoreboard on blenderdumbass.org/danisrace/scoreboard"
        },
        "1782643658": {
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Online.py",
                "/Scripts/Opt.py",
                "/SettingUI/icon.png"
            ],
            "text": "Fixed, changing settings removes username."
        },
        "1782653786": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "Basic scoreboard in launcher."
        },
        "1782654345": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "Basic scoreboard in launcher."
        },
        "1782655276": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "Leaderboard size allocation shananingans."
        },
        "1782661987": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Race_Manager.py"
            ],
            "text": "Leaderboard Races fetch."
        },
        "1782676782": {
            "added": [
                "/racedata/raceline_Hills_Street_Cars_Race.json",
                "/races/Hills_Street_Cars_Race.json"
            ],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/textures/map.jpg",
                "/Scripts/Racing.py",
                "/Scripts/Map.py"
            ],
            "text": "New area and race."
        },
        "1782752325": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Garage.py",
                "/Scripts/Main_update.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Multiplayer/client.py"
            ],
            "text": "Fixed the NaN bug ( cars despawning from Garage )???"
        },
        "1782756224": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Race_Manager.py"
            ],
            "text": "More data on the leaderboard."
        },
        "1782760751": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "More map"
        },
        "1782764742": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "stuff"
        },
        "1782844975": {
            "added": [
                "/textures/Dani_Ozoned.png"
            ],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Outfits.py",
                "/Scripts/Input.py"
            ],
            "text": "Ozoned Skin"
        },
        "1782924692": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/ast/Shared_Materials.blend",
                "/Scripts/Map.py",
                "/Scripts/Input.py"
            ],
            "text": "Greenhouse"
        },
        "1782943222": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Racing.py",
                "/Scripts/Phone.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Race Editor in Phone"
        },
        "1782945915": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py",
                "/Scripts/Phone.py"
            ],
            "text": "Adjustments to Race Editor"
        },
        "1782950879": {
            "added": [],
            "changed": [
                "/Scripts/Script.py",
                "/Scripts/Outfits.py",
                "/Scripts/UI.py",
                "/Scripts/Character.py",
                "/Scripts/Racing.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Changing UI print system"
        },
        "1782952459": {
            "added": [],
            "changed": [
                "/Scripts/UI.py",
                "/Scripts/Main_update.py",
                "/Scripts/Input.py"
            ],
            "text": "Made it so multiple prints all will be shown."
        },
        "1783000285": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py",
                "/Scripts/Phone.py"
            ],
            "text": "Making Race Editor less broken."
        },
        "1783002423": {
            "added": [],
            "changed": [
                "//run.py"
            ],
            "text": "Changed Multiplayer settings UI a bit."
        },
        "1783005162": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py"
            ],
            "text": "Small fix"
        },
        "1783015156": {
            "added": [],
            "changed": [
                "//run.py",
                "/Scripts/Race_Manager.py"
            ],
            "text": "More info in the launcher about users and records."
        },
        "1783028272": {
            "added": [],
            "changed": [
                "//run.py",
                "//assembly.blend",
                "/Scripts/Race_Manager.py",
                "/Scripts/Racing.py",
                "/Scripts/Phone.py",
                "/races/Scooter_Race.json",
                "/races/Race_Pito.json",
                "/races/Race_Spiral_Bottom.json",
                "/races/Race_Around_Highway.json",
                "/races/Grove_Race_1.json",
                "/races/Race_DuneTown_Sign.json",
                "/races/Hills_Street_Cars_Race.json",
                "/races/Race_Parking_Lot.json",
                "/races/Race_BigBuilding.json",
                "/races/Race_Karting.json",
                "/races/SkatePark_Race.json",
                "/races/Race_3_Buildings.json",
                "/races/Race_ToRaceTrackAndBack.json",
                "/races/Race_Test.json",
                "/races/RacetrackRace.json",
                "/races/Race_Highway.json"
            ],
            "text": "Added some basic ways to add functionality to custom races."
        },
        "1783033248": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py",
                "/Scripts/Online.py"
            ],
            "text": "Sharing races works now."
        },
        "1783033644": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Phone.py"
            ],
            "text": "Fixed small bug."
        },
        "1783035595": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Race_Manager.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Few adjustments."
        },
        "1783068314": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Race_Manager.py",
                "/Scripts/Racing.py",
                "/Scripts/Phone.py"
            ],
            "text": "Now you can choose to race a specific ghost."
        },
        "1783069923": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Racing.py"
            ],
            "text": "UI for timetrial mode shows by how much you beat the ghost."
        },
        "1783074764": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed too many karts spawn in the karting club."
        },
        "1783075112": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Phone.py"
            ],
            "text": "Fixed annoying exiting from Phone app when in car camera thing."
        },
        "1783083728": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Adjusted Dani's climbing for better platforming."
        },
        "1783086578": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Racing.py",
                "/Scripts/Phone.py"
            ],
            "text": "Fixed small bug with racing ghosts."
        },
        "1783107568": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Modeling city + changes to code."
        },
        "1783110474": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "text": "IDK maybe something changed."
        },
        "1783116508": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend"
            ],
            "text": "Stuff"
        },
        "1783123153": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "customracebug"
        },
        "1783123748": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "eh?"
        },
        "1783170641": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py",
                "/Scripts/Character.py"
            ],
            "text": "Fixed dani's jumping linearvelocity physics. "
        },
        "1783181294": {
            "added": [
                "/racedata/raceline_Crazy_Stunt_Race.json",
                "/races/Crazy_Stunt_Race.json"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py"
            ],
            "text": "Crazy Stupid Jump Race"
        },
        "1783182729": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py",
                "/races/Crazy_Stunt_Race.json"
            ],
            "text": "Small fixes"
        },
        "1783182989": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/races/Crazy_Stunt_Race.json"
            ],
            "text": "Forgot to name the race properly"
        },
        "1783187236": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/textures/map.jpg"
            ],
            "text": "Map"
        },
        "1783192277": {
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt"
            ],
            "text": "Separated settings into pieces."
        },
        "1783197128": {
            "added": [],
            "changed": [
                "//run.py",
                "/Scripts/Race_Manager.py"
            ],
            "text": "Choose what racerecords to download"
        },
        "1783197503": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "Separated leaderboard from race-records"
        },
        "1783200750": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Map.py",
                "/Scripts/Settings.py"
            ],
            "text": "PRISON"
        },
        "1783216705": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Adjusted stuff about car spawns."
        },
        "1783261333": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/UI.py",
                "/Scripts/Main_update.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Adjusted stuff about car spawns more."
        },
        "1783266676": {
            "added": [],
            "changed": [
                "//run.py",
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Settings.py",
                "/animdata/chr/Dani_Box.json"
            ],
            "text": "Running Dani"
        },
        "1783268574": {
            "added": [],
            "changed": [
                "/Scripts/Character.py"
            ],
            "text": "Balanced out running stamina"
        },
        "1783280662": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Garage.py",
                "/Scripts/Main_update.py",
                "/Scripts/Settings.py",
                "/Scripts/Tools.py"
            ],
            "text": "Remade the inventory."
        },
        "1783280762": {
            "added": [],
            "changed": [
                "/Scripts/Character.py"
            ],
            "text": "Save the dropped money into the save-file"
        },
        "1783286370": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Main_update.py"
            ],
            "text": "Adjusted the jumping and stuff."
        },
        "1783310163": {
            "added": [
                "/sfx/voices/Regular_Radio/host11.ogg",
                "/sfx/voices/Regular_Radio/host10.ogg",
                "/sfx/voices/Regular_Radio/host02.ogg",
                "/sfx/voices/Regular_Radio/host04.ogg",
                "/sfx/voices/Regular_Radio/script.txt",
                "/sfx/voices/Regular_Radio/host09.ogg",
                "/sfx/voices/Regular_Radio/host07.ogg",
                "/sfx/voices/Regular_Radio/host03.ogg",
                "/sfx/voices/Regular_Radio/host08.ogg",
                "/sfx/voices/Regular_Radio/host01.ogg",
                "/sfx/voices/Regular_Radio/ad02.ogg",
                "/sfx/voices/Regular_Radio/host05.ogg",
                "/sfx/voices/Regular_Radio/host06.ogg",
                "/sfx/voices/Regular_Radio/ad03.ogg",
                "/sfx/voices/Regular_Radio/ad01.ogg"
            ],
            "changed": [
                "//run.py",
                "//grabbed.txt",
                "/Scripts/Music.py"
            ],
            "text": "Sort of kind of working radio."
        },
        "1783350207": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Music.py",
                "/Scripts/Character.py"
            ],
            "text": "Radio stuff"
        },
        "1783375680": {
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt"
            ],
            "text": "Fixed multiple save-files, reverting to last game, bug."
        },
        "1783379790": {
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "More stable Physics ( against falling thtrough world )"
        },
        "1783383967": {
            "added": [
                "/sfx/voices/Regular_Radio/noise.ogg"
            ],
            "changed": [
                "/Scripts/Music.py"
            ],
            "text": "Radio static on broken car."
        },
        "1783421557": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Garage.py",
                "/Scripts/Tools.py"
            ],
            "text": "Selling things in Garage."
        },
        "1783440716": {
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt",
                "/Scripts/Race_Manager.py",
                "/Scripts/Character.py",
                "/Scripts/Online.py",
                "/Scripts/Main_update.py",
                "/Scripts/Settings.py"
            ],
            "text": "Deleting custom tracks!"
        },
        "1783446278": {
            "added": [],
            "changed": [
                "/Scripts/UI.py",
                "/Scripts/Character.py",
                "/Scripts/Online.py",
                "/Scripts/Main_update.py",
                "/Scripts/Settings.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Shitty reward system."
        },
        "1783462063": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "text": "Something about the spawn system was kind of broken"
        },
        "1783521079": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Character.py"
            ],
            "text": "Fix AntiFall"
        },
        "1783524330": {
            "added": [],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "text": "Race"
        },
        "1783553601": {
            "added": [
                "/animdata/chr/Other_DaniBox.json"
            ],
            "changed": [
                "//run.py",
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Character.py",
                "/Scripts/Main_update.py",
                "/Scripts/Multiplayer/client.py"
            ],
            "text": "Re-wrote Multiplayer extrapolation, for better multiplayer."
        },
        "1783603798": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Multiplayer/client.py"
            ],
            "text": "Changed the recv to avoid a race condition."
        },
        "1783606977": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Character.py",
                "/Scripts/Main_update.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Cops"
        },
        "1783685440": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed a few annoying things."
        },
        "1783686857": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "text": "Taxis are now save-able in Garage."
        },
        "1783687814": {
            "added": [],
            "changed": [
                "/Scripts/Character.py"
            ],
            "text": "Slightly less broken Taxi mode"
        },
        "1783690594": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "When racing you can see who you beat. Including if you set a world record."
        },
        "1783719034": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "More balanced ( and fun ) rocket racing."
        },
        "1783722646": {
            "added": [],
            "changed": [
                "/Scripts/Racing.py",
                "/Scripts/Navigation.py",
                "/Scripts/Online.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "Made spawning of race NPCs more sane."
        },
        "1783729147": {
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Music.py",
                "/Scripts/Destruction.py"
            ],
            "text": "Rocket inherits car's momentum."
        },
        "1783731742": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "text": "Patched exploit"
        },
        "1783773506": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Racing.py"
            ],
            "text": "World Record"
        },
        "1783811395": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "text": "Fixed a rather peculiar spawning limitation."
        },
        "1783855576": {
            "added": [
                "/sfx/voices/Police_Radio/man_down1.ogg",
                "/sfx/voices/Police_Radio/man_down3.ogg",
                "/sfx/voices/Police_Radio/green_house2.ogg",
                "/sfx/voices/Police_Radio/green_house3.ogg",
                "/sfx/voices/Police_Radio/the_mall1.ogg",
                "/sfx/voices/Police_Radio/man_down2.ogg",
                "/sfx/voices/Police_Radio/the_mall2.ogg",
                "/sfx/voices/Police_Radio/the_mall3.ogg",
                "/sfx/voices/Police_Radio/green_house1.ogg",
                "/sfx/voices/Regular_Radio/host_ad1.ogg",
                "/sfx/voices/Regular_Radio/host_ad3.ogg",
                "/sfx/voices/Regular_Radio/host_ad2.ogg",
                "/sfx/voices/Man1Box/speed5.ogg",
                "/sfx/voices/Man1Box/crash3.ogg",
                "/sfx/voices/Man1Box/crash5.ogg",
                "/sfx/voices/Man1Box/near3.ogg",
                "/sfx/voices/Man1Box/speed3.ogg",
                "/sfx/voices/Man1Box/speed4.ogg",
                "/sfx/voices/Man1Box/crash4.ogg",
                "/sfx/voices/Man1Box/crash2.ogg",
                "/sfx/voices/Man1Box/near1.ogg",
                "/sfx/voices/Man1Box/speed2.ogg",
                "/sfx/voices/Man1Box/crash1.ogg",
                "/sfx/voices/Man1Box/near2.ogg",
                "/sfx/voices/Man1Box/speed1.ogg"
            ],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Character.py",
                "/Scripts/Vehicle.py"
            ],
            "text": "More Audio stuff"
        },
        "1783860066": {
            "added": [
                "/sfx/voices/Man1Box/taxi_grove_skate_park_1.ogg",
                "/sfx/voices/Man1Box/taxi_missed2.ogg",
                "/sfx/voices/Man1Box/taxi_pito_statue_1.ogg",
                "/sfx/voices/Man1Box/taxi_police_station_1.ogg",
                "/sfx/voices/Man1Box/taxi_unfinished_bridge_2.ogg",
                "/sfx/voices/Man1Box/taxi_missed3.ogg",
                "/sfx/voices/Man1Box/taxi_karting_club_1.ogg",
                "/sfx/voices/Man1Box/taxi_grove_skate_park_2.ogg",
                "/sfx/voices/Man1Box/taxi_grove_street_1.ogg",
                "/sfx/voices/Man1Box/taxi_grove_suspended_building_1.ogg",
                "/sfx/voices/Man1Box/taxi_unfinished_bridge_1.ogg",
                "/sfx/voices/Man1Box/taxi_grove_pond_1.ogg",
                "/sfx/voices/Man1Box/taxi_karting_club_2.ogg",
                "/sfx/voices/Man1Box/taxi_pito_statue_2.ogg",
                "/sfx/voices/Man1Box/taxi_grove_street_2.ogg",
                "/sfx/voices/Man1Box/taxi_grove_suspended_building_2.ogg",
                "/sfx/voices/Man1Box/taxi_racetrack_2.ogg",
                "/sfx/voices/Man1Box/taxi_the_mall_1.ogg",
                "/sfx/voices/Man1Box/taxi_green_house_2.ogg",
                "/sfx/voices/Man1Box/taxi_green_house_1.ogg",
                "/sfx/voices/Man1Box/taxi_missed.ogg",
                "/sfx/voices/Man1Box/taxi_racetrack_1.ogg",
                "/sfx/voices/Man1Box/taxi_grove_pond_2.ogg",
                "/sfx/voices/Man1Box/taxi_the_mall_2.ogg",
                "/sfx/voices/Man1Box/taxi_police_station_2.ogg"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "text": "Much better taxi experience"
        },
        "1783877627": {
            "added": [],
            "changed": [
                "//notgit.py",
                "//grabbed.txt"
            ],
            "text": "Doing dev on notgit"
        },
        "1783877659": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783877740": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783877747": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783877925": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783877956": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783877981": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783878009": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783878074": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783878086": {
            "added": [],
            "changed": [],
            "text": "Doing dev on notgit"
        },
        "1783878313": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "text": "Doing dev on notgit"
        },
        "1783878423": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -135,9 +135,14 @@\n         if fil not in oldlist:\n             added.append(fil)\n         elif newlist[fil].get(\"md5\") != oldlist[fil].get(\"md5\"):\n             changed.append(fil)\n+            if fil not in changed_diffs:\n+                changed_diffs[fil] = []\n             try:\n                 f1 = open(GETCWD()+\".notgit/prevcopy/\"+copyname, \"r\").read()\n                 f2 = open(GETCWD()+fil, \"r\").read()\n",
                        "comment": "Adding a diff sub-group for every changed file."
                    },
                    {
                        "diff": "@@ -153,8 +158,9 @@\n                         print()\n                         print(last_change)\n-                        input(\"Comment: \")\n+                        comment = input(\"Comment: \")\n+                        if comment:\n+                            changed_diffs[fil].append({\"diff\":last_change,\"comment\":comment })\n                         last_change = \"\"\n                     line_raw = line[line.find(\" \"):].strip()\n",
                        "comment": "Making sure I can comment on every change in the code."
                    },
                    {
                        "diff": "@@ -162,7 +168,12 @@\n                     if line_raw:\n                         last_change = last_change + line\n+                print()\n+                print(last_change)\n+                comment = input(\"Comment: \")\n+                if comment:\n+                    changed_diffs[fil].append({\"diff\":last_change,\"comment\":comment })\n                 wd = open(GETCWD()+\"/.notgit/lastdiffs/\"+copyname, \"w\")\n                 wd.write(\"\".join(diff))\n",
                        "comment": "This is needed for the last change, since it will happen outside of loop."
                    },
                    {
                        "diff": "@@ -181,6 +192,7 @@\n     data = {}\n     data[\"added\"] = added\n     data[\"changed\"] = changed\n+    data[\"changed_diffs\"] = changed_diffs\n     data[\"text\"] = text\n     try:\n",
                        "comment": "Finally adding the change comments ( with diffs ) into the data of the commit."
                    }
                ]
            },
            "text": "Doing dev on notgit done."
        },
        "1783879025": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -193,6 +193,7 @@\n     data[\"added\"] = added\n     data[\"changed\"] = changed\n     data[\"changed_diffs\"] = changed_diffs\n+    data[\"comment\"] = input(\"Master Comment: \")\n     data[\"text\"] = text\n     try:\n",
                        "comment": "Adding a master comment to the commits. Because I forgot, lol."
                    }
                ]
            },
            "comment": "That is the master comment test.",
            "text": "Doing dev on notgit 3"
        },
        "1783881453": {
            "added": [],
            "changed": [
                "//run.py"
            ],
            "changed_diffs": {
                "//run.py": [
                    {
                        "diff": "@@ -559,40 +559,72 @@\n                 accounted_for = []\n                 updates = update_data.get(\"updates\", {})\n-                for update in updates:\n-                    expander = Gtk.Expander(label=updates[update].get(\"text\", \"Update\"))\n-                    box.pack_start(expander, 0,5,5)\n-                    exbox = Gtk.VBox()\n-                    expander.add(exbox)\n+                for update in reversed(updates):\n+                    updateData = updates[update]\n+                    # Title\n+                    text = \"<span size='large'><b> \"+updateData.get(\"text\", \"Update\")+\"</b></span>\"\n+                    label = Gtk.Label()\n+                    label.set_markup(text)\n+                    label.set_halign(Gtk.Align.START)\n+                    label.set_line_wrap(True)\n+                    box.pack_start(label, 0,5,5)\n+                    # Description\n+                    label = Gtk.Label(label=updateData.get(\"comment\", \"\"))\n+                    label.set_halign(Gtk.Align.START)\n+                    label.set_line_wrap(True)\n+                    box.pack_start(label, 0,5,5)\n                     # Added\n-                    exadded = Gtk.Expander(label=\"    Added (\"+str(len(updates[update].get(\"added\", [])))+\")\")\n-                    exbox.pack_start(exadded, 0,5,5)\n-                    addedbox = Gtk.VBox()\n-                    exadded.add(addedbox)\n-                    for a in updates[update].get(\"added\", []):\n-                        addedbox.pack_start(Gtk.Label(a),0,5,5)\n-                        accounted_for.append(a)\n+                    if updateData.get(\"added\", []):\n+                        label = Gtk.Label(label=\"Added: \")\n+                        label.set_halign(Gtk.Align.START)\n+                        label.set_line_wrap(True)\n+                        box.pack_start(label, 0,20,20)\n+                        for a in updateData.get(\"added\", []):\n+                            label = Gtk.Label(label=a)\n+                            label.set_halign(Gtk.Align.START)\n+                            label.set_line_wrap(True)\n+                            box.pack_start(label, 0,5,5)\n                     # Changed\n-                    exchanged = Gtk.Expander(label=\"    Changed (\"+str(len(updates[update].get(\"changed\", [])))+\")\")\n-                    exbox.pack_start(exchanged, 0,5,5)\n-                    changedbox = Gtk.VBox()\n-                    exchanged.add(changedbox)\n-                    for a in updates[update].get(\"changed\", []):\n-                        changedbox.pack_start(Gtk.Label(a), 0,5,5)\n-                        accounted_for.append(a)\n+                    if updateData.get(\"changed\", []):\n+                        label = Gtk.Label(label=\"Changed: \")\n+                        label.set_halign(Gtk.Align.START)\n+                        label.set_line_wrap(True)\n+                        box.pack_start(label, 0,20,20)\n+                        for a in updateData.get(\"changed\", []):\n+                            label = Gtk.Label(label=a)\n+                            label.set_halign(Gtk.Align.START)\n+                            label.set_line_wrap(True)\n+                            box.pack_start(label, 0,5,5)\n+                            if a in updateData.get(\"changed_diffs\", {}):\n+                                for diff in updateData[\"changed_diffs\"][a]:\n+                                    code = diff.get(\"diff\", \"\")\n+                                    comment = diff.get(\"comment\",\"\")\n+                                    codepart = Gtk.TextView()\n+                                    codepart.set_monospace(True)\n+                                    codebuff = codepart.get_buffer()\n+                                    codebuff.set_text(code)\n+                                    box.pack_start(codepart, 0,5,5)\n+                                    label = Gtk.Label(label=comment)\n+                                    label.set_halign(Gtk.Align.START)\n+                                    label.set_line_wrap(True)\n+                                    box.pack_start(label, 0,5,5)\n+                    box.pack_start(Gtk.HSeparator(), 0,20,20)\n                 additional = []\n                 for a in update_data.get(\"get\", {}):\n",
                        "comment": "This is GUI code for the new diff visible stuff. GTK."
                    }
                ]
            },
            "comment": "Now you can see the diffs in the update windows, with all the comments and stuff.",
            "text": "Making the diffs visible in the GUI"
        },
        "1783883969": {
            "added": [],
            "changed": [
                "//run.py"
            ],
            "changed_diffs": {
                "//run.py": [
                    {
                        "diff": "@@ -612,11 +612,36 @@\n                                     code = diff.get(\"diff\", \"\")\n                                     comment = diff.get(\"comment\",\"\")\n                                     codepart = Gtk.TextView()\n                                     codepart.set_monospace(True)\n                                     codebuff = codepart.get_buffer()\n                                     codebuff.set_text(code)\n                                     box.pack_start(codepart, 0,5,5)\n+                                    tag_lines   = codebuff.create_tag(\"lines\", background=\"#111111\", foreground=\"#4444ff\")\n+                                    tag_added   = codebuff.create_tag(\"added\", background=\"#111111\", foreground=\"#44ff44\")\n+                                    tag_removed = codebuff.create_tag(\"removed\", background=\"#111111\", foreground=\"#ff4444\")\n+                                    for num, line in enumerate(code.splitlines(keepends=True)):\n+                                        if line.startswith(\"+\"):\n+                                            start = codebuff.get_iter_at_line(num)\n+                                            end   = start.copy()\n+                                            end.forward_line()\n+                                            codebuff.apply_tag(tag_added, start, end)\n+                                        elif line.startswith(\"-\"):\n+                                            start = codebuff.get_iter_at_line(num)\n+                                            end   = start.copy()\n+                                            end.forward_line()\n+                                            codebuff.apply_tag(tag_removed, start, end)\n+                                        elif line.startswith(\"@\"):\n+                                            start = codebuff.get_iter_at_line(num)\n+                                            end   = start.copy()\n+                                            end.forward_line()\n+                                            codebuff.apply_tag(tag_lines, start, end)\n                                     label = Gtk.Label(label=comment)\n                                     label.set_halign(Gtk.Align.START)\n",
                        "comment": "This implements the GTK textbuffer tags. 3 of them. To color parts of the diff UI based on the type of line it is. Added lines are green, removed lines are red and line numbers are blue."
                    }
                ]
            },
            "comment": "Makes it easier to see code changes in the updater.",
            "text": "Added Colors To Diff"
        },
        "1783884804": {
            "added": [],
            "changed": [
                "/Scripts/Garage.py",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -321,10 +321,12 @@\n     cont = bge.logic.getCurrentController()\n     dani = scene.objects[\"Dani_Box\"]\n+    computer           = scene.objects[\"Computer\"]    \n+    if computer.get(\"timer\"): computer[\"timer\"] -= 1\n     if str(dani.get(\"tool\")) != \"PowerWrench\" or dani.get(\"tool-attachment\"):\n         return\n-    computer           = scene.objects[\"Computer\"]\n     computerIcon       = scene.objects[\"ComputerIcon\"]\n     computerIconTop    = scene.objects[\"ComputerIcon.Top\"]\n     computerIconBottom = scene.objects[\"ComputerIcon.Bottom\"]\n",
                        "comment": "I had to shuffle the computer timer code for this to work."
                    },
                    {
                        "diff": "@@ -420,7 +422,7 @@\n             computer[\"timer\"] = 5\n             return\n-        if computer.get(\"timer\"): computer[\"timer\"] -= 1\n def Buy(name):\n",
                        "comment": "Still shuffling the computer timer"
                    }
                ],
                "/Scripts/Tools.py": [
                    {
                        "diff": "@@ -433,7 +433,7 @@\n                     FixToolSound()\n                     Character.ApplyAnimation(dani, \"WrenchUse\")\n-                    if c == computer:\n+                    if c == computer and not computer.get(\"timer\"):\n                         price = Garage.shop.get(attachment).get(\"cost\", 100)\n                         sellprice = price * 0.75\n                         Money.Recieve(sellprice)\n",
                        "comment": "Adding a computer timer to the execution of selling."
                    }
                ]
            },
            "comment": "On a controller it would sometimes sell the item immediately as it was bought. On keyboard the buying and selling happens on different buttons, so it didn't bother me at first. But on the controller it is the same exact button. So I need some sort of a timer thing to make it not happen immediately. To give player time to let go of the button. Fortunately this something existed already in the form of compter.get(\"timer\")",
            "text": "Made selling parts less annoying"
        },
        "1783884986": {
            "added": [],
            "changed": [
                "//notgit.py"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -157,6 +157,7 @@\n                     if last_change and line.startswith(\"@\"):\n                         print()\n+                        print(fil)\n                         print(last_change)\n                         comment = input(\"Comment: \")\n                         if comment:\n",
                        "comment": "Added fil ( filename )"
                    },
                    {
                        "diff": "@@ -169,6 +170,7 @@\n                         last_change = last_change + line\n                 print()\n+                print(fil)\n                 print(last_change)\n                 comment = input(\"Comment: \")\n                 if comment:\n",
                        "comment": "Added the same thing here too, for the end of the loop. I should probably make it a function at this point."
                    }
                ]
            },
            "comment": "I was commiting the previous commit and realized I'm not sure which file I was trying to comment about. I had to recognize it from the code itself. And it is not very ideal.",
            "text": "Adding filenames to committing"
        },
        "1783890038": {
            "added": [],
            "changed": [
                "//assembly.blend"
            ],
            "changed_diffs": {
                "//assembly.blend": []
            },
            "comment": "A little park area inside of the mall.",
            "text": "Mall Park"
        },
        "1783891406": {
            "added": [
                "/racedata/raceline_Mall_Skate_Race.json",
                "/races/Mall_Skate_Race.json"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Vehicle.py",
                "/races/Crazy_Stunt_Race.json"
            ],
            "changed_diffs": {
                "//assembly.blend": [],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -5203,7 +5203,8 @@\n     if not car.get(\"driver\"):\n         return\n-    Character.AntiFall(car)\n+    if not car[\"specs\"].get(\"jumpable\"):\n+        Character.AntiFall(car)\n     onground = OnGround(car)\n",
                        "comment": "I noticed that Moria ( other racers ) don't do anything, while they suppose to race you. That is due to the new implementation of AntiFall() that I did a few days ago. Scooters ( for balance ) have their center points low under the floor, which doesn't work well with this AntiFall(). So I don't have it for the scooter. ( I should probably think about how to make it work properly for scooters ). The AntiFall() in UserControl() ( this one is RacingAI() ) was turned of a few days ago already."
                    }
                ],
                "/races/Crazy_Stunt_Race.json": []
            },
            "comment": "",
            "text": "In-Mall Race"
        },
        "1783958924": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": []
            },
            "comment": "For the longest time the City model was scaled up a lot. And I wasn't doing much of anything about it because the materials all of a sudden looked back if I applied the scaling. Today I moved the scaling from relative to object, to global. Allowing me to apply scaling.",
            "text": "Fixed Material Scaling"
        },
        "1783967333": {
            "added": [
                "/SettingUI/icons/longest-walk_gold.png",
                "/SettingUI/icons/most-police-stars_gold.png",
                "/SettingUI/icons/Dani_Franzo.png",
                "/SettingUI/icons/most-nice-driving-money_gold.png",
                "/SettingUI/icons/longest-gameplay_gold.png",
                "/SettingUI/icons/money.png",
                "/SettingUI/icons/time-played_gold.png",
                "/SettingUI/icons/Dani_Pijamas.png",
                "/SettingUI/icons/most-nice-driving-money.png",
                "/SettingUI/icons/Dani_Like_01.png",
                "/SettingUI/icons/Dani_Chabad_01.png",
                "/SettingUI/icons/time-played.png",
                "/SettingUI/icons/Dani_Punk.png",
                "/SettingUI/icons/longest-gameplay.png",
                "/SettingUI/icons/longest-walk.png",
                "/SettingUI/icons/Dani_METAL.png",
                "/SettingUI/icons/longest-drive_gold.png",
                "/SettingUI/icons/Dani_GOTH.png",
                "/SettingUI/icons/Dani_Ozoned.png",
                "/SettingUI/icons/longest-drive.png",
                "/SettingUI/icons/most-police-stars.png",
                "/SettingUI/icons/Dani_EMO_01.png",
                "/SettingUI/icons/money_gold.png"
            ],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "changed_diffs": {
                "/Scripts/Race_Manager.py": [
                    {
                        "diff": "@@ -676,108 +676,201 @@\n     box = Gtk.VBox()\n     scrl.add(box)\n-    RenderUserData(box, userdata.get(\"file\", {}))\n+    RenderUserData(box, userdata.get(\"file\", {}), moreData=userdata)\n     win.show_all()\n     response = win.run()\n     win.destroy()\n-def RenderUserData(detailsBox, data):\n-    timeBox = Gtk.HBox()\n-    detailsBox.pack_start(timeBox, 0,5,5)\n-    timeBox.pack_start(Gtk.Label(\"Time played: \"), 0,5,5)\n-    timeBox.pack_end(Gtk.Label(str(datetime.timedelta(seconds=int(data.get(\"time-played\", 0))))), 0,5,5)\n-    levelBox = Gtk.HBox()\n-    detailsBox.pack_start(levelBox, 0,5,5)\n-    levelBox.pack_start(Gtk.Label(\"Current Level: \"), 0,5,5)\n-    levelBox.pack_end(Gtk.Label(str(data.get(\"currentEvent\")).replace(\"_\",\" \")), 0,5,5)\n-    moneyBox = Gtk.HBox()\n-    detailsBox.pack_start(moneyBox, 0,5,5)\n-    moneyBox.pack_start(Gtk.Label(\"In-game Money: \"), 0,5,5)\n-    moneyBox.pack_end(Gtk.Label(\"$ \"+str(int(data.get(\"money\", 0)))), 0,5,5)\n-    if data.get(\"lastsession\", {}):\n-        detailsBox.pack_start(Gtk.HSeparator(), 0,5,5) #############################\n-        detailsBox.pack_start(Gtk.Label(\"Last Session:\"), 0,5,5)\n-        timeBox = Gtk.HBox()\n-        detailsBox.pack_start(timeBox, 0,5,5)\n-        timeBox.pack_start(Gtk.Label(\"Exited Game: \"), 0,5,5)\n-        lastplayed = str(datetime.datetime.fromtimestamp(int(data.get(\"lastsession\", {}).get(\"timestamp\", 0))))\n-        timeBox.pack_end(Gtk.Label(lastplayed), 0,5,5)\n-        timeBox = Gtk.HBox()\n-        detailsBox.pack_start(timeBox, 0,5,5)\n-        timeBox.pack_start(Gtk.Label(\"Time played: \"), 0,5,5)\n-        timeBox.pack_end(Gtk.Label(str(datetime.timedelta(seconds=int(data.get(\"lastsession\", {}).get(\"time-played\", 0))))), 0,5,5)\n-    if data.get(\"cheats-used\", 0):\n-        detailsBox.pack_start(Gtk.HSeparator(), 0,5,5) #############################\n-        detailsBox.pack_start(Gtk.Label(\"Cheating:\"), 0,5,5)\n-        cheatBox = Gtk.HBox()\n-        detailsBox.pack_start(cheatBox, 0,5,5)\n-        cheatBox.pack_start(Gtk.Label(\"Cheats Used: \"), 0,5,5)\n-        cheatBox.pack_end(Gtk.Label(str(data.get(\"cheats-used\", 0))), 0,5,5)\n-        cheatBox = Gtk.HBox()\n-        detailsBox.pack_start(cheatBox, 0,5,5)\n-        cheatBox.pack_start(Gtk.Label(\"Cheats per minute: \"), 0,5,5)\n-        cheatBox.pack_end(Gtk.Label(str(round(data.get(\"cheats-used\", 0) / ( data.get(\"time-played\", 1) / 60 ), 2))), 0,5,5)\n-        cheatBox = Gtk.HBox()\n-        detailsBox.pack_start(cheatBox, 0,5,5)\n-        cheatBox.pack_start(Gtk.Label(\"Cheating every: \"), 0,5,5)\n-        cheatBox.pack_end(Gtk.Label(str(datetime.timedelta(seconds=int(data.get(\"time-played\", 0) / data.get(\"cheats-used\", 1))))), 0,5,5)\n-    if data.get(\"outfits\", []):\n-        detailsBox.pack_start(Gtk.HSeparator(), 0,5,5) #############################\n-        skinBox = Gtk.HBox()\n-        detailsBox.pack_start(skinBox, 0,5,5)\n-        skinBox.pack_start(Gtk.Label(\"Current Outfit: \"), 0,5,5)\n-        skinBox.pack_end(Gtk.Label(str(data.get(\"outfit\")).replace(\"_\",\" \")), 0,5,5)\n-        detailsBox.pack_start(Gtk.Label(\"Outfits:\"), 0,5,5)\n-        for outfit in data.get(\"outfits\", []):\n-            b = Gtk.HBox()\n-            detailsBox.pack_start(b, 0,5,5)\n-            b.pack_start(Gtk.Label(str(outfit).replace(\"_\", \" \")), 0,5,5)\n-    if data.get(\"cars\", []):\n-        detailsBox.pack_start(Gtk.HSeparator(), 0,5,5) #############################\n-        detailsBox.pack_start(Gtk.Label(\"Cars:\"), 0,5,5)\n-    for car in data.get(\"cars\", []):\n-        b = Gtk.HBox()\n-        detailsBox.pack_start(b, 0,5,5)\n-        string = str(car.get(\"name\", \"Car\")).replace(\"Box\", \"\")\n-        string = string + \", \"+str(int(car.get(\"health\", 1)*100))+\"% health\"\n-        if car.get(\"Spoiler\"):\n-            string = string + \", with Spoiler\"\n-        if car.get(\"NitroCan\"):\n-            string = string + \", with Nitro\"\n-        string = string + \", and with \"+str(len(car.get(\"attachments\", [])))+\" attachments.\"\n-        b.pack_start(Gtk.Label(string), 0,5,5)\n+def Badge(icon, title, description):\n+    # Makes a visible clickable badge for users\n+    button = Gtk.Button()\n+    button_box = Gtk.HBox()\n+    button.add(button_box)\n+    icon_image = Gtk.Image.new_from_file('SettingUI/icons/'+icon+'.png')\n+    button_box.pack_start(icon_image, 0,5,5)\n+    if title:\n+        text = \"<span><b> \"+title+\"</b></span>\"\n+        label = Gtk.Label()\n+        label.set_markup(text)\n+        button_box.pack_start(label, 1,5,5)\n+    def onButton(w, title, description):\n+        dialog = Gtk.MessageDialog(\n+                message_type=Gtk.MessageType.INFO,\n+                buttons=(Gtk.STOCK_OK, Gtk.ResponseType.OK),\n+                text=title)\n+        dialog.format_secondary_text(description)\n+        dialog.run()\n+        dialog.destroy()\n+    button.connect(\"clicked\", onButton, title, description)\n+    return button\n+def RenderUserData(detailsBox, data, moreData={}):\n+    outfit = data.get(\"outfit\", \"Dani_Pijamas\")\n+    outfitname = outfit.replace(\"_\", \" \")\n+    if moreData:\n+        outfitname = data.get(\"username\")\n+    badge = Badge(outfit,\n+                  outfitname,\n+                  \"The skin, this account uses at the moment.\")\n+    detailsBox.pack_start(badge, 0,1,1)\n+    stats_types = {\n+        \"most-nice-driving-money\":[\"$\", \"Most money made driving a car nicely\"],\n+        \"most-police-stars\":[\"\", \"Most police stars at once\"],\n+        \"longest-drive\":[\"time\", \"Longest drive on a single car\"],\n+        \"longest-walk\":[\"time\", \"Longest time without a car.\"],\n+        \"longest-gameplay\":[\"time\", \"Longest single game.\"]\n+    }\n+    ###\n+    double = Gtk.HBox()\n+    detailsBox.pack_start(double, 0,0,0)\n+    ###\n+    if moreData.get(\"badges\", {}):\n+        for stat in moreData[\"badges\"].get(\"gold\", []):\n+            Type, Description = stats_types.get(stat, [\"\", stat.replace(\"-\", \" \")])\n+            badge = Badge(stat+\"_gold\",\n+                          \"\",\n+                          \"Gold Badge for \"+Description)\n+            double.pack_start(badge, 1,1,1)\n+        for stat in moreData[\"badges\"].get(\"silver\", []):\n+            Type, Description = stats_types.get(stat, [\"\", stat.replace(\"-\", \" \")])\n+            badge = Badge(stat,\n+                          \"\",\n+                          \"Silver Badge for \"+Description)\n+            double.pack_start(badge, 1,1,1)\n+    ###\n+    double = Gtk.HBox()\n+    detailsBox.pack_start(double, 0,0,0)\n+    ###\n+    timeplayed = str(datetime.timedelta(seconds=int(data.get(\"time-played\", 0))))\n+    badge = Badge(\"time-played\",\n+                  timeplayed,\n+                  \"The amount of time in total spent playing Dani's Race from this account.\")\n+    double.pack_start(badge, 1,1,1)\n+    inGameMoney = \"$ \"+str(int(data.get(\"money\", 0)))\n+    badge = Badge(\"money\",\n+                  inGameMoney,\n+                  \"The amount of in-game money this account currenly has.\")\n+    double.pack_start(badge, 1,1,1)\n+    ###\n+    double = Gtk.HBox()\n+    detailsBox.pack_start(double, 0,0,0)\n+    ###\n+    for n, stat in enumerate(stats_types):\n+        Type, Description = stats_types[stat]\n+        if Type == \"$\":\n+            stat_amount = \"$ \"+str(int(data.get(stat, 0)))\n+        elif Type == \"time\":\n+            stat_amount = str(datetime.timedelta(seconds=int(data.get(stat, 0))))\n+        else:\n+            stat_amount = str(int(data.get(stat, 0)))\n+        badge = Badge(stat,\n+                      stat_amount,\n+                      Description)\n+        double.pack_start(badge, 1,1,1)\n+        if (n+1) % 2 == 0:\n+            ###\n+            double = Gtk.HBox()\n+            detailsBox.pack_start(double, 0,0,0)\n+            ###\n+    # Racing Records\n+    if moreData.get(\"race_times\", {}):\n+        detailsBox.pack_start(Gtk.HSeparator(), 0,20,20)\n+        detailsBox.pack_start(Gtk.Label(label=\"Racing Best Times:\"), 0,5,5)\n+        liststore = Gtk.ListStore(str, int, str, str, str)\n+        for n, code in enumerate(moreData.get(\"race_times\", {})):\n+            if code.count(\"|\") != 2:\n+                continue\n+            racename, laps, reverse = code.split(\"|\")\n+            try:\n+                laps = int(laps)\n+            except:\n+                continue\n+            reverse_text = \"\"\n+            if reverse == \"True\":\n+                reverse_text = \"Reverse\"\n+            racedata = moreData[\"race_times\"][code]\n+            Time = racedata.get(\"time\", 0)\n+            TimeString = timestring(round(Time,2))\n+            Available = \"\"\n+            if racedata.get(\"file\") in hashes:\n+                Available = \"Available\"\n+            liststore.append([racename,\n+                                  laps,\n+                                  reverse_text,\n+                                  TimeString,\n+                                  Available])\n+        treeview  = Gtk.TreeView(model=liststore)\n+        #treeview.connect(\"row_activated\", clicked)\n+        # Scroller\n+        scrl = Gtk.ScrolledWindow()\n+        scrl.set_size_request(1, 150)\n+        scrl.set_vexpand(True)\n+        detailsBox.pack_start(scrl, 1,1,1)\n+        scrl.add(treeview)\n+        # Race Title | Laps | Reversed | Time | Available\n+        for i, title in enumerate([\"Race\", \"Laps\", \"Reversed\", \"Time\", \"Available\"]):\n+            renderer = Gtk.CellRendererText()\n+            column = Gtk.TreeViewColumn(title, renderer, text=i)\n+            treeview.append_column(column)\n+    # More Data\n+    detailsBox.pack_start(Gtk.HSeparator(), 0,20,20)\n+    expander = Gtk.Expander(label=\"Additional Infomation\")\n+    detailsBox.pack_start(expander, 0,5,5)\n+    if moreData:\n+        DATA = data_widget(moreData)\n+    else:\n+        DATA = data_widget(data)\n+    expander.add(DATA)\n raceboxes = {}\n",
                        "comment": "This is me deleting old code that results in a boring looking user-ui. And instead writing a better UI."
                    },
                    {
                        "diff": "@@ -1100,3 +1193,52 @@\n     win.destroy()\n+def populate_dict(treeStore, data, parent=None):\n+    # This will take a dictionary and populate a tree out of it.\n+    if type(data) in [list, tuple]:\n+        # Inspired by the Json visualizer of Firefox\n+        newvalue = {}\n+        for n, i in enumerate(data):\n+            newvalue[n] = i\n+        data = newvalue\n+    for key in data:\n+        value = data[key]\n+        if not type(value) in [dict, list, tuple]:\n+            putvalue = str(value)\n+        else:\n+            putvalue = None\n+        currentIter = treeStore.append(parent, [str(key),putvalue])\n+        if type(value) in [dict, list, tuple]:\n+            populate_dict(treeStore, value, currentIter)\n+def data_widget(data):\n+    # This will create and return a treeview object\n+    data_tree_store = Gtk.TreeStore(str, str)\n+    populate_dict(data_tree_store, data)\n+    data_tree_view = Gtk.TreeView(data_tree_store)\n+    key_column = Gtk.TreeViewColumn(\"Category\")\n+    text_col = Gtk.CellRendererText()\n+    text_col.set_property(\"editable\", True)\n+    key_column.pack_start(text_col, True)\n+    key_column.add_attribute(text_col, \"text\", 0)\n+    data_tree_view.append_column(key_column)\n+    value_column = Gtk.TreeViewColumn(\"Information\")\n+    text_col = Gtk.CellRendererText()\n+    text_col.set_property(\"editable\", True)\n+    value_column.pack_start(text_col, True)\n+    value_column.add_attribute(text_col, \"text\", 1)\n+    data_tree_view.append_column(value_column)\n+    return data_tree_view\n",
                        "comment": "This is me copy-pasting something I did for FastLBRY long time ago. This basically works like the FireFox JSON previewer but in GTK. Useful for \"More Data\" type situations."
                    }
                ]
            },
            "comment": "Implemented UI changes so User windows will look more engaging and colorful.",
            "text": "Reworked UserUI"
        },
        "1783971302": {
            "added": [
                "/SettingUI/icons/most-on-time-taxi-deliveries_gold.png",
                "/SettingUI/icons/most-on-time-taxi-deliveries.png"
            ],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Race_Manager.py",
                "/Scripts/Character.py",
                "/Scripts/Online.py",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Race_Manager.py": [
                    {
                        "diff": "@@ -730,7 +730,8 @@\n         \"most-police-stars\":[\"\", \"Most police stars at once\"],\n         \"longest-drive\":[\"time\", \"Longest drive on a single car\"],\n         \"longest-walk\":[\"time\", \"Longest time without a car.\"],\n-        \"longest-gameplay\":[\"time\", \"Longest single game.\"]\n+        \"longest-gameplay\":[\"time\", \"Longest single game.\"],\n+        \"most-on-time-taxi-deliveries\": [\"\", \"Most people delivered as a taxi driver in one go.\"]\n     }\n     ###\n",
                        "comment": "Adding the taxi metric to the UI"
                    }
                ],
                "/Scripts/Character.py": [
                    {
                        "diff": "@@ -1369,6 +1369,7 @@\n                 car[\"path\"] = []\n                 car[\"taxi_price\"] = Phone.State[\"apps\"][\"MapApp\"][\"waypoint\"].get(\"taxi_fare\", 30)\n                 carD[\"npc\"] = \"autopilot\"\n+            car[\"taxi_delivered_on_time\"] = 0\n",
                        "comment": "Making sure when you enter the car the metric goes to zero."
                    }
                ],
                "/Scripts/Online.py": [
                    {
                        "diff": "@@ -85,6 +85,9 @@\n     },\n     \"longest-gameplay\":{\n         \"title\":\"longest session playing Dani's Race\",\n+    },\n+    \"most-on-time-taxi-deliveries\":{\n+        \"title\":\"Most people delievered on time\\nas a Taxi driver, in one go\"\n     }\n }\n",
                        "comment": "Letting the counter code know what to render in-game when you beat your ( or anybody else's ) record when it comes to the taxi metric."
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -6707,8 +6707,11 @@\n                 bonus = max(0, (carD[\"taxi_timer\"] / ( carD[\"taxi_timer\"] - Tleft )-1) ) * carD[\"taxi_reward\"] / 2\n                 if int(bonus) > 0:\n                     UI.Print(\"You got $\"+str(int(carD[\"taxi_reward\"]))+\"\\n and got $\"+str(int(bonus))+\" for speed.\", important=True)\n+                    car[\"taxi_delivered_on_time\"] = car.get(\"taxi_delivered_on_time\", 0) + 1\n+                    Online.GameStat(\"most-on-time-taxi-deliveries\", car.get(\"taxi_delivered_on_time\", 0))\n                 else:\n                     UI.Print(\"You got $\"+str(int(carD[\"taxi_reward\"])), important=True)\n+                    car[\"taxi_delivered_on_time\"] = 0\n                 Money.Recieve(carD[\"taxi_reward\"]+bonus)\n                 person = carD.get(\"taxi_passanger\")\n",
                        "comment": "Actually counting the taxi metric. Notice it goes to zero if you didn't deliver a person on time."
                    }
                ]
            },
            "comment": "Adding a basic taxi metric, to make taxi mode a bit more competitive. Basically more delivery on time, more points.",
            "text": "Taxi Driver Rank"
        },
        "1783973668": {
            "added": [
                "/textures/Dani_Travis.png",
                "/SettingUI/icons/Dani_Travis.png"
            ],
            "changed": [
                "//assembly.blend",
                "/Scripts/Outfits.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py",
                "/races/Mall_Skate_Race.json"
            ],
            "changed_diffs": {
                "//assembly.blend": [],
                "/Scripts/Outfits.py": [
                    {
                        "diff": "@@ -77,6 +77,10 @@\n         \"cost\":369,\n         \"store\":\"HELLO_AND_WIN\"\n     },\n+    \"Dani_Travis\": {\n+        \"name\":\"Taxi Driver\",\n+        \"default\":False\n+    }\n",
                        "comment": "Adding data about the Dani_Travis skin into the Outfits.py"
                    },
                    {
                        "diff": "@@ -151,7 +155,7 @@\n                                )\n                 else:\n                     Hints.Show(\"Outfit Instructions\"+store,\n-                               \"[Right] and [Left] to change outfits.\",\n+                               \"[Right] and [Left] to change outfits.\\n[\"+outfits.get(currentOutfit, {}).get(\"name\", currentOutfit)+\"]\",\n                                stores[store][\"location\"]\n                                )\n",
                        "comment": "Making it so you can actually see what outfit you are changing to at home."
                    },
                    {
                        "diff": "@@ -225,3 +229,10 @@\n             LIST.append(item)\n     return LIST\n+def Unlock_Hidden(outfit):\n+    if outfit not in bought:\n+        bought.append(outfit)\n+        name = outfits.get(outfit, {}).get(\"name\", outfit.replace(\"_\", \" \"))\n+        UI.Print(\"Unlocked Hidden Outfit\\n\\\"\"+name+\"\\\".\\nReturn home to try it out.\", important=True)\n",
                        "comment": "Adding a function that makes it possible to unlock hidden outfits."
                    }
                ],
                "/Scripts/Input.py": [
                    {
                        "diff": "@@ -176,7 +176,8 @@\n             \"OUTFITGOTH\"   :\"Dani_GOTH\",\n             \"OUTFITMETAL\"  :\"Dani_METAL\",\n             \"OUTFITPUNK\"   :\"Dani_Punk\",\n-            \"OUTFITOZONED\" :\"Dani_Ozoned\"\n+            \"OUTFITOZONED\" :\"Dani_Ozoned\",\n+            \"OUTPUTRAVIS\"  :\"Dani_Travis\"\n         }\n         for i in outfits:\n",
                        "comment": "Adding a cheatcode for Dani_Travis outfit ( I mean, I must see that it's not broken somehow first )"
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -34,6 +34,7 @@\n from Scripts import Doors\n from Scripts import UI\n from Scripts import Online\n+from Scripts import Outfits\n from Scripts import Character\n",
                        "comment": "Adding the Outfits module to Vehicles ( because that is where the logic to unlock it will be )"
                    },
                    {
                        "diff": "@@ -6709,6 +6710,12 @@\n                     UI.Print(\"You got $\"+str(int(carD[\"taxi_reward\"]))+\"\\n and got $\"+str(int(bonus))+\" for speed.\", important=True)\n                     car[\"taxi_delivered_on_time\"] = car.get(\"taxi_delivered_on_time\", 0) + 1\n                     Online.GameStat(\"most-on-time-taxi-deliveries\", car.get(\"taxi_delivered_on_time\", 0))\n+                    # At night you get a Travis outfit\n+                    Time = bge.logic.globalDict[\"time\"]\n+                    if Time > 21 or Time < 6:\n+                        Outfits.Unlock_Hidden(\"Dani_Travis\")\n                 else:\n                     UI.Print(\"You got $\"+str(int(carD[\"taxi_reward\"])), important=True)\n                     car[\"taxi_delivered_on_time\"] = 0\n",
                        "comment": "Adding the logic to unlock Dani_Travis. Specifically between 21:00 and 6:00 if you deliver anybody on time, you get this skin."
                    }
                ],
                "/races/Mall_Skate_Race.json": []
            },
            "comment": "Adding Dani_Travis, but as a whole, adding a whole concept of unlockable hidden skins.",
            "text": "Hidden Skin Dani Travis"
        },
        "1783979469": {
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Online.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Online.py": [
                    {
                        "diff": "@@ -101,7 +101,7 @@\n     for stat in regular_stats:\n         user_stats[stat] = data.get(stat, 0)\n         if user_stats[stat]:\n-            regular_stats[stat][\"had_some\"] = True\n+            regular_stats[stat][\"had_some\"] = user_stats[stat]\n     # Special cases\n     if not user_stats.get(\"longest-gameplay\"):\n",
                        "comment": "Instead of simply recording if you had any record on the start of the game at a category, we record what that record was ( for the sake of if statements in python everything above 0 is the same as True )."
                    },
                    {
                        "diff": "@@ -140,6 +140,9 @@\n             savefile = online_stats[user].get(\"file\", {})\n             if savefile.get(stat, 0) and value > savefile.get(stat, 0):\n+                if regular_stats[stat].get(\"had_some\", 0) > savefile.get(stat, 0):\n+                    continue\n                 if not \"online\" in regular_stats[stat]:\n                     regular_stats[stat][\"online\"] = {}\n                 if not user in regular_stats[stat][\"online\"]:\n",
                        "comment": "Then if the online record we beat is lower than the record we had on the start of the game, we ignore it."
                    }
                ]
            },
            "comment": "Made it ignore records that you have already beaten.",
            "text": "Made You have Beat the record less annoying"
        },
        "1784051471": {
            "comment": "When I commit I want to comment first about everything and then about the changes. Otherwise it might miss it in the end.",
            "added": [],
            "changed": [
                "//notgit.py",
                "/textures/icons.png"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -119,6 +119,8 @@\n     changed = []\n     changed_diffs = {}\n+    data = {}\n+    data[\"comment\"] = input(\"Master Comment: \")\n     for fil in newlist:\n",
                        "comment": "I had to move the begining of the data before the for loop. And the input too."
                    },
                    {
                        "diff": "@@ -191,11 +193,10 @@\n                 pass\n-    data = {}\n     data[\"added\"] = added\n     data[\"changed\"] = changed\n     data[\"changed_diffs\"] = changed_diffs\n-    data[\"comment\"] = input(\"Master Comment: \")\n     data[\"text\"] = text\n     try:\n",
                        "comment": "And remove them ( obviously ) from their previous position."
                    }
                ],
                "/textures/icons.png": []
            },
            "text": "Moving master comment to the front"
        },
        "1784108336": {
            "comment": "Making the commits more colorful to be able to read the diffs easiers.",
            "added": [],
            "changed": [
                "//notgit.py",
                "//grabbed.txt",
                "/Scripts/Phone.py"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -10,6 +10,8 @@\n import zlib\n import urllib.request\n+from Scripts.Common import *\n fetchurl = \"https://blenderdumbass.org/danisrace/json/\"\n downloadurl = \"https://blenderdumbass.org/danisrace/download\"\n # For source code of this server API\n",
                        "comment": "added everything in Scripts.Common so I could have the shorthands for color excape codes, called \"clr\" in the Common file."
                    },
                    {
                        "diff": "@@ -121,6 +123,18 @@\n     changed_diffs = {}\n     data = {}\n     data[\"comment\"] = input(\"Master Comment: \")\n+    def PrintLastChange(text):\n+        for i in text.split(\"\\n\"):\n+            if i.startswith(\"@\"):\n+                print(clr[\"tdbu\"]+i+clr[\"norm\"])\n+            elif i.startswith(\"+\"):\n+                print(clr[\"tdgr\"]+i+clr[\"norm\"])\n+            elif i.startswith(\"-\"):\n+                print(clr[\"tdrd\"]+i+clr[\"norm\"])\n+            else:\n+                print(i)\n     for fil in newlist:\n",
                        "comment": "Made a small print funtion for any diff section."
                    },
                    {
                        "diff": "@@ -160,7 +174,7 @@\n                         print()\n                         print(fil)\n-                        print(last_change)\n+                        PrintLastChange(last_change)\n                         comment = input(\"Comment: \")\n                         if comment:\n                             changed_diffs[fil].append({\"diff\":last_change,\"comment\":comment })\n",
                        "comment": "Replaced the print in the loop."
                    },
                    {
                        "diff": "@@ -173,7 +187,7 @@\n                 print()\n                 print(fil)\n-                print(last_change)\n+                PrintLastChange(last_change)\n                 comment = input(\"Comment: \")\n                 if comment:\n                     changed_diffs[fil].append({\"diff\":last_change,\"comment\":comment })\n",
                        "comment": "Replaced the diff after the loop ends for the last diff."
                    }
                ],
                "//grabbed.txt": [],
                "/Scripts/Phone.py": [
                    {
                        "diff": "@@ -239,6 +239,7 @@\n     \"taxi\":[7,6],\n     \"racing_app\":[7,7],\n     \"racing_editor\":[7,8],\n+    \"chat\":[7,9],\n     \"paps\":[4,0],\n     \"moria\":[4,1],\n",
                        "comment": "Opps. This is not supposed to be here. Wrong commit. I'm developing a chat app for multiplayer. This is me adding the icon into the list."
                    },
                    {
                        "diff": "@@ -582,6 +583,18 @@\n          size=0.3,\n          execute=MenuApp_Racing_Editor)\n+    def MenuApp_Chat():\n+        State[\"app\"] = RacingEditorApp\n+    Icon(\"MenuApp_Chat\",\n+         \"chat\",\n+         position=(-0.2,-0.2),\n+         size=0.3,\n+         execute=MenuApp_Chat)\n     Icon(\"PhoneBookApp_Cancel\",\n          \"back\",\n",
                        "comment": "And me adding the icon into the MenuApp"
                    }
                ]
            },
            "text": "Making the diffs colorful on commit"
        },
        "1784108781": {
            "comment": "This is a test to see if this comment now appears ABOVE the \"Files Changed:\" message. LOL",
            "added": [],
            "changed": [
                "/Scripts/Phone.py"
            ],
            "changed_diffs": {
                "/Scripts/Phone.py": [
                    {
                        "diff": "@@ -1881,6 +1881,22 @@\n                  size=0.3,\n                  execute=Cancel)\n+def ChatApp():\n+    scene = bge.logic.getCurrentScene()\n+    dani = scene.objects[\"Dani_Box\"]\n+    cam = scene.active_camera\n+    settings = bge.logic.globalDict.get(\"settings\")\n+    def Cancel():\n+        State[\"app\"] = MenuApp\n+    Icon(\"PhoneBookApp_Cancel\",\n+         \"back\",\n+         position=(0,-0.8),\n+         size=0.3,\n+         execute=Cancel)\n State = {\n",
                        "comment": "Added some stuff to the code ( basic app with an exit button )."
                    }
                ]
            },
            "text": "Adding basic Chat App"
        },
        "1784120252": {
            "comment": "At the moment the chat app is only used for the game messages. You can see the backlog of them. I will soon work on adding multiplayer chat there.",
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Common.py",
                "/Scripts/UI.py",
                "/Scripts/Phone.py"
            ],
            "changed_diffs": {
                "//assembly.blend": [],
                "/Scripts/Common.py": [
                    {
                        "diff": "@@ -91,6 +91,10 @@\n     \"=\":66,\n     \"[\":67,\n     \"]\":68,\n+    \",\":10,\n+    \".\":12,\n+    \"?\":64,\n     \"F1\" :88,\n     \"F2\" :89,\n",
                        "comment": "I had to add basic thing like , . and ? to the list of known buttons so typing would be possible."
                    }
                ],
                "/Scripts/UI.py": [
                    {
                        "diff": "@@ -13,6 +13,7 @@\n from Scripts import Opt\n from Scripts import Reuse\n+from Scripts import Phone\n from Scripts import Vehicle\n def UpdateFPSCounter():\n",
                        "comment": "To make the game messages store in chat, I need the Phone module in UI.py"
                    },
                    {
                        "diff": "@@ -98,7 +99,12 @@\n         important = importants.pop(0)\n         lastprint = bge.logic.getRealTime()\n-        if important and bge.logic.globalDict.get(\"last_print\") != bge.logic.globalDict.get(\"print\"):\n-            bge.logic.globalDict[\"SoundDevice\"].play(bge.logic.globalDict[\"sounds\"][\"active\"][\"sound\"]) # Play a Ding\n+        if bge.logic.globalDict.get(\"last_print\") != bge.logic.globalDict.get(\"print\"):\n+            Phone.ChatSend(\"Messages\", bge.logic.globalDict[\"print\"] ) \n+            if important:\n+                bge.logic.globalDict[\"SoundDevice\"].play(bge.logic.globalDict[\"sounds\"][\"active\"][\"sound\"]) # Play a Ding\n",
                        "comment": "On new message, it sends said message to the phone."
                    }
                ],
                "/Scripts/Phone.py": [
                    {
                        "diff": "@@ -319,7 +319,7 @@\n         State[\"timer\"] = 15\n-def Text(ID, text, position=(0,0), size=1.0):\n+def Text(ID, text, position=(0,0), size=1.0, TOP=\"TOP\", CENTER=\"CENTER\"):\n     # Scene stuff\n     scene = bge.logic.getCurrentScene()\n",
                        "comment": "Added an option to the UI text in the phone to be not only anchored to the TOP and to the Center."
                    },
                    {
                        "diff": "@@ -343,8 +343,8 @@\n         text, bold = Hints.AutoBold(text)\n         obj.blenderObject.data = obj.blenderObject.data.copy()\n-        obj.blenderObject.data.align_y = 'TOP'\n-        obj.blenderObject.data.align_x = 'CENTER'\n+        obj.blenderObject.data.align_y = TOP\n+        obj.blenderObject.data.align_x = CENTER\n         # Update text\n",
                        "comment": "This makes the new TOP and CENTER options actually do something."
                    },
                    {
                        "diff": "@@ -585,7 +585,7 @@\n     def MenuApp_Chat():\n-        State[\"app\"] = RacingEditorApp\n+        State[\"app\"] = ChatApp\n     Icon(\"MenuApp_Chat\",\n",
                        "comment": "Actually made the chat app button go to the chat app."
                    },
                    {
                        "diff": "@@ -1888,16 +1888,188 @@\n     cam = scene.active_camera\n     settings = bge.logic.globalDict.get(\"settings\")\n+    Box(\"ChatApp_Box1\",\n+        position=(0.0,0.0),\n+        size=(1.5,3))\n+    Text(\"ChatApp_Buffer\",\n+         \"\",\n+         position=(-0.3,0.6),\n+         size=0.15,\n+         CENTER=\"LEFT\")\n+    # We need the object itself directly because editing\n+    # it's text is far less depsgraph then \"refreshing\" it\n+    # ( despawning and spawning it ) all the time.\n+    database = bge.logic.globalDict[\"phone-icons\"]\n+    TextObject = database[\"ChatApp_Buffer\"][\"obj\"]\n+    State[\"apps\"][\"ChatApp\"][\"chatBuffer\"] = TextObject\n+    if not State[\"apps\"][\"ChatApp\"][\"currentChat\"]:\n+        text = \"\"\n+        page = State[\"apps\"][\"ChatApp\"][\"page\"]\n+        buffSize = 15\n+        offset = page * buffSize\n+        # Mouse over\n+        mouse = bge.logic.mouse\n+        pos = list(mouse.position)\n+        # Adjusting the mouse position to icon position.\n+        pos = (\n+            (pos[0] - 0.5) *  4.4,\n+            (pos[1] - 0.5) * -2.2\n+               )\n+        max_item = 0.5199\n+        min_item = -0.2179\n+        dis_item = max_item - min_item\n+        per_item = dis_item / 10\n+        click = mousecodes[\"LMB\"] in bge.logic.globalDict[\"mouse\"]\n+        for n, chat in enumerate(State[\"apps\"][\"ChatApp\"][\"chats\"]):\n+            n -= offset\n+            if n < 0: continue\n+            if n > buffSize - 1: break\n+            text = text + chat + \"\\n\"\n+            # Mouse over\n+            np = max_item - ( n * per_item )\n+            if np - ( per_item / 2 ) < pos[1] < np + ( per_item / 2 ):\n+                def ChatSelect():\n+                    State[\"apps\"][\"ChatApp\"][\"currentChat\"] = chat\n+                    State[\"apps\"][\"ChatApp\"][\"page\"] = 0\n+                Icon(\"Chat_Chat_Select\",\n+                     \"chat\",\n+                     position=(0.3, np + ( per_item / 2 )),\n+                     size=0.2,\n+                     execute=ChatSelect)\n+    else:\n+        currentChat = State[\"apps\"][\"ChatApp\"][\"currentChat\"]\n+        messages = State[\"apps\"][\"ChatApp\"][\"chats\"].get(currentChat, [])\n+        text = \"\\n\"*16\n+        lineLength = 25\n+        for message in messages:\n+            for line in message.split(\"\\n\"):\n+                n = 0\n+                for word in line.split(\" \"):\n+                    if n + len(word) + 1 > lineLength:\n+                        text = text + \"\\n\"\n+                        n = 0\n+                    text = text + word + \" \"\n+                    n += len(word) + 1\n+                text = text + \"\\n\"\n+            text = text + \"\\n\"\n+        # Typing\n+        Buffer = State[\"apps\"][\"ChatApp\"][\"inputBuffer\"]\n+        Timer  = State[\"apps\"][\"ChatApp\"][\"inputTimer\"]\n+        keys = bge.logic.globalDict[\"keys\"]\n+        changed = False\n+        for key in keys:\n+            for i in keycodes:\n+                if keycodes[i] == key and len(i) == 1:\n+                    if Buffer and i == Buffer[-1].upper() and Timer + 0.2 > bge.logic.getRealTime():\n+                        bge.logic.globalDict[\"keys\"] = []\n+                        break\n+                    if not keycodes[\"LShift\"] in keys:\n+                        i = i.lower()\n+                    State[\"apps\"][\"ChatApp\"][\"inputBuffer\"] = Buffer + i\n+                    changed = True\n+        if keycodes[\"BackSpace\"] in keys and Timer + 0.2 < bge.logic.getRealTime():\n+            State[\"apps\"][\"ChatApp\"][\"inputBuffer\"] = Buffer[:-1]\n+            changed = True\n+        if keycodes[\"Space\"] in keys and Timer + 0.2 < bge.logic.getRealTime():\n+            State[\"apps\"][\"ChatApp\"][\"inputBuffer\"] = Buffer + \" \"\n+            changed = True\n+        if keycodes[\"Enter\"] in keys and Buffer:\n+            username = settings.get(\"username\", getpass.getuser())\n+            ChatSend(State[\"apps\"][\"ChatApp\"][\"currentChat\"], username+\": \"+Buffer)\n+            State[\"apps\"][\"ChatApp\"][\"inputBuffer\"] = \"\"\n+            changed = True\n+        if changed:\n+            State[\"apps\"][\"ChatApp\"][\"inputTimer\"] = bge.logic.getRealTime()\n+            bge.logic.globalDict[\"keys\"] = []\n+        # Cleaning the text\n+        page = (-State[\"apps\"][\"ChatApp\"][\"page\"]) * 15\n+        lines = text.splitlines(keepends=True)\n+        text = \"\".join(lines[len(lines)-15-page:len(lines)-page])\n+        while text.count(\"\\n\") < 16:\n+            text = text + \"\\n\"\n+        text = text + Buffer[-25:]+\"|\"\n+    if TextObject.blenderObject.data.body != text:\n+        TextObject.blenderObject.data.body = text \n+    def PageDown():\n+        State[\"apps\"][\"ChatApp\"][\"page\"] += 1\n+    Icon(\"Chat_Page_Increase\",\n+         \"down\",\n+         position=(0.05, -0.55),\n+         size=0.2,\n+         execute=PageDown)\n+    def PageUp():\n+        State[\"apps\"][\"ChatApp\"][\"page\"] -= 1\n+    Icon(\"Chat_Page_Decrease\",\n+         \"up\",\n+         position=(-0.05, -0.55),\n+         size=0.2,\n+         execute=PageUp)\n     def Cancel():\n-        State[\"app\"] = MenuApp\n-    Icon(\"PhoneBookApp_Cancel\",\n+        if not State[\"apps\"][\"ChatApp\"][\"currentChat\"]:\n+            State[\"app\"] = MenuApp\n+        else:\n+            State[\"apps\"][\"ChatApp\"][\"currentChat\"] = None\n+            State[\"apps\"][\"ChatApp\"][\"page\"] = 0\n+    Icon(\"Chat_Cancel\",\n          \"back\",\n          position=(0,-0.8),\n          size=0.3,\n          execute=Cancel)\n+def ChatSend(chat, message):\n+    if chat not in State[\"apps\"][\"ChatApp\"][\"chats\"]:\n+        State[\"apps\"][\"ChatApp\"][\"chats\"][chat] = []\n+    State[\"apps\"][\"ChatApp\"][\"chats\"][chat].append(message)\n State = {\n     \"app\":None,\n",
                        "comment": "Ths is the chat app itself and a bit in the bottom is the ChatSend function. I will be extending it."
                    },
                    {
                        "diff": "@@ -1912,6 +2084,18 @@\n             \"mouse\":[0.0,0.0],\n             \"settingWaypoint\":False,\n             \"waypoint\":None\n+        },\n+        \"ChatApp\":{\n+            \"currentChat\":None,\n+            \"chatBuffer\":None,\n+            \"inputBuffer\":\"\",\n+            \"inputTimer\":0,\n+            \"page\":0,\n+            \"chats\":{\n+                \"Messages\":[]\n+            }\n         }\n     },\n     \"timer\":0\n",
                        "comment": "ChatApp variables for saving them between game frames."
                    }
                ]
            },
            "text": "Implemented basic chat app"
        },
        "1784140203": {
            "comment": "In the chat app you can now send messages to other players in the multiplayer.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Character.py",
                "/Scripts/Phone.py",
                "/Scripts/Multiplayer/client.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Character.py": [
                    {
                        "diff": "@@ -2751,11 +2751,16 @@\n         # If it is a new object.\n         if netId not in raw_objects:\n             character = Reuse.Create(\"Other_DaniBox\")\n+            chatusername = data.get(\"username\", \"Player\")+\"(\"+str(netId)+\")\"\n+            Phone.State[\"apps\"][\"ChatApp\"][\"chats\"][chatusername] = []\n             character[\"type\"] = \"chr\"\n             character.position    = data.get(\"position\",    (0,0,0))\n             character.orientation = data.get(\"orientation\", (0,0,0))\n             character[\"network\"] = True\n             character[\"username\"] = data.get(\"username\", \"Player\")\n+            character[\"chatusername\"] = chatusername\n             raw_objects[netId] = character\n             SetOutfit(character, data.get(\"outfit\", \"\"))\n",
                        "comment": "When a new player is joined and a new character is spawned into the scene, the phone app gets a new chat, with this user."
                    }
                ],
                "/Scripts/Phone.py": [
                    {
                        "diff": "@@ -19,6 +19,7 @@\n from Scripts import Vehicle\n from Scripts import Racing\n from Scripts import Money\n+from Scripts.Multiplayer import client\n from Scripts.Common import *\n",
                        "comment": "Phone now has multiplayer functionality. So we need to import it."
                    },
                    {
                        "diff": "@@ -2065,10 +2066,20 @@\n          size=0.3,\n          execute=Cancel)\n-def ChatSend(chat, message):\n+def ChatSend(chat, message, fromnet=False):\n     if chat not in State[\"apps\"][\"ChatApp\"][\"chats\"]:\n         State[\"apps\"][\"ChatApp\"][\"chats\"][chat] = []\n     State[\"apps\"][\"ChatApp\"][\"chats\"][chat].append(message)\n+    if not fromnet:\n+        scene = bge.logic.getCurrentScene()\n+        dani = scene.objects[\"Dani_Box\"]\n+        settings = bge.logic.globalDict[\"settings\"]\n+        username = settings.get(\"mp-name\")\n+        netId    = dani.get(\"netId\", \"\")\n+        username_and_netId = str(username)+\"(\"+str(netId)+\")\"\n+        client.message([\"private-message\", username_and_netId, chat, message])\n State = {\n",
                        "comment": "Added the actual sending to server, of the message you type in the chat."
                    }
                ],
                "/Scripts/Multiplayer/client.py": [
                    {
                        "diff": "@@ -21,6 +21,7 @@\n     from Scripts import Destruction\n     from Scripts import Racing\n     from Scripts import Opt\n+    from Scripts import Phone\n     from Scripts.Common import *\n except:\n     pass\n",
                        "comment": "The multiplayer code now can do things in the Phone, so we import it."
                    },
                    {
                        "diff": "@@ -429,7 +430,14 @@\n     message([\"text\", text])\n def deal_messages(data):\n+    scene = bge.logic.getCurrentScene()\n+    dani = scene.objects[\"Dani_Box\"]\n+    settings = bge.logic.globalDict[\"settings\"]\n+    username = settings.get(\"mp-name\")\n+    netId    = dani.get(\"netId\", \"\")\n+    username_and_netId = str(username)+\"(\"+str(netId)+\")\"\n     for m in data:\n         if m[0] == \"text\" and len(m) > 1:\n             bge.logic.globalDict[\"print\"] = str(m[1])\n",
                        "comment": "This is a copy of the same code from the ChatSend() funtion in the Phone ( from this same commit ). It creates a username + netId string to recognize a user."
                    },
                    {
                        "diff": "@@ -438,6 +446,16 @@\n         # Start a race.\n         if m[0] == \"race-start\" and len(m) > 1:\n             Racing.StartRace(m[1], network=True)\n+        # If private message\n+        if m[0] == \"private-message\" and len(m) > 3:\n+            From    = m[1]\n+            To      = m[2]\n+            Message = m[3]\n+            if To == username_and_netId:\n+                Phone.ChatSend(From, Message, fromnet=True)\n def clean_deleted_objects(raw_objects):\n",
                        "comment": "Adding the code to handle incoming chat messages."
                    }
                ]
            },
            "text": "Basic multiplayer chat."
        },
        "1784143505": {
            "comment": "Makes it so you can see when the other person messages you in the multiplayer.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/UI.py",
                "/Scripts/Phone.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/UI.py": [
                    {
                        "diff": "@@ -101,7 +101,9 @@\n         if bge.logic.globalDict.get(\"last_print\") != bge.logic.globalDict.get(\"print\"):\n-            Phone.ChatSend(\"Messages\", bge.logic.globalDict[\"print\"] ) \n+            Phone.ChatSend(\"Messages\", bge.logic.globalDict[\"print\"],\n+                           fromnet=True, # This is a hack, to not send this over the network.\n+                           announce=False) \n             if important:\n                 bge.logic.globalDict[\"SoundDevice\"].play(bge.logic.globalDict[\"sounds\"][\"active\"][\"sound\"]) # Play a Ding\n",
                        "comment": "Turning off this feature specifically in the UI prints ( Messages chat )."
                    }
                ],
                "/Scripts/Phone.py": [
                    {
                        "diff": "@@ -187,6 +187,18 @@\n                 pass\n+    ChatAnnounce = State[\"apps\"][\"ChatApp\"].get(\"announced\") and State[\"apps\"][\"ChatApp\"].get(\"announced\",0) + 10 > bge.logic.getRealTime()\n+    if ChatAnnounce:\n+        read = sum(State[\"apps\"][\"ChatApp\"][\"read\"].values())\n+        ALL  = 0\n+        for chat in State[\"apps\"][\"ChatApp\"][\"chats\"]:\n+            ALL += len(State[\"apps\"][\"ChatApp\"][\"chats\"][chat])\n+        unread = ALL - read\n+        Hints.Show(\"Message Announcements\",\n+                   \"You have \"+str(unread)+\" unread messages\\n[ESC] to go to chat app.\",\n+                   phone)\n",
                        "comment": "Adding a Hints thingie for the announcement itself to the main loop of the phone ( to see outside of the phone )"
                    },
                    {
                        "diff": "@@ -1936,8 +1948,14 @@\n             n -= offset\n             if n < 0: continue\n             if n > buffSize - 1: break\n-            text = text + chat + \"\\n\"\n+            unread_text = \"\"\n+            read = State[\"apps\"][\"ChatApp\"][\"read\"]\n+            unread = len(State[\"apps\"][\"ChatApp\"][\"chats\"][chat]) - read.get(chat, 0) \n+            if unread:\n+                unread_text = \"(\"+str(unread)+\") \"\n+            text = text + unread_text + chat + \"\\n\"\n             # Mouse over\n             np = max_item - ( n * per_item )\n",
                        "comment": "Adding a number of unread chats next to the chat name in chats list."
                    },
                    {
                        "diff": "@@ -1960,6 +1978,9 @@\n         messages = State[\"apps\"][\"ChatApp\"][\"chats\"].get(currentChat, [])\n         text = \"\\n\"*16\n         lineLength = 25\n+        read = len(messages)\n+        State[\"apps\"][\"ChatApp\"][\"read\"][currentChat] = read\n         for message in messages:\n             for line in message.split(\"\\n\"):\n",
                        "comment": "Marking chats as \"read\" when entering the chat."
                    },
                    {
                        "diff": "@@ -2006,7 +2027,7 @@\n         if keycodes[\"Enter\"] in keys and Buffer:\n             username = settings.get(\"username\", getpass.getuser())\n-            ChatSend(State[\"apps\"][\"ChatApp\"][\"currentChat\"], username+\": \"+Buffer)\n+            ChatSend(State[\"apps\"][\"ChatApp\"][\"currentChat\"], username+\": \"+Buffer, announce=False)\n             State[\"apps\"][\"ChatApp\"][\"inputBuffer\"] = \"\"\n             changed = True\n",
                        "comment": "Making sure it doesn't announce your own messages back at you."
                    },
                    {
                        "diff": "@@ -2066,7 +2087,7 @@\n          size=0.3,\n          execute=Cancel)\n-def ChatSend(chat, message, fromnet=False):\n+def ChatSend(chat, message, fromnet=False, announce=True):\n     if chat not in State[\"apps\"][\"ChatApp\"][\"chats\"]:\n         State[\"apps\"][\"ChatApp\"][\"chats\"][chat] = []\n     State[\"apps\"][\"ChatApp\"][\"chats\"][chat].append(message)\n",
                        "comment": "Adding the \"announce\" variable to the ChatSend function"
                    },
                    {
                        "diff": "@@ -2080,7 +2101,10 @@\n         username_and_netId = str(username)+\"(\"+str(netId)+\")\"\n         client.message([\"private-message\", username_and_netId, chat, message])\n+    if announce:\n+        State[\"apps\"][\"ChatApp\"][\"announced\"] = bge.logic.getRealTime()\n+        PlayDing()\n State = {\n     \"app\":None,\n",
                        "comment": "Adding the announce logic tot he ChatSend function"
                    },
                    {
                        "diff": "@@ -2105,7 +2129,8 @@\n             \"chats\":{\n                 \"Messages\":[]\n-            }\n+            },\n+            \"read\":{}\n         }\n     },\n",
                        "comment": "Adding the datapoint for comparing what chats are read and what are unread."
                    }
                ]
            },
            "text": "Multiplayer chat announcement."
        },
        "1784277131": {
            "comment": "Implemented vibration on gear-shift. Had to do a lot of work on the vibration functions to make it work.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Input.py": [
                    {
                        "diff": "@@ -64,21 +64,33 @@\n                     if i < 0: flip = -1\n                     bge.logic.globalDict[\"joystickSticks\"][n] = ( i ** 2 ) * flip\n-            if bge.logic.globalDict.get(\"joystickVibrationSince\", 0) + 0.5 <  bge.logic.getRealTime():\n-                stick.stopVibration()\n-def VibrateJoystick(strength=1.0, direction=0.0):\n+            strengthLeft  = 0\n+            strengthRight = 0\n+            for layer in vibration_layers:\n+                data = vibration_layers[layer]\n+                if data.get(\"started\", 0) + data.get(\"time\", 0.5) <  bge.logic.getRealTime():\n+                    data[\"left\"]  = 0\n+                    data[\"right\"] = 0\n+                strengthLeft  += data.get(\"left\" )\n+                strengthRight += data.get(\"right\")\n+            stick.strengthLeft  = strengthLeft\n+            stick.strengthRight = strengthRight\n+            stick.startVibration()\n+vibration_layers = {}\n+def VibrateJoystick(strength=1.0, direction=0.0, time=0.5, layer=0):\n     strength = min(1, strength)\n-    bge.logic.globalDict[\"joystickVibrationSince\"] = bge.logic.getRealTime()\n     joysticks = bge.logic.joysticks\n     for stick in joysticks:\n         if stick:\n-            stick.startVibration()\n             ld = max(0.0, min(1.0, 1-direction))\n             rd = max(0.0, min(1.0, 1+direction))\n",
                        "comment": "Moved the starting of the vibration from the VibrateJoystick() funtion to the Loop instead. And added new variables like `time` ( that controls how long the vibration should be ) and `layer` so I could layer more than one vibration on top of each other."
                    },
                    {
                        "diff": "@@ -86,8 +98,14 @@\n             l = max(0.0, min(1.0, strength))\n             r = max(0.0, min(1.0, strength))\n-            stick.strengthLeft = numpy.random.choice((ld, 0), p=(l, 1-l))\n-            stick.strengthRight = numpy.random.choice((rd, 0), p=(r, 1-r))\n+            strengthLeft = numpy.random.choice((ld, 0), p=(l, 1-l))\n+            strengthRight = numpy.random.choice((rd, 0), p=(r, 1-r))\n+            layer_data = {\"left\":strengthLeft,\n+                          \"right\":strengthRight,\n+                          \"started\":bge.logic.getRealTime(),\n+                          \"time\":time}\n+            vibration_layers[layer] = layer_data\n",
                        "comment": "Instead of applying the vibration directly, not it writes data about the \"layer\" for the loop to deal with."
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -3931,8 +3931,6 @@\n         # Have enough performace.\n         # Have enough variety.\n-    print(\"SpawnLogic\")\n     settings = bge.logic.globalDict[\"settings\"]\n",
                        "comment": "Removed annoying print from Vehicle Spawn system."
                    },
                    {
                        "diff": "@@ -4032,13 +4030,13 @@\n     # Model of the car to spawn.\n     carModel = str(numpy.random.choice(NPC_cars, p=NPC_cars_probability))\n-    print(\"original choice\", carModel)\n     if spawnedCars >= maxCars:\n         danisCar = str(dani.get(\"driving\"))\n         allCars = str(bge.logic.globalDict[\"allcars\"])\n         while not carModel in allCars or ( carModel == danisCar and allCars.count(danisCar) < 2 ):\n             carModel = str(numpy.random.choice(NPC_cars, p=NPC_cars_probability))\n-    print(\"final choice\", carModel)\n     for n, spawn in enumerate(spawnSorted):\n",
                        "comment": "More annoying prints from the same place."
                    },
                    {
                        "diff": "@@ -6848,7 +6846,10 @@\n     sound[\"play\"].distance_maximum = 200\n     sound[\"play\"].distance_reference = 1\n     sound[\"play\"].attenuation = 1\n-    sound[\"play\"].volume = 3\n+    sound[\"play\"].volume = 5\n+    if car.get(\"active\"):\n+        Input.VibrateJoystick(time=0.2, layer=\"GearShift\")\n def DriftSound(car):\n",
                        "comment": "Added more volume to the shifter and added the Vibration of the stick ( as you can see, using the new variables )."
                    }
                ]
            },
            "text": "Vibration on gear-shift"
        },
        "1784283455": {
            "comment": "There seemed like a need for a street-car race near the green-house. So I made one.",
            "added": [
                "/races/raceline_Green_House_Race.json",
                "/races/Green_House_Race.json"
            ],
            "changed": [
                "//assembly.blend"
            ],
            "changed_diffs": {
                "//assembly.blend": []
            },
            "text": "Added Green-House Race"
        },
        "1784284855": {
            "comment": "Now you can start races in the multipler using the phone app.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Racing.py",
                "/Scripts/Phone.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Racing.py": [
                    {
                        "diff": "@@ -327,7 +327,8 @@\n         # Beam of energy\n         racer[\"beam\"] = Reuse.Create(\"Racer.Indicator\")\n-        Vehicle.ResqueRacer(racer, do_now=True)\n+        if not settings.get(\"multiplayer\"):\n+            Vehicle.ResqueRacer(racer, do_now=True)\n     if not race.get(\"amount-racers\", 1):\n",
                        "comment": "Added an if statement, not to do this for multiplayer, since we are not playing against bots here."
                    }
                ],
                "/Scripts/Phone.py": [
                    {
                        "diff": "@@ -1212,6 +1212,8 @@\n     dani = scene.objects[\"Dani_Box\"]\n     cam = scene.active_camera\n+    settings = bge.logic.globalDict[\"settings\"]\n     # Phone\n     phone = scene.objects[\"Phone\"]\n",
                        "comment": "Added a way to read settings in the race app on the phone."
                    },
                    {
                        "diff": "@@ -1253,6 +1255,33 @@\n              size=0.3,\n              execute=OpenMapApp)\n+    # If dani is in multiplayer\n+    elif settings.get(\"multiplayer\"):\n+        Box(\"Racingbox1\",\n+            position=(0.0,0.0),\n+            size=(1.5,1.8))\n+        Text(\"Racing_Multiplayer\",\n+             \"Race will start to all\\nplayers in the circle.\",\n+             position=(0.0,0.1),\n+             size=0.15)\n+        def StartRace():\n+            Racing.StartRace(race[\"racename\"], dani)\n+            State[\"app\"] = MenuApp\n+            Hide()\n+        Icon(\"RacingApp_Start\",\n+             \"okay\",\n+             position=(0,-0.4),\n+             size=0.3,\n+             execute=StartRace)\n     # If dani has wrong car type\n     elif not Racing.CanStartRace(race, dani):\n",
                        "comment": "Added a special window in the raceapp for multiplayer with simple instructions and a start button."
                    }
                ]
            },
            "text": "Starting Races in Multiplayer"
        },
        "1784290827": {
            "comment": "Added another hidden outfit",
            "added": [
                "/textures/Dani_Daniel.png"
            ],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Outfits.py",
                "/Scripts/Input.py",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/Scripts/Outfits.py": [
                    {
                        "diff": "@@ -80,6 +80,10 @@\n     \"Dani_Travis\": {\n         \"name\":\"Taxi Driver\",\n         \"default\":False\n+    },\n+    \"Dani_Daniel\": {\n+        \"name\":\"Daniel\",\n+        \"default\":False\n     }\n",
                        "comment": "Adding the data about the outfit."
                    }
                ],
                "/Scripts/Input.py": [
                    {
                        "diff": "@@ -195,7 +195,8 @@\n             \"OUTFITMETAL\"  :\"Dani_METAL\",\n             \"OUTFITPUNK\"   :\"Dani_Punk\",\n             \"OUTFITOZONED\" :\"Dani_Ozoned\",\n-            \"OUTPUTRAVIS\"  :\"Dani_Travis\"\n+            \"OUTFITRAVIS\"  :\"Dani_Travis\",\n+            \"OUTFITDANIEL\" :\"Dani_Daniel\"\n         }\n         for i in outfits:\n",
                        "comment": "Making a cheatcode for it ( also fixing the travis cheatcode )"
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -1262,7 +1262,16 @@\n             if data.get(\"rocketLauncher\") and data.get(\"usemodel\") == obj.name:\n                 return True\n+def IsTuned(car):\n+    # Outputs whether the car has any tuning done to is\n+    attachments = car.get(\"Attachments\", [])\n+    nitro       = car.get(\"NitroCan\")\n+    spoiler     =  car.get(\"Spoiler\")\n+    return any((attachments, nitro, spoiler))\n def ReduceNitro(car, amount):\n     carD       = Opt.FastDict(car)\n",
                        "comment": "Adding a function that checks whether you did any improvements to your car."
                    },
                    {
                        "diff": "@@ -6713,6 +6722,10 @@\n                     Time = bge.logic.globalDict[\"time\"]\n                     if Time > 21 or Time < 6:\n                         Outfits.Unlock_Hidden(\"Dani_Travis\")\n+                    # If you have a tuned car, you get Daniel outfit.\n+                    if IsTuned(car):\n+                        Outfits.Unlock_Hidden(\"Dani_Daniel\")\n                 else:\n                     UI.Print(\"You got $\"+str(int(carD[\"taxi_reward\"])), important=True)\n",
                        "comment": "If you successfully delivered a person ( as a taxi ) and have a tuned taxi, you get the daniel outfit."
                    }
                ]
            },
            "text": "Hidden Outfit Daniel"
        },
        "1784291964": {
            "comment": "Sorry forgot the icon",
            "added": [
                "/SettingUI/icons/Dani_Daniel.png"
            ],
            "changed": [
                "//grabbed.txt"
            ],
            "changed_diffs": {
                "//grabbed.txt": []
            },
            "text": "Icon Outfit Daniel"
        },
        "1784313684": {
            "comment": "Today I forget the IP and Port of the main server for the multiplayer. So I decided to implement a history so servers will be storred.",
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt"
            ],
            "changed_diffs": {
                "//run.py": [
                    {
                        "diff": "@@ -318,6 +318,14 @@\n                             data[\"mp-host\"] = ipport.get_text()\n                             data[\"mp-name\"] = username.get_text()\n                             data[\"mp-room\"] = roomname\n+                            # Storring the history of hosts.\n+                            if \"mp-hosts\" not in data:\n+                                data[\"mp-hosts\"] = [\"51.83.238.186:4445\"]\n+                            if data[\"mp-host\"] not in data[\"mp-hosts\"]:\n+                                data[\"mp-hosts\"].append(data[\"mp-host\"])\n                             save_settings(data)\n                             multiplayerWindow.destroy()\n",
                        "comment": "When you click Join it will not just assign the server as mp-host but also append it to the list of mp-hosts ( plural )"
                    },
                    {
                        "diff": "@@ -392,6 +400,34 @@\n     ipbox.pack_end(ip, 0,5,5)\n     setbox.pack_start(ipbox, 0,5,5)\n+    # Known servers\n+    scrl = Gtk.ScrolledWindow()\n+    setbox.pack_start(scrl, 1,1,0)\n+    history_box = Gtk.VBox()\n+    scrl.add(history_box)\n+    serverbuttons = {}\n+    for server in data.get(\"mp-hosts\", []):\n+        def on_server_button(w, server):\n+            ip.set_text(server)\n+        server_button = Gtk.Button(server)\n+        server_button.connect(\"clicked\", on_server_button, server)\n+        history_box.pack_start(server_button, 0,5,5)\n+        serverbuttons[server] = server_button\n+    def on_changed_ip(w):\n+        server = ip.get_text()\n+        for server_button_name in serverbuttons:\n+            server_button = serverbuttons[server_button_name]\n+            if server_button_name == server:\n+                server_button.set_visible(False)\n+            else:\n+                server_button.set_visible(True)\n+    ip.connect(\"changed\", on_changed_ip)\n     # Host Mulitiplayer\n     hostButton = Gtk.LinkButton(\n",
                        "comment": "UI of retrieving this list in a meaningful way. Notice the on_changed_ip() function. It makes it so servers inputed into the input entry do not show up in the list."
                    },
                    {
                        "diff": "@@ -436,6 +472,7 @@\n     box2.pack_end(addbox, 0,5,5)\n     main_box.show_all()\n+    on_changed_ip(True)\n     ### Starting the updater thread\n     t = threading.Thread(target=fetchThread, args=(ip,widgets,gamesBox,))\n",
                        "comment": "I have to run this function once after I set everything in the window as visible. "
                    }
                ],
                "//grabbed.txt": []
            },
            "text": "Added server history"
        },
        "1784314185": {
            "comment": "If Dani would jump while the car has smoke trails, those would get stuck on the car, and then when it respawns you would see a random NPC with smoketrails.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -3230,6 +3230,16 @@\n     # to simulate the look of drift smoke\n     if not (car.get(\"active\")):# or Opt.GoodFPS(\"Car Drift Smoke\")):\n+        # Removing the smoke\n+        for n, wheel in enumerate(car[\"specs\"][\"wheels\"]):\n+            wheelObject = car[\"wheels\"][n]\n+            if wheelObject.get(\"Drift_Smoke\"):\n+                smoke = wheelObject.get(\"Drift_Smoke\")\n+                smoke.removeParent()\n+                Reuse.Delete(smoke)\n+                wheelObject[\"Drift_Smoke\"] = None\n         return\n     dirt = False\n",
                        "comment": "Added a simple loop to check fo them and get rid of them on non-active cars."
                    }
                ]
            },
            "text": "Removed smoke trails from cars"
        },
        "1784330879": {
            "comment": "AH",
            "added": [
                "/textures/colorwheel.png"
            ],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Garage.py",
                "/Scripts/Multiplayer/client.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -4,6 +4,7 @@\n # This will deal with garage and inventory system.\n import bge\n+import bpy\n import random\n import mathutils\n",
                        "comment": "This is unrelated"
                    },
                    {
                        "diff": "@@ -324,8 +325,6 @@\n     computer           = scene.objects[\"Computer\"]    \n     if computer.get(\"timer\"): computer[\"timer\"] -= 1\n-    if str(dani.get(\"tool\")) != \"PowerWrench\" or dani.get(\"tool-attachment\"):\n-        return\n     computerIcon       = scene.objects[\"ComputerIcon\"]\n     computerIconTop    = scene.objects[\"ComputerIcon.Top\"]\n",
                        "comment": "I will look into it soon"
                    },
                    {
                        "diff": "@@ -334,6 +333,38 @@\n     computerItemHave   = scene.objects[\"Garage_Computer_Text.Have\"]\n     computerItemPrice  = scene.objects[\"Garage_Computer_Text.Price\"]\n+    computer_ui = [computerIcon,\n+                   computerIconTop,\n+                   computerIconBottom,\n+                   computerItemName,\n+                   computerItemHave,\n+                   computerItemPrice]\n+    computerPaint = scene.objects[\"Computer_Paint\"]\n+    paint_ui = [computerPaint]\n+    def show_paint():\n+        for i in paint_ui:\n+            if not i.visible: i.visible = True\n+    def hide_paint():\n+        for i in paint_ui:\n+            if i.visible: i.visible = False\n+    def show_fix():\n+        for i in computer_ui:\n+            if not i.visible: i.visible = True\n+    def hide_fix():\n+        for i in computer_ui:\n+            if i.visible: i.visible = False\n+    if str(dani.get(\"tool\")) not in (\"PowerWrench\", \"PaintTool\") or dani.get(\"tool-attachment\"):\n+        hide_fix()\n+        hide_paint()\n+        return\n     keys = bge.logic.globalDict[\"keys\"]\n     joystickButtons = bge.logic.globalDict.get(\"joystickButtons\", [])\n",
                        "comment": "I'm trying to make a way to select specific color for coloring tool, it doesn't work."
                    },
                    {
                        "diff": "@@ -341,87 +372,137 @@\n         bge.logic.globalDict[\"near_computer\"] = False\n     if dani.getDistanceTo(computer) > 3:\n+        hide_fix()\n+        hide_paint()\n         bge.logic.globalDict[\"near_computer\"] = False\n         return\n     else:\n         bge.logic.globalDict[\"near_computer\"] = True\n-        # Updating the icons\n-        # You need to trigger the depsgraph on them for them\n-        # to get the material updated. So we do a dummy operation.\n-        Hints.Show(\"garage computer\",\n-                   \"[Parts eShop]\\n[Up], [Down] to choose.\\n[Enter] to buy.\",\n-                   (-756.137,\n-                    -1048.46,\n-                    407.162))\n-        computerIcon.applyRotation((0,0,0))\n-        computerIconTop.applyRotation((0,0,0))\n-        computerIconBottom.applyRotation((0,0,0))\n+        if str(dani.get(\"tool\")) == \"PowerWrench\":\n+            show_fix()\n+            hide_paint()\n-        for n, name in enumerate(shop):\n-            item = shop[name]\n-            have = inventory.get(name, 0)\n-            if computer.get(\"selection\",0) == n:\n-                printname = item.get(\"name\", name)\n-                computerItemName[\"Text\"] = printname\n-                have = \"have \"+str(int(inventory.get(name, 0)))\n-                computerItemHave[\"Text\"] = have\n-                price = \"$\"+str(item.get(\"cost\", 0))\n-                computerItemPrice[\"Text\"] = price\n+            # Updating the icons\n+            # You need to trigger the depsgraph on them for them\n+            # to get the material updated. So we do a dummy operation.\n+            Hints.Show(\"garage computer\",\n+                       \"[Parts eShop]\\n[Up], [Down] to choose.\\n[Enter] to buy.\",\n+                       (-756.137,\n+                        -1048.46,\n+                        407.162))\n+            computerIcon.applyRotation((0,0,0))\n+            computerIconTop.applyRotation((0,0,0))\n+            computerIconBottom.applyRotation((0,0,0))\n+            for n, name in enumerate(shop):\n+                item = shop[name]\n+                have = inventory.get(name, 0)\n+                if computer.get(\"selection\",0) == n:\n+                    printname = item.get(\"name\", name)\n+                    computerItemName[\"Text\"] = printname\n+                    have = \"have \"+str(int(inventory.get(name, 0)))\n+                    computerItemHave[\"Text\"] = have\n+                    price = \"$\"+str(item.get(\"cost\", 0))\n+                    computerItemPrice[\"Text\"] = price\n+                    icon      = item.get(\"icon\", [16,16])\n+                    computerIcon.blenderObject[\"raw\"]    = icon[0]\n+                    computerIcon.blenderObject[\"column\"] = icon[1]\n+                elif computer.get(\"selection\",0) + 1 ==  n:\n+                    icon      = item.get(\"icon\", [16,16])\n+                    computerIconBottom.blenderObject[\"raw\"]    = icon[0]\n+                    computerIconBottom.blenderObject[\"column\"] = icon[1]\n+                elif computer.get(\"selection\",0) + 1 ==  len(shop):\n+                    icon      = [15,15]\n+                    computerIconBottom.blenderObject[\"raw\"]    = icon[0]\n+                    computerIconBottom.blenderObject[\"column\"] = icon[1]\n+                elif computer.get(\"selection\",0) - 1 == n:\n+                    icon      = item.get(\"icon\", [16,16])\n+                    computerIconTop.blenderObject[\"raw\"]    = icon[0]\n+                    computerIconTop.blenderObject[\"column\"] = icon[1]\n+                elif computer.get(\"selection\",0) == 0:\n+                    icon      = [15,15]\n+                    computerIconTop.blenderObject[\"raw\"]    = icon[0]\n+                    computerIconTop.blenderObject[\"column\"] = icon[1]\n+            if ( keycodes[\"UpArrow\"] in keys or joystickcodes[\"Up\"] in joystickButtons ) and not computer.get(\"timer\"):\n+                computer[\"selection\"] = max(computer.get(\"selection\",0) - 1, 0)\n+                computer[\"timer\"] = 5\n+            elif ( keycodes[\"DownArrow\"] in keys or joystickcodes[\"Down\"] in joystickButtons ) and not computer.get(\"timer\"):\n+                computer[\"selection\"] = min(computer.get(\"selection\",0) + 1, len(shop)-1)\n+                computer[\"timer\"] = 5\n+            elif ( keycodes[\"Enter\"] in keys or joystickcodes[\"A_><\"] in joystickButtons ) and not computer.get(\"timer\"):\n+                Buy(list(shop.keys())[computer.get(\"selection\",0)])\n+                computer[\"timer\"] = 5\n+                return\n+        elif str(dani.get(\"tool\")) == \"PaintTool\":\n+            show_paint()\n+            hide_fix()\n+            camera     = scene.active_camera\n+            camrot     = camera.orientation.to_euler()\n+            MainColor      = mathutils.Color(computerPaint.blenderObject.get(\"MainColor\",      [1,0,0]))\n+            SecondaryColor = mathutils.Color(computerPaint.blenderObject.get(\"SecondaryColor\", [1,1,0]))\n+            print(SecondaryColor)\n+            mouse = bge.logic.globalDict[\"mouse\"]\n+            joystickButtons = bge.logic.globalDict.get(\"joystickButtons\", [])\n+            if mousecodes[\"RMB\"] in mouse or joystickcodes[\"Y_/\\\\\"] in joystickButtons:\n+                if \"secondaryCam\" not in computerPaint:\n+                    computerPaint[\"secondaryCam\"] = mathutils.Vector(camrot)\n+                    computerPaint[\"secondary_color\"] = SecondaryColor\n+                rotdelta = computerPaint[\"secondaryCam\"] - mathutils.Vector(camrot)\n+                newcolor = computerPaint[\"secondary_color\"]\n+                newcolor.h += rotdelta.z\n+                newcolor.s += rotdelta.y\n+                computerPaint.blenderObject[\"SecondaryColor\"] = newcolor\n-                icon      = item.get(\"icon\", [16,16])\n-                computerIcon.blenderObject[\"raw\"]    = icon[0]\n-                computerIcon.blenderObject[\"column\"] = icon[1]\n+            elif \"secondaryCam\" in computerPaint:\n+                try:\n+                    del computerPaint[\"secondaryCam\"]\n+                    del computerPaint[\"secondary_color\"]\n+                except:\n+                    pass\n-            elif computer.get(\"selection\",0) + 1 ==  n:\n-                icon      = item.get(\"icon\", [16,16])\n-                computerIconBottom.blenderObject[\"raw\"]    = icon[0]\n-                computerIconBottom.blenderObject[\"column\"] = icon[1]\n-            elif computer.get(\"selection\",0) + 1 ==  len(shop):\n-                icon      = [15,15]\n-                computerIconBottom.blenderObject[\"raw\"]    = icon[0]\n-                computerIconBottom.blenderObject[\"column\"] = icon[1]\n-            elif computer.get(\"selection\",0) - 1 == n:\n-                icon      = item.get(\"icon\", [16,16])\n-                computerIconTop.blenderObject[\"raw\"]    = icon[0]\n-                computerIconTop.blenderObject[\"column\"] = icon[1]\n-            elif computer.get(\"selection\",0) == 0:\n-                icon      = [15,15]\n-                computerIconTop.blenderObject[\"raw\"]    = icon[0]\n-                computerIconTop.blenderObject[\"column\"] = icon[1]\n-        if ( keycodes[\"UpArrow\"] in keys or joystickcodes[\"Up\"] in joystickButtons ) and not computer.get(\"timer\"):\n-            computer[\"selection\"] = max(computer.get(\"selection\",0) - 1, 0)\n-            computer[\"timer\"] = 5\n-        elif ( keycodes[\"DownArrow\"] in keys or joystickcodes[\"Down\"] in joystickButtons ) and not computer.get(\"timer\"):\n-            computer[\"selection\"] = min(computer.get(\"selection\",0) + 1, len(shop)-1)\n-            computer[\"timer\"] = 5\n-        elif ( keycodes[\"Enter\"] in keys or joystickcodes[\"A_><\"] in joystickButtons ) and not computer.get(\"timer\"):\n-            Buy(list(shop.keys())[computer.get(\"selection\",0)])\n-            computer[\"timer\"] = 5\n-            return\n def Buy(name):\n",
                        "comment": "Dunno, too much changes."
                    }
                ],
                "/Scripts/Multiplayer/client.py": [
                    {
                        "diff": "@@ -166,7 +166,7 @@\n     while True:\n         try:\n-            if queue[\"send\"] and not queue[\"recv\"]:\n+            if queue[\"send\"]:# and not queue[\"recv\"]:\n                 queue[\"tick\"] = queue.get(\"prev\", time.time())\n                 queue[\"time\"] = time.time()\n",
                        "comment": "THIS IS THE THING."
                    }
                ]
            },
            "text": "Testing mulitplayer line of code shananigans"
        },
        "1784332812": {
            "comment": "Wrong code",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Multiplayer/client.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Multiplayer/client.py": [
                    {
                        "diff": "@@ -166,7 +166,7 @@\n     while True:\n         try:\n-            if queue[\"send\"]:# and not queue[\"recv\"]:\n+            if queue[\"send\"] and not queue[\"recv\"]:\n                 queue[\"tick\"] = queue.get(\"prev\", time.time())\n                 queue[\"time\"] = time.time()\n",
                        "comment": "Reverting it back"
                    }
                ]
            },
            "text": "No not that."
        },
        "1784396093": {
            "comment": "I could not figure out what causes the timeouts on the main server. So I patched it by making it try sending a message multiple times.",
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt",
                "/Scripts/Multiplayer/client.py"
            ],
            "changed_diffs": {
                "//run.py": [
                    {
                        "diff": "@@ -11,6 +11,7 @@\n import getpass\n import datetime\n import threading\n+import traceback\n import gi\n gi.require_version('Gtk', '3.0')\n from gi.repository import Gtk\n",
                        "comment": "I used traceback to try to diagnose the issue."
                    },
                    {
                        "diff": "@@ -276,6 +277,8 @@\n                 connection = True\n             except Exception as e:\n                 print(\"Multiplayer Connection Error:\", e)\n+                traceback.print_exception(e)\n                 games = {}\n                 connection = False\n",
                        "comment": "Instead of just printing out the name of the expection, I printed the full traceback of it."
                    }
                ],
                "//grabbed.txt": [],
                "/Scripts/Multiplayer/client.py": [
                    {
                        "diff": "@@ -34,7 +34,7 @@\n     else:\n         return ipport, 7860\n-def connect(ip, port, timeout=5):\n+def connect(ip, port, timeout=10):\n     if not socks.get(ip+\":\"+str(port)):\n         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
                        "comment": "Tried touching the timeout value, didn't change nothing."
                    },
                    {
                        "diff": "@@ -59,12 +59,26 @@\n     s, ID = connect(ip, port, timeout=2)\n     return s\n-def send(s, data):\n+def send(s, data, repeat=10, fail_wait=0.1):\n     d = handler.encode(data)\n-    handler.send(s, d)\n-    r = handler.recv(s)\n+    for TRY in range(repeat):\n+        try:\n+            handler.send(s, d)\n+            break\n+        except:\n+            time.sleep(fail_wait)\n+    for TRY in range(repeat):\n+        try:\n+            r = handler.recv(s)\n+            break\n+        except:\n+            time.sleep(fail_wait)\n     d = handler.decode(r)\n     return d\n def fetchGames(ipport):\n",
                        "comment": "Ended up doing this monstrocity of try and except calls to try to send the badly sending message up to 10 times with some time in between. Works somewhat. But still the server seems to be very unstable."
                    }
                ]
            },
            "text": "Made timeouts less rare. Still doesn't help."
        },
        "1784400632": {
            "comment": "I am not sure is anything is change on the client side.",
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt"
            ],
            "changed_diffs": {
                "//run.py": [],
                "//grabbed.txt": []
            },
            "text": "Is there anything?"
        },
        "1784400705": {
            "comment": "Checking if anything is changed.",
            "added": [],
            "changed": [
                "//run.py"
            ],
            "changed_diffs": {
                "//run.py": []
            },
            "text": "Is there anything?"
        },
        "1784415283": {
            "comment": "Made it so can manually select colors for your cars, instead of relying on the random selector.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/textures/colorwheel.png",
                "/Scripts/Garage.py",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/textures/colorwheel.png": [],
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -5,6 +5,8 @@\n import bge\n import bpy\n+import math\n+import numpy\n import random\n import mathutils\n",
                        "comment": "At one point I tried to do a lot of trigonometry for a fancier editor."
                    },
                    {
                        "diff": "@@ -466,33 +468,67 @@\n             show_paint()\n             hide_fix()\n-            camera     = scene.active_camera\n+            camera     = scene.objects[\"DaniCam_Parent\"]\n             camrot     = camera.orientation.to_euler()\n-            MainColor      = mathutils.Color(computerPaint.blenderObject.get(\"MainColor\",      [1,0,0]))\n-            SecondaryColor = mathutils.Color(computerPaint.blenderObject.get(\"SecondaryColor\", [1,1,0]))\n-            print(SecondaryColor)\n+            # I tried using the same exact system as with anything else.\n+            # but it simply didn't work. TODO: figure out why!?!?!\n+            # MainColor      = mathutils.Color(computerPaint.blenderObject.get(\"MainColor\",      [1,0,0]))\n+            # SecondaryColor = mathutils.Color(computerPaint.blenderObject.get(\"S\", [1,1,0]))\n             mouse = bge.logic.globalDict[\"mouse\"]\n             joystickButtons = bge.logic.globalDict.get(\"joystickButtons\", [])\n+            currentColor = \"\"\n             if mousecodes[\"RMB\"] in mouse or joystickcodes[\"Y_/\\\\\"] in joystickButtons:\n-                if \"secondaryCam\" not in computerPaint:\n-                    computerPaint[\"secondaryCam\"] = mathutils.Vector(camrot)\n-                    computerPaint[\"secondary_color\"] = SecondaryColor\n-                rotdelta = computerPaint[\"secondaryCam\"] - mathutils.Vector(camrot)\n-                newcolor = computerPaint[\"secondary_color\"]\n-                newcolor.h += rotdelta.z\n-                newcolor.s += rotdelta.y\n-                computerPaint.blenderObject[\"SecondaryColor\"] = newcolor\n-            elif \"secondaryCam\" in computerPaint:\n+                currentColor = \"SecondaryColor\"\n+            elif mousecodes[\"LMB\"] in mouse or joystickcodes[\"A_><\"] in joystickButtons:\n+                currentColor = \"MainColor\"\n+            if currentColor:\n+                camrot = mathutils.Vector(camera.orientation.to_euler())\n+                prevrot = computerPaint.get(\"prevrot\", camrot)\n+                change = camrot - prevrot\n+                # normal = change.normalized()\n+                # distance = math.dist(camrot, prevrot)\n+                # if distance < 0.01:\n+                #     return\n+                color = mathutils.Color(computerPaint.get(currentColor, [1,0,0]))\n+                color.h += change.z\n+                color.s = min(1,max(0, color.s + change.x))\n+                if ( keycodes[\"UpArrow\"] in keys or joystickcodes[\"Up\"] in joystickButtons ) and not computer.get(\"timer\"):\n+                    color.v += 0.1\n+                elif ( keycodes[\"DownArrow\"] in keys or joystickcodes[\"Down\"] in joystickButtons ) and not computer.get(\"timer\"):\n+                    color.v -= 0.1\n+                # color.s = 1\n+                # normal2D = mathutils.Vector([normal.y,normal.z])\n+                # angle = normal2D.angle( mathutils.Vector([1,0]), 0 )\n+                # color.h = angle\n+                computerPaint[currentColor] = color.copy()                \n+                color = list(color)\n+                color.append(1)\n+                bpy.data.materials[currentColor].node_tree.nodes[\"Emission\"].inputs[0].default_value = color\n+                computerPaint[\"prevrot\"] =  camrot\n+            elif \"prevrot\" in computerPaint:\n                 try:\n-                    del computerPaint[\"secondaryCam\"]\n-                    del computerPaint[\"secondary_color\"]\n+                    del computerPaint[\"prevrot\"]\n                 except:\n                     pass\n",
                        "comment": "Editor in question. Notice that I opted to directly change the values in a material instead of dealing with custom properties. Because those bastards still don't work. While they work everywhere else. What? Yes. What?!?!"
                    }
                ],
                "/Scripts/Tools.py": [
                    {
                        "diff": "@@ -707,6 +707,8 @@\n     hand  = scene.objects[\"Tool_Hand\"]\n     hc    = scene.objects[\"Health_Circle\"]\n+    computerPaint = scene.objects[\"Computer_Paint\"]\n     joystickButtons = bge.logic.globalDict.get(\"joystickButtons\", [])\n     box = scene.objects[\"Boxify\"]\n",
                        "comment": "Adding the computerPaint object ( with the color data ) to the paint tool itself"
                    },
                    {
                        "diff": "@@ -733,7 +735,15 @@\n             if not tool.get(\"active-timer\"):\n                 Destruction.SmokeBurst(ray[1], 1, 5)\n-                Vehicle.SmartColor(car, \"pallete\")\n+                found = False\n+                for color in [\"MainColor\", \"SecondaryColor\"]:\n+                    value = computerPaint.get(color)\n+                    if value:\n+                        Vehicle.Material(car, value, color)\n+                        found = True\n+                if not found:\n+                    Vehicle.SmartColor(car, \"pallete\")\n                 tool[\"active-timer\"] = 30\n         elif mousecodes[\"RMB\"] in mouse  or joystickcodes[\"Y_/\\\\\"] in joystickButtons:\n",
                        "comment": "Making it use the colors from the computer if they are select. If not it will do the good old random stuff."
                    }
                ]
            },
            "text": "Color Picker"
        },
        "1784451143": {
            "comment": "Now you can color pieces of the car separately. By coloring those pieces when they are detached.",
            "added": [],
            "changed": [
                "/Scripts/Garage.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -467,6 +467,13 @@\n         elif str(dani.get(\"tool\")) == \"PaintTool\":\n             show_paint()\n             hide_fix()\n+            Hints.Show(\"garage computer paint\",\n+                       \"[Color Mixer]\\n[LMB] for primary, [RMB] for neon.\\n[Move Mouse] for Hue and Saturation\\n[Up] and [Down] for Value.\",\n+                       (-756.137,\n+                        -1048.46,\n+                        407.162))\n             camera     = scene.objects[\"DaniCam_Parent\"]\n             camrot     = camera.orientation.to_euler()\n",
                        "comment": "A hint of how the color picker works."
                    },
                    {
                        "diff": "@@ -567,7 +574,10 @@\n             # UpdateShelfs()\n             dani[\"tool-attachment\"] = name\n             dani[\"tool-attachment-model\"] = Reuse.Create(usemodel)\n+            colors = Vehicle.SmartColor(dani[\"tool-attachment-model\"], \"pallete\", just_return=True)\n+            dani[\"tool-attachment-model\"][\"colors\"] = colors\n+            Vehicle.ColorPart(dani[\"tool-attachment-model\"], dani[\"tool-attachment-model\"])\n         else:\n",
                        "comment": "Color purchased items into random color, so quick fixes would have wrong color on parts, like in the real life."
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -1217,9 +1217,10 @@\n     attachment[\"health\"] = health\n     attachment.setParent(car)\n-    ColorPart(car, attachment)\n+    #ColorPart(car, attachment)\n     car[\"Attachments\"].append(attachment)\n+    return attachment\n def Detach(car, usemodel):\n",
                        "comment": "Do not color attachments to the car's color, so you could color attachments separately."
                    },
                    {
                        "diff": "@@ -1388,9 +1389,10 @@\n     spoiler.worldOrientation = spoilerproxy.worldOrientation\n     spoiler.scaling = spoilerproxy.scaling\n     spoiler.setParent(spoilerproxy)\n-    ColorPart(car, spoiler)\n+    #ColorPart(car, spoiler)\n     car[\"Spoiler\"] = spoilertype\n     car[\"SpoilerObject\"] = spoiler\n+    return spoiler\n def RemoveSpoiler(car):\n",
                        "comment": "Same with spoilers"
                    },
                    {
                        "diff": "@@ -3016,6 +3018,7 @@\n     # Getting objects\n     for obj in car.childrenRecursive:\n+        obj[\"colors\"] = car[\"colors\"]\n         ColorPart(car, obj)\n     for wheel in car.get(\"wheels\", []):\n",
                        "comment": "When coloring the whole car at once record the color of each part, so it could be encoded."
                    },
                    {
                        "diff": "@@ -3038,7 +3041,7 @@\n             light.blenderObject.data.color = value\n             light.blenderObject.data.use_shadow = False\n-def SmartColor(car, color=None):\n+def SmartColor(car, color=None, just_return=False):\n     # Coloring the car. This is not easy\n     # since we have multiple possible attributes.\n",
                        "comment": "Added just_return value to smart color, so I could generate a good looking pallete color and only have the color data."
                    },
                    {
                        "diff": "@@ -3126,6 +3129,9 @@\n                 secondcol.h = maincol.h\n         color = {\"MainColor\":maincol, \"SecondaryColor\":secondcol}\n+        if just_return:\n+            return color\n         for attribute in color:\n             value = color[attribute]\n",
                        "comment": "This is return of the just_return"
                    },
                    {
                        "diff": "@@ -6473,8 +6479,9 @@\n     Material(car, (0.1,0.6,1), \"SecondaryColor\")\n     for door in car.get(\"doors\"):\n-        door.blenderObject[\"MainColor\"] = (1,1,1)\n-        door.blenderObject[\"SecondaryColor\"] = (1,0.09,0)\n+        colors = {\"MainColor\":[1,1,1], \"SecondaryColor\":[1,0.09,0]}\n+        door[\"colors\"] = colors\n+        ColorPart(door, door)\n     car[\"police\"] = True\n     if car not in bge.logic.globalDict[\"policeCars\"]:\n",
                        "comment": "For police, made it so the white doors are done in the same fashion as coloring individual parts in garage."
                    },
                    {
                        "diff": "@@ -7350,14 +7357,28 @@\n     cardata[\"NitroCan\"]       = car.get(\"NitroCan\" , False)\n     cardata[\"blown\"]          = car.get(\"blown\"  , False)\n     cardata[\"Spoiler\"]        = car.get(\"Spoiler\", False)\n+    if car.get(\"Spoiler\", False):\n+        colors = car[\"SpoilerObject\"].get(\"colors\")\n+        if colors:\n+            for i in colors: colors[i] = list(colors[i])\n+            cardata[\"SpoilerColors\"] = colors\n     cardata[\"doors\"]          = []\n     for door in car.get(\"doors\",[]):\n         doordata = {\n             \"health\"  : door[\"health\"],\n             \"locked\"  : door[\"locked\"],\n             \"visible\" : door.visible\n         }\n+        colors = door.get(\"colors\")\n+        if colors:\n+            for i in colors: colors[i] = list(colors[i])\n+            doordata[\"colors\"] = colors\n         cardata[\"doors\"].append(doordata)\n",
                        "comment": "On Encode writing the color of individual parts colors into the JSON"
                    },
                    {
                        "diff": "@@ -7368,6 +7389,12 @@\n             \"orientation\":EncodeRotation(obj),\n             \"health\":obj.get(\"health\", 1)\n         }\n+        colors = obj.get(\"colors\")\n+        if colors:\n+            for i in colors: colors[i] = list(colors[i])\n+            objdata[\"colors\"] = colors\n         cardata[\"attachments\"].append(objdata)\n",
                        "comment": "same for more parts"
                    },
                    {
                        "diff": "@@ -7377,6 +7404,12 @@\n             \"health\"  : wheel[\"health\"],\n             \"visible\" : wheel.visible\n         }\n+        colors = wheel.get(\"colors\")\n+        if colors:\n+            for i in colors: colors[i] = list(colors[i])\n+            wheeldata[\"colors\"] = colors\n         cardata[\"wheels\"].append(wheeldata)\n     # Color data\n",
                        "comment": "and foe wheels ( some cars have colorable wheels, like neonspeedster )"
                    },
                    {
                        "diff": "@@ -7439,6 +7472,19 @@\n     if \"orientation\" in changed:\n         car.orientation = data.get(\"orientation\", (0,0,0))\n+    if \"police\" in changed or not changed:\n+        if data.get(\"police\") and not car.get(\"police\"):\n+            Policify(car)\n+    if \"taxi\" in changed or not changed:\n+        if data.get(\"taxi\") and not IsTaxi(car):\n+            Taxify(car)\n     if \"colors\" in changed or not changed:\n         for attribute in data.get(\"colors\", {}):\n             value = data[\"colors\"][attribute]\n",
                        "comment": "Moving the police and taxi Decoding before the color, so you could changed color of police and taxi cars."
                    },
                    {
                        "diff": "@@ -7490,11 +7536,25 @@\n         elif not car.get(\"Spoiler\") and Spoiler:\n             AddSpoiler(car, Spoiler)\n-    for objdata in data.get(\"attachments\", []):\n-        obj = Reuse.Create(objdata.get(\"name\", \"Intake1_Attach\"))\n-        obj.worldPosition = objdata.get(\"position\", [0,0,0])\n-        obj.orientation = objdata.get(\"orientation\", [0,0,0])\n-        Attach(car, obj, True, objdata.get(\"health\", 1))\n+    if \"SpoilerColors\" in changed or not changed:\n+        SpoilerObject = car.get(\"SpoilerObject\")\n+        if SpoilerObject:\n+            colors = data.get(\"SpoilerColors\")\n+            if colors:\n+                SpoilerObject[\"colors\"] = colors\n+                ColorPart(SpoilerObject, SpoilerObject)\n+    if \"attachments\" in changed or not changed:\n+        for objdata in data.get(\"attachments\", []):\n+            obj = Reuse.Create(objdata.get(\"name\", \"Intake1_Attach\"))\n+            obj.worldPosition = objdata.get(\"position\", [0,0,0])\n+            obj.orientation = objdata.get(\"orientation\", [0,0,0])\n+            Attach(car, obj, True, objdata.get(\"health\", 1))\n+            if objdata.get(\"colors\"):\n+                obj[\"colors\"] = objdata.get(\"colors\")\n+                ColorPart(obj, obj)\n     if \"blown\" in changed or not changed:\n",
                        "comment": "First, optimized attachments for multiplayer by making their updates only when they are changed. And then added the colors from the data, for them and the spoilers."
                    },
                    {
                        "diff": "@@ -7525,6 +7585,11 @@\n                     door.replaceMesh(door[\"Borked\"])\n                     door[\"mesh\"] = \"Borked\"\n+            if doordata.get(\"colors\"):\n+                door[\"colors\"] = doordata.get(\"colors\")\n+                ColorPart(door, door)\n     if \"wheels\" in changed or not changed:\n         for n, wheel in enumerate(car.get(\"wheels\", [])):\n",
                        "comment": "And the doors."
                    },
                    {
                        "diff": "@@ -7539,13 +7604,10 @@\n             wheel[\"health\"] = wheeldata.get(\"health\", 1.0)\n             wheel.visible   = wheeldata.get(\"visible\", True)\n-    if \"police\" in changed or not changed:\n-        if data.get(\"police\") and not car.get(\"police\"):\n-            Policify(car)\n-    if \"taxi\" in changed or not changed:\n-        if data.get(\"taxi\") and not IsTaxi(car):\n-            Taxify(car)\n+            if wheeldata.get(\"colors\"):\n+                wheel[\"colors\"] = wheeldata.get(\"colors\")\n+                ColorPart(wheel, wheel)\n",
                        "comment": "And the wheels ( also this is where police and taxi lived before )"
                    }
                ],
                "/Scripts/Tools.py": [
                    {
                        "diff": "@@ -441,7 +441,14 @@\n                         dani[\"tool-attachment\"] = None\n                     elif freepos:\n-                        Vehicle.Attach(car, usemodel)\n+                        c = Vehicle.Attach(car, usemodel)\n+                        reference_model = dani.get(\"tool-attachment-model\")\n+                        if reference_model:\n+                            colors = reference_model.get(\"colors\")\n+                            if colors:\n+                                c[\"colors\"] = colors\n+                                Vehicle.ColorPart(c, c)\n                         dani[\"tool-attachment\"] = None\n",
                        "comment": "When attaching the model, in garage, it will color the part into the color of the part you are holding ( those are 2 separate models )"
                    },
                    {
                        "diff": "@@ -454,7 +461,14 @@\n                     if str(c) == \"SpoilerProxy\" and attachment:\n                         spoilertype = Garage.shop.get(attachment, {}).get(\"usemodel\")\n-                        Vehicle.AddSpoiler(car, spoilertype)\n+                        c = Vehicle.AddSpoiler(car, spoilertype)\n+                        reference_model = dani.get(\"tool-attachment-model\")\n+                        if reference_model:\n+                            colors = reference_model.get(\"colors\")\n+                            if colors:\n+                                c[\"colors\"] = colors\n+                                Vehicle.ColorPart(c, c)\n                         dani[\"tool-attachment\"] = None\n                     cD[\"health\"] = cD.get(\"health\", 1.0) + 0.01\n",
                        "comment": "same with spoiler"
                    },
                    {
                        "diff": "@@ -489,6 +505,16 @@\n                     if cD[\"health\"] > 0.2:\n                         if not c.visible:\n+                            # Coloring the doors accordingly\n+                            reference_model = dani[\"tool-attachment-model\"]\n+                            if reference_model:\n+                                colors = reference_model.get(\"colors\")\n+                                if colors:\n+                                    c[\"colors\"] = colors\n+                                    Vehicle.ColorPart(c, c)\n                             dani[\"tool-attachment\"] = None    \n                             c.visible = True\n",
                        "comment": "same with doors"
                    },
                    {
                        "diff": "@@ -717,13 +743,24 @@\n     ray = DaniPoint(dani, camera)\n     tool = dani[\"tool\"]\n-    if ray[0] in bge.logic.globalDict[\"allcars\"]:\n-        car = ray[0]\n+    colorable = bge.logic.globalDict[\"allcars\"] + garageItems\n+    car = None\n+    dist = 3\n+    if ray[1]:\n+        for i in colorable:\n+            d = math.dist(i.position, ray[1])\n+            if d < dist:\n+                car = i\n+                dist = d\n+    if car:\n+        #car = ray[0]\n         Boxify(car)\n         Hints.Show(\"color tool\",\n-               \"[\"+car[\"specs\"].get(\"name\",str(car))+\"]\\n[LMB] to color.\\n[RMB] stock color.\",\n+               \"[\"+car.get(\"specs\", {}).get(\"name\",str(car))+\"]\\n[LMB] to color.\\n[RMB] stock color.\",\n                car)\n         if mousecodes[\"LMB\"] in mouse or joystickcodes[\"A_><\"] in joystickButtons:\n",
                        "comment": "Added items laying on the ground to the colorable objects. And changed the hint, so it would not error out from the items laying on the groun."
                    },
                    {
                        "diff": "@@ -737,13 +774,31 @@\n                 Destruction.SmokeBurst(ray[1], 1, 5)\n                 found = False\n+                colors = {}\n                 for color in [\"MainColor\", \"SecondaryColor\"]:\n                     value = computerPaint.get(color)\n                     if value:\n+                        colors[color] = value\n                         Vehicle.Material(car, value, color)\n                         found = True\n+                if found and not car.get(\"specs\"):\n+                    car[\"colors\"] = colors\n+                    if \"item\" in car:\n+                        for i in colors: colors[i] = list(colors[i])\n+                        car[\"item\"][\"colors\"] = list(colors)\n+                    Vehicle.ColorPart(car, car)\n                 if not found:\n-                    Vehicle.SmartColor(car, \"pallete\")\n+                    if car.get(\"specs\"):\n+                        Vehicle.SmartColor(car, \"pallete\")\n+                    else:\n+                        color = Vehicle.SmartColor(car, \"pallete\", just_return=True)\n+                        car[\"colors\"] = color\n+                        if \"item\" in car:\n+                            for i in color: color[i] = list(color[i])\n+                            car[\"item\"][\"colors\"] = color\n+                        Vehicle.ColorPart(car, car)\n                 tool[\"active-timer\"] = 30\n         elif mousecodes[\"RMB\"] in mouse  or joystickcodes[\"Y_/\\\\\"] in joystickButtons:\n",
                        "comment": "Changed coloring so it works both with the color picker and with the parts laying on the ground."
                    },
                    {
                        "diff": "@@ -940,8 +995,12 @@\n                 item[\"object\"].position = item.get(\"position\", (0,0,0))\n                 item[\"object\"].scaling = item.get(\"scaling\", (1,1,1))\n                 item[\"object\"].suspendPhysics(True)\n+                item[\"object\"][\"item\"] = item\n                 if item.get(\"colors\"):\n                     Vehicle.ColorPart(item, item[\"object\"])\n+                if item.get(\"garage\"):\n+                    garageItems.append(item[\"object\"])\n         if distance < 10:\n             item[\"object\"].applyRotation((0,0,0.1))\n",
                        "comment": "Add items laying on the ground to a list, that the coloring tool can use to see what can be colored."
                    },
                    {
                        "diff": "@@ -956,8 +1015,11 @@\n                 GarageItem(item, index, addr)\n         if distance > 20 and item.get(\"object\"):\n+            if item in garageItems:\n+                garageItem.remove(item[\"object\"])\n             Reuse.Delete(item[\"object\"])\n             item[\"object\"] = None\n     for a in items:\n         if a == addr:\n",
                        "comment": "And remove them from the list when they despawn"
                    },
                    {
                        "diff": "@@ -1004,6 +1066,8 @@\n itemFunctions[\"Money\"] = MoneyItem\n+garageItems = []\n def DropGarageItem():\n",
                        "comment": "adding said list."
                    }
                ]
            },
            "text": "Color Individual Parts"
        },
        "1784453068": {
            "comment": "There was a bug where small pieces dictated the look of the entire car. This is now seems to be fixed.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -3142,6 +3142,8 @@\n     # This function colors a specific part\n     # of the car, into the colors of the car.\n+    part[\"colors\"] = car[\"colors\"]\n     for attribute in car.get(\"colors\", []):\n         value = car[\"colors\"][attribute]\n         part.blenderObject[attribute] = value\n",
                        "comment": "Specifically made sure the color of a part is recorded at a part level."
                    }
                ],
                "/Scripts/Tools.py": [
                    {
                        "diff": "@@ -545,7 +545,7 @@\n                         dani[\"tool-attachment-model\"] = Reuse.Create(str(c))\n                         dani[\"tool-attachment-model\"].suspendPhysics()\n                         dani[\"tool-attachment-model\"].scaling = c.scaling.copy()\n-                        Vehicle.ColorPart(car, dani[\"tool-attachment-model\"])\n+                        Vehicle.ColorPart(c, dani[\"tool-attachment-model\"])\n                     # Removing wheels\n                     elif c in car[\"wheels\"] and not attachment:\n",
                        "comment": "Specifically made sure when detaching that the object you will get will recieve the color."
                    },
                    {
                        "diff": "@@ -555,12 +555,18 @@\n                         dani[\"tool-attachment-model\"] = Reuse.Create(str(c))\n                         dani[\"tool-attachment-model\"].suspendPhysics()\n                         dani[\"tool-attachment-model\"].scaling = c.scaling.copy()\n+                        Vehicle.ColorPart(c, dani[\"tool-attachment-model\"])\n                     elif c in car.get(\"Attachments\", []):\n                         for name in Garage.shop:\n                             item = Garage.shop[name]\n                             if item.get(\"usemodel\") == str(c):\n                                 dani[\"tool-attachment\"] = name\n+                                dani[\"tool-attachment-model\"] = Reuse.Create(str(c))\n+                                dani[\"tool-attachment-model\"].suspendPhysics()\n+                                dani[\"tool-attachment-model\"].scaling = c.scaling.copy()\n+                                Vehicle.ColorPart(c, dani[\"tool-attachment-model\"])\n                         Vehicle.Detach(car, c)\n",
                        "comment": "In more than one place."
                    }
                ]
            },
            "text": "Individual Colors Bug Fix"
        },
        "1784453824": {
            "comment": "When detaching spoilers their colors got all wrong. Fixed it.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Tools.py": [
                    {
                        "diff": "@@ -526,11 +526,19 @@\n                     # Removing spoilers\n                     if str(c) == \"SpoilerProxy\" and not attachment:\n-                        spoilertype = Vehicle.RemoveSpoiler(car)\n+                        spoilertype = car.get(\"Spoiler\", \"\")\n                         for name in Garage.shop:\n                             item = Garage.shop[name]\n                             if item.get(\"usemodel\") == spoilertype:\n                                 dani[\"tool-attachment\"] = name\n+                                c = car.get(\"SpoilerObject\")\n+                                dani[\"tool-attachment-model\"] = Reuse.Create(str(c))\n+                                dani[\"tool-attachment-model\"].suspendPhysics()\n+                                dani[\"tool-attachment-model\"].scaling = c.scaling.copy()\n+                                Vehicle.ColorPart(c, dani[\"tool-attachment-model\"])\n+                                Vehicle.RemoveSpoiler(car)\n                     # Removing nitros\n                     if str(c) == \"NitroCanProxy\" and not attachment:\n",
                        "comment": "Redone how the detachment is done."
                    }
                ]
            },
            "text": "Fixed Spoiler Detach"
        },
        "1784457213": {
            "comment": "Cars that were blown up, when fixed, immediately blew up again. Fixed it.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Tools.py": [
                    {
                        "diff": "@@ -499,7 +499,7 @@\n                         if c == car:\n                             Vehicle.ChangeBody(car, good=True)\n-                    if c == car:\n+                    if c == car and cD[\"health\"] > 0.5:\n                         car[\"blown\"] = False\n                     if cD[\"health\"] > 0.2:\n",
                        "comment": "Made a simple check to un-blow-up them only after a certain safe amount of health."
                    },
                    {
                        "diff": "@@ -535,7 +535,8 @@\n                                 dani[\"tool-attachment-model\"] = Reuse.Create(str(c))\n                                 dani[\"tool-attachment-model\"].suspendPhysics()\n                                 dani[\"tool-attachment-model\"].scaling = c.scaling.copy()\n-                                Vehicle.ColorPart(c, dani[\"tool-attachment-model\"])\n+                                if c.get(\"color\"):\n+                                    Vehicle.ColorPart(c, dani[\"tool-attachment-model\"])\n                                 Vehicle.RemoveSpoiler(car)\n",
                        "comment": "Oh... Ah... yeah... This is needed to fix a different bug, when old car ( before the color commit ) used to have strange spoilers."
                    }
                ]
            },
            "text": "Fixed Blown up cars blow up on fix."
        },
        "1784464044": {
            "comment": "It was rather weird that all cars sound like they are turned on all the time. So if nobody is driving the cars. They get no volume now.",
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -6819,6 +6819,9 @@\n         sound[\"play\"].pitch = pitch * 3\n         sound[\"play\"].volume = HV\n+        if not car.get(\"driver\"):\n+            sound[\"play\"].volume = 0\n         # Grind sound\n         v = -car.localLinearVelocity[1]\n         if v < 0: v *= -1\n",
                        "comment": "I did it by making her volume go to zero if there is no driver here..."
                    },
                    {
                        "diff": "@@ -6855,6 +6858,9 @@\n         v = -car.localLinearVelocity[1]\n         if v < 0: v *= -1\n         sound[\"play\"].volume = min(1.5, v)\n+        if not car.get(\"driver\"):\n+            sound[\"play\"].volume = 0\n def GearShiftSound(car):\n",
                        "comment": "here..."
                    }
                ]
            },
            "text": "Made cars without drivers have no engine noise"
        },
        "1784464223": {
            "comment": "I think I should make a more proper speed limit system instead.",
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -1169,7 +1169,7 @@\n     car[\"nitroing\"] = True\n-    Character.PoliceHeat(car.get(\"driver\", {}), \"Nitro\")\n+#    Character.PoliceHeat(car.get(\"driver\", {}), \"Nitro\")\n def StopNitro(car):\n",
                        "comment": "commented out the line that makes nitro a crime."
                    }
                ]
            },
            "text": "Made nitro not a crime."
        },
        "1784465656": {
            "comment": "It used to be that police would start chasing you as it spawns. Now it chases you only if it sees you. So if it spawns over a wall, they wont know you are there.",
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -4847,15 +4847,16 @@\n            or (car in bge.logic.globalDict[\"policeCars\"] and police_heat\\\n                and ( not thecar in bge.logic.globalDict[\"policeCars\"] or thecar.get(\"driver\") == dani ) ))\\\n            and thecar != car and carD[\"npc\"] != \"pursuit\":\n-            car[\"target\"] = thecar\n-            carD[\"npc\"] = \"pursuit\"\n-            #FaceTarget(car, car[\"target\"])\n-            AddNitroCan(car)\n-            carD[\"nitro\"] = 10.0\n-            if car in bge.logic.globalDict[\"policeCars\"] and thecar.get(\"driver\") == dani:\n-                Character.PoliceRadio(\"Pursuit\")\n-            print(consoleForm(car), \"Auto-Pursuit\", consoleForm(thecar))\n-            return\n+            if Character.Sees(car, thecar):\n+                car[\"target\"] = thecar\n+                carD[\"npc\"] = \"pursuit\"\n+                #FaceTarget(car, car[\"target\"])\n+                AddNitroCan(car)\n+                carD[\"nitro\"] = 10.0\n+                if car in bge.logic.globalDict[\"policeCars\"] and thecar.get(\"driver\") == dani:\n+                    Character.PoliceRadio(\"Pursuit\")\n+                print(consoleForm(car), \"Auto-Pursuit\", consoleForm(thecar))\n+                return\n     police_heat = dani.get(\"police_heat\", 0)\n     if police_heat and car in bge.logic.globalDict[\"policeCars\"] \\\n",
                        "comment": "Moved the chase code under an if statement to check whether they see you."
                    },
                    {
                        "diff": "@@ -6555,9 +6556,10 @@\n     for police in bge.logic.globalDict[\"policeCars\"]:\n         policeD       = Opt.FastDict(police)\n         if police.getDistanceTo(car) < 150 and police.get(\"driver\") and police != car and police.get(\"target\") != car:\n-            policeD[\"npc\"] = \"pursuit\"\n-            police[\"target\"] = car\n-            return True\n+            if Character.Sees(police, car):\n+                policeD[\"npc\"] = \"pursuit\"\n+                police[\"target\"] = car\n+                return True\n     return False\n",
                        "comment": "And again in a different place."
                    }
                ]
            },
            "text": "Made police more blind"
        },
        "1784467089": {
            "comment": "My poor coding choices made it so it completely forgets anything you dump into the config.json as soon as you update settings.",
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt"
            ],
            "changed_diffs": {
                "//run.py": [
                    {
                        "diff": "@@ -2018,6 +2018,7 @@\n                 \"maxperobjdata\":{},\n                 \"precalculate\" :precalculate.get_active(),\n                 \"username\"     :data.get(\"username\", getpass.getuser()),\n+                \"mp-hosts\"     :data.get(\"mp-hosts\", []),\n                 \"songs\"        :list(song_widgets.keys())\n                 }\n",
                        "comment": "Like for example mp-hosts"
                    }
                ],
                "//grabbed.txt": []
            },
            "text": "Preserve server list"
        },
        "1784467460": {
            "comment": "I accidentaly put a raceline file into the races folder. Which is a json and was trying to read itself as a race. But was failing. I added a checker for this not to break. And moved the file to where it needed to be.",
            "added": [
                "/racedata/raceline_Green_House_Race.json"
            ],
            "changed": [
                "/Scripts/Race_Manager.py"
            ],
            "changed_diffs": {
                "/Scripts/Race_Manager.py": [
                    {
                        "diff": "@@ -950,7 +950,11 @@\n         data = races[name]\n+        if type(data) != dict:\n+            continue\n         length = 0\n         first = data.get(\"starters\", [{}])[0].get(\"location\", (0,0,0))\n         prev = first\n         for i in data.get(\"checkpoints\", []):\n",
                        "comment": "Checker"
                    }
                ]
            },
            "text": "Fixed broken Race Manager"
        },
        "1784479750": {
            "comment": "A kit for Underground with front, back, and side pieces.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Garage.py",
                "/races/Green_House_Race.json"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/textures/icons.png": [],
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -234,6 +234,58 @@\n         \"icon\":[1,14],\n         \"usemodel\":\"RocketLauncherAttach\",\n         \"rocketLauncher\":True,\n+        \"position_free\":True\n+    },\n+    \"Underground_Kit1_Front\":{\n+        \"name\":\"Kit 1 Underground Front\",\n+        \"cost\":350,\n+        \"model\":\"\",\n+        \"icon\":[1,11],\n+        \"usemodel\":\"Underground_Kit1_Front\",\n+        \"effects\":{\n+            \"drag\"     :0.9,\n+            \"downforce\":1         \n+        },\n+        \"position_free\":True\n+    },\n+    \"Underground_Kit1_Back\":{\n+        \"name\":\"Kit 1 Underground Back\",\n+        \"cost\":350,\n+        \"model\":\"\",\n+        \"icon\":[1,10],\n+        \"usemodel\":\"Underground_Kit1_Back\",\n+        \"effects\":{\n+            \"drag\"     :0.9,\n+            \"downforce\":1         \n+        },\n+        \"position_free\":True\n+    },\n+    \"Underground_Kit1_Left\":{\n+        \"name\":\"Kit 1 Underground Left\",\n+        \"cost\":350,\n+        \"model\":\"\",\n+        \"icon\":[1,12],\n+        \"usemodel\":\"Underground_Kit1_Left\",\n+        \"effects\":{\n+            \"drag\"     :0.9,\n+            \"downforce\":1         \n+        },\n+        \"position_free\":True\n+    },\n+    \"Underground_Kit1_Right\":{\n+        \"name\":\"Kit 1 Underground Right\",\n+        \"cost\":350,\n+        \"model\":\"\",\n+        \"icon\":[1,13],\n+        \"usemodel\":\"Underground_Kit1_Right\",\n+        \"effects\":{\n+            \"drag\"     :0.9,\n+            \"downforce\":1         \n+        },\n         \"position_free\":True\n     }\n }\n",
                        "comment": "Adding the data about the pieces into the Garage."
                    }
                ],
                "/races/Green_House_Race.json": []
            },
            "text": "Underground Kit1"
        },
        "1784538385": {
            "comment": "When intensely playing some cars were despawning from the garage. This was because of the optimization system being a bit badly coded. When it spawns in the garage, it spawns in all cars in the list with the Spawn() function. Which first tries to Safely Despawn a car from cars you can't see. And then only if this doesn't work, will spawn a completely new car, using Reuse.Create() ( which also has a similar system ). SafelyDespawn marks cars it returns as deleted by Reuse. So when you can Reuse.Create it might actually spawn a Safely Despawned car. On car update ( on the next frame ) the car gets undeleted from Reuse. So it was okay for the most part. But in garage, multiple cars spawn in during the same one frame. So it could spawn one car. And then spawn in THE SAME CAR ( since it is still \"deleted\" ) again, as the second car of the garage. Which in turn made it so a car dissapeared from the garage.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Garage.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Multiplayer/client.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -343,11 +343,21 @@\n     if not saved:\n         return\n-    for cardata in saved:\n+    print()\n+    print(\"Respawning the Garage\", len(saved), \"cars.\")\n+    print()\n+    for n, cardata in enumerate(saved):\n         car = Vehicle.Decode(cardata)\n-        print( consoleForm(car), car.position)\n-        print( consoleForm(car), car.worldLinearVelocity)\n+        print( n, consoleForm(car), car.position)\n+        print( n, consoleForm(car), car.worldLinearVelocity)\n+    inside = Inside()\n+    print()\n+    print(\"Spawned in\", len(inside), \" cars.\")\n+    print()\n     bge.logic.globalDict[\"garage-saved\"] = []\n     UpdateShelfs()\n",
                        "comment": "This is diagnosis code. With this I figured out what went wrong."
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -4234,6 +4234,8 @@\n                           carname,\n                           anything=anything,\n                           keepdriver=driver)\n+        if car:\n+            Reuse.Undelete(car)\n         spawnedmessage = clr[\"tdgr\"]+\" Spawned Reused!\"\n",
                        "comment": "This is the fix."
                    }
                ],
                "/Scripts/Multiplayer/client.py": []
            },
            "text": "Fixed Spawnning of Garage (again)"
        },
        "1784544107": {
            "comment": "To fix engine you needed to aim the wrench up at a car from below. It worked but you could not see what you are doing and how much is left to do. Now we have a hollorgram for it.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Main_update.py",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/Scripts/Main_update.py": [
                    {
                        "diff": "@@ -618,6 +618,10 @@\n     scene.objects[\"Gage.001\"].visible = False\n+    scene.objects[\"Engine_Hollogram\"].visible = False\n     # Races\n     Racing.Precalculate()\n",
                        "comment": "Making the hologram invisible on init"
                    }
                ],
                "/Scripts/Tools.py": [
                    {
                        "diff": "@@ -47,6 +47,7 @@\n     camera     = scene.active_camera\n     hand  = scene.objects[\"Tool_Hand\"]\n     hc    = scene.objects[\"Health_Circle\"]\n+    Engine_Hollogram = scene.objects[\"Engine_Hollogram\"]\n     box = scene.objects[\"Boxify\"]\n     if box.get(\"timer\"): box[\"timer\"] -= 1\n",
                        "comment": "adding hologram into tools"
                    },
                    {
                        "diff": "@@ -69,6 +70,10 @@\n     elif str(dani.get(\"tool\")) == \"Bazooka\":\n         BazookaTool()\n+    if str(dani.get(\"tool\")) != \"PowerWrench\":\n+        if Engine_Hollogram.visible:\n+                Engine_Hollogram.visible = False\n def UpdateTool(tool):\n",
                        "comment": "if not using power wrench make the hologram invisible again"
                    },
                    {
                        "diff": "@@ -264,6 +269,7 @@\n     hc    = scene.objects[\"Health_Circle\"]\n     computer  = scene.objects[\"Computer\"]\n+    Engine_Hollogram = scene.objects[\"Engine_Hollogram\"]\n     box = scene.objects[\"Boxify\"]\n     moveusermodel = True\n",
                        "comment": "now the power wrench tool itself."
                    },
                    {
                        "diff": "@@ -295,7 +301,13 @@\n             objs.append(computer)\n         if not Vehicle.OnGround(car):\n-            objs.append(car)\n+            objs.append(Engine_Hollogram)\n+            if not Engine_Hollogram.visible:\n+                Engine_Hollogram.visible = True\n+        else:\n+            if Engine_Hollogram.visible:\n+                Engine_Hollogram.visible = False\n         for wheel in car[\"wheels\"]:\n             if ( wheel.visible and not attachment ) or  attachment == \"Wheels\" :\n",
                        "comment": "instead of aiming at the car aim at hollogram"
                    },
                    {
                        "diff": "@@ -381,11 +393,7 @@\n             if c:\n-                if c == car:\n-                    cD = Opt.FastDict(c)\n-                else:\n-                    cD = c\n                 found = True\n",
                        "comment": "moved this code lower"
                    },
                    {
                        "diff": "@@ -404,8 +412,9 @@\n                 elif \"Spoiler\" in str(c):\n                     text = \"[Spoiler]\"\n-                elif c == car:\n-                    text = \"[Engine and Chassis]\"\n+                elif c == Engine_Hollogram:\n+                    text = \"[Engine]\"\n                 elif c in car[\"doors\"]:\n                     text = \"[Bodywork]\"\n",
                        "comment": "we are concidering engine when aming at the hologram"
                    },
                    {
                        "diff": "@@ -420,12 +429,20 @@\n                         if Garage.shop[thing].get(\"usemodel\") == str(c):\n                             text = \"[\"+Garage.shop[thing].get(\"name\", thing)+\"]\"\n+                orc = c\n+                if c == Engine_Hollogram:\n+                    c = car\n+                    cD = Opt.FastDict(c)\n+                else:\n+                    cD = c\n                 if c != computer:\n                     text = text + \"\\n\" + str(int(round(cD.get(\"health\", 1.0)*100)))+\"%\"\n                     text = text + \"\\n[LMB] to fix.\\n[RMB] to take.\"\n-                Hints.Show(\"tool\", text, c,\n-                           allow_under = ( c == car ))\n+                Hints.Show(\"tool\", text, orc)\n                 # Activate the tool\n                 if mousecodes[\"LMB\"] in mouse or joystickcodes[\"A_><\"] in joystickButtons:\n",
                        "comment": "Making sure that you are actually fixing the car by aiming at this other object, lol. And reshuffeling the UI."
                    }
                ]
            },
            "text": "Made fixing engine easier, by adding a hologram."
        },
        "1784563082": {
            "comment": "Now you can buy sets of breaks of various strength to attatch them to the wheels of the car. To get them to handle better.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/textures/icons.png",
                "/Scripts/Garage.py",
                "/Scripts/Vehicle.py",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/textures/icons.png": [],
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -287,7 +287,53 @@\n             \"downforce\":1         \n         },\n         \"position_free\":True\n+    },\n+    \"Breaks1\":{\n+        \"name\":\"Break\",\n+        \"cost\":100,\n+        \"model\":\"\",\n+        \"icon\":[1,9],\n+        \"usemodel\":\"DiskBreaks\",\n+        \"effects\":{\n+            \"breaks\":5         \n+        }\n+    },\n+    \"Breaks2\":{\n+        \"name\":\"Breaks FINE\",\n+        \"cost\":350,\n+        \"model\":\"\",\n+        \"icon\":[1,9],\n+        \"usemodel\":\"DiskBreaks\",\n+        \"effects\":{\n+            \"breaks\":10         \n+        }\n+    },\n+    \"Breaks3\":{\n+        \"name\":\"Breaks SUPER\",\n+        \"cost\":500,\n+        \"model\":\"\",\n+        \"icon\":[1,9],\n+        \"usemodel\":\"DiskBreaks\",\n+        \"effects\":{\n+            \"breaks\":15         \n+        }\n+    },\n+    \"Breaks4\":{\n+        \"name\":\"Breaks MEGA\",\n+        \"cost\":999,\n+        \"model\":\"\",\n+        \"icon\":[1,9],\n+        \"usemodel\":\"DiskBreaks\",\n+        \"effects\":{\n+            \"breaks\":20         \n+        }\n     }\n }\n def AddCarData(carData):\n",
                        "comment": "Sets of breaks"
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -470,6 +470,17 @@\n                 roll += 0.8\n             grip = grip*math.sqrt(car.mass)*hbf\n+            if car.get(\"braking\") and wheelObject.get(\"extra-breaks\"):\n+                extra_breaks = wheelObject.get(\"extra-breaks\")\n+                if extra_breaks:\n+                    power = Garage.shop.get(extra_breaks, {}).get(\"effects\",{}).get(\"breaks\", 1)\n+                    tgrip = grip * power\n+                    lastgrip = carD.get(\"lastgrip\", grip)\n+                    grip = lastgrip + ( ( tgrip - lastgrip ) / Opt.Velocity(10) )\n+            carD[\"lastgrip\"] = grip\n             getCarPhysics(car).setTyreFriction(grip, n)\n             getCarPhysics(car).setRollInfluence(roll, n)\n",
                        "comment": "Actuall applying of the breaks. I tried adjI tried applying breaks to the actual breaking physics but it didn't produce much effect since the rubber is rubbish. Instead I augment the grip on breaking."
                    },
                    {
                        "diff": "@@ -1097,7 +1108,9 @@\n         # If the car moves forward stopping only with back\n         # wheels so it will not fly into the air.\n         if ( factor < 0 and not wheel[\"front\"] ) or ( factor > 0 and wheel[\"front\"] ):\n-            getCarPhysics(car).applyBraking(Abs*health*strenght, n)\n+            strenght = Abs*health*strenght\n+            getCarPhysics(car).applyBraking(strenght, n)\n         else:\n             getCarPhysics(car).applyBraking(0, n)\n",
                        "comment": "This is where I tried doing it earlier."
                    },
                    {
                        "diff": "@@ -4325,6 +4338,9 @@\n     try: RemoveSpoiler(car)\n     except: pass\n+    for wheel in car.get(\"wheels\", []):\n+        wheel[\"extra-breaks\"] = None\n     try: RemovePoliceLights(car)\n     except: pass\n     car[\"police\"] = False\n",
                        "comment": "When new cars spawn we remove the break augmentations."
                    },
                    {
                        "diff": "@@ -7414,7 +7430,8 @@\n     for wheel in car.get(\"wheels\", []):\n         wheeldata = {\n             \"health\"  : wheel[\"health\"],\n-            \"visible\" : wheel.visible\n+            \"visible\" : wheel.visible,\n+            \"extra-breaks\":wheel.get(\"extra-breaks\")\n         }\n         colors = wheel.get(\"colors\")\n",
                        "comment": "And ofcourse it need to be save-able into JSON"
                    },
                    {
                        "diff": "@@ -7615,6 +7632,7 @@\n             wheel[\"health\"] = wheeldata.get(\"health\", 1.0)\n             wheel.visible   = wheeldata.get(\"visible\", True)\n+            wheel[\"extra-breaks\"] = wheeldata.get(\"extra-breaks\")\n             if wheeldata.get(\"colors\"):\n                 wheel[\"colors\"] = wheeldata.get(\"colors\")\n",
                        "comment": "and retreavable from JSON"
                    }
                ],
                "/Scripts/Tools.py": [
                    {
                        "diff": "@@ -310,7 +310,7 @@\n                 Engine_Hollogram.visible = False\n         for wheel in car[\"wheels\"]:\n-            if ( wheel.visible and not attachment ) or  attachment == \"Wheels\" :\n+            if ( wheel.visible and not attachment ) or  attachment == \"Wheels\" or ( \"Break\" in str(attachment) and not wheel.get(\"extra-breaks\")):\n                 objs.append(wheel)\n         for door in car.get(\"doors\", []):\n",
                        "comment": "Added a little Hint for breaks."
                    },
                    {
                        "diff": "@@ -440,6 +439,9 @@\n                 if c != computer:\n                     text = text + \"\\n\" + str(int(round(cD.get(\"health\", 1.0)*100)))+\"%\"\n                     text = text + \"\\n[LMB] to fix.\\n[RMB] to take.\"\n+                if c.get(\"extra-breaks\"):\n+                    text = text + \"   + Extra Breaks\"\n                 Hints.Show(\"tool\", text, orc)\n",
                        "comment": "Wait... This is the hint about breaks. That previous thing was the if statement to highlight wheels on attachment of breaks."
                    },
                    {
                        "diff": "@@ -468,6 +470,10 @@\n                         dani[\"tool-attachment\"] = None\n+                    # Installing breaks\n+                    if c in car[\"wheels\"] and \"Break\" in str(attachment):\n+                        c[\"extra-breaks\"] = attachment\n+                        dani[\"tool-attachment\"] = None\n",
                        "comment": "Attachment of breaks."
                    },
                    {
                        "diff": "@@ -575,13 +581,19 @@\n                     # Removing wheels\n                     elif c in car[\"wheels\"] and not attachment:\n-                        c[\"health\"] = 0.0\n-                        c.visible = False\n-                        dani[\"tool-attachment\"] = \"Wheels\"\n-                        dani[\"tool-attachment-model\"] = Reuse.Create(str(c))\n-                        dani[\"tool-attachment-model\"].suspendPhysics()\n-                        dani[\"tool-attachment-model\"].scaling = c.scaling.copy()\n-                        Vehicle.ColorPart(c, dani[\"tool-attachment-model\"])\n+                        if c.get(\"extra-breaks\"):\n+                            dani[\"tool-attachment\"] = c.get(\"extra-breaks\")\n+                            c[\"extra-breaks\"] = None\n+                        else:\n+                            c[\"health\"] = 0.0\n+                            c.visible = False\n+                            dani[\"tool-attachment\"] = \"Wheels\"\n+                            dani[\"tool-attachment-model\"] = Reuse.Create(str(c))\n+                            dani[\"tool-attachment-model\"].suspendPhysics()\n+                            dani[\"tool-attachment-model\"].scaling = c.scaling.copy()\n+                            Vehicle.ColorPart(c, dani[\"tool-attachment-model\"])\n                     elif c in car.get(\"Attachments\", []):\n                         for name in Garage.shop:\n",
                        "comment": "Removal of breaks. If there are breaks, you remove them first, and then the wheel."
                    },
                    {
                        "diff": "@@ -673,6 +685,19 @@\n                     box.position = ray[1]\n                     box.position.z += 1\n                     box.scaling  = (1,1,1)\n+                    itemdata = Garage.shop.get(dani[\"tool-attachment\"], {})\n+                    text = \"            [\"+itemdata.get(\"name\", \"item\")+\"]\\n             Effects:\\n\"\n+                    for effect in itemdata.get(\"effects\", {}):\n+                        value = itemdata[\"effects\"][effect]\n+                        value = ( value - 1 ) * 100\n+                        if value > 0: value = \"+\"+str(round(value, 1))+\"%\"\n+                        else:         value = str(round(value,1))+\"%\"\n+                        text = text + \"                \"+effect+\" \"+value+\"\\n\"\n+                    Hints.Show(\"item description\",\n+                               text,\n+                               dani)\n                 # Dropping the part\n                 if ( mousecodes[\"LMB\"] in mouse or joystickcodes[\"A_><\"] in joystickButtons ) and ray[1] and not tool.get(\"active-timer\"):\n",
                        "comment": "A hint about an item you are holding, with its effects and stuff ( because all breaks look the same )."
                    }
                ]
            },
            "text": "Ability to improve breaks."
        },
        "1784568460": {
            "comment": "Forgot to make it so custom breaks would detatch with the wheel. When you break it.",
            "added": [],
            "changed": [
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -2825,6 +2825,8 @@\n                 newWheel.orientation = wheelObject.orientation\n                 newWheel.scaling     = wheelObject.scaling\n                 ColorPart(car, newWheel)\n+                wheelObject[\"extra-breaks\"] = None \n                 # Now a little physics cheat to make this pop\n                 # more exciting! Let the wheel have the same\n",
                        "comment": "One line and that is all you need."
                    }
                ]
            },
            "text": "Breaks detatch with wheel."
        },
        "1784573165": {
            "comment": "Tweaks",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Garage.py",
                "/Scripts/Tools.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Garage.py": [],
                "/Scripts/Tools.py": []
            },
            "text": "Tweaks"
        },
        "1784576359": {
            "comment": "Problem: There was a bug where randomly cars in the garage would be colored one was and their doors another way. This is a fix for said bug.",
            "added": [],
            "changed": [
                "/Scripts/Garage.py",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -398,6 +398,7 @@\n         car = Vehicle.Decode(cardata)\n         print( n, consoleForm(car), car.position)\n         print( n, consoleForm(car), car.worldLinearVelocity)\n     inside = Inside()\n     print()\n",
                        "comment": "\\"
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -3033,7 +3033,6 @@\n     # Getting objects\n     for obj in car.childrenRecursive:\n-        obj[\"colors\"] = car[\"colors\"]\n         ColorPart(car, obj)\n     for wheel in car.get(\"wheels\", []):\n",
                        "comment": "Removed unnesesary color copying."
                    },
                    {
                        "diff": "@@ -3157,7 +3156,7 @@\n     # This function colors a specific part\n     # of the car, into the colors of the car.\n-    part[\"colors\"] = car[\"colors\"]\n+    part[\"colors\"] = car[\"colors\"].copy()\n     for attribute in car.get(\"colors\", []):\n         value = car[\"colors\"][attribute]\n",
                        "comment": "added .copy() so python would recognize colors of doors as separate enteties to colors for the whole car."
                    }
                ]
            },
            "text": "Fixed cars lose half of their color."
        },
        "1784582739": {
            "comment": "Made it so the game doesn't despawn a car you took from the garage, even if you leave it very far away.",
            "added": [],
            "changed": [
                "/Scripts/Garage.py",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -365,10 +365,11 @@\n     for car in bge.logic.globalDict[\"allcars\"]:\n         if car.getDistanceTo(garage) < garageDistance:\n             cardata = Vehicle.Encode(car)\n             saved.append(cardata)\n             Reuse.Delete(car)\n+            Vehicle.UnsetMyCar(car)\n     bge.logic.globalDict[\"garage-saved\"] = saved\n",
                        "comment": "When it is recorded in the garage, the MY CAR thing is un-recorded. So it could be despawned. The data there is recorded anyway."
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -896,6 +896,36 @@\n     # Making night lights\n     GameTime.NightLightsEffect(car)\n+    SetMyCar(car)\n+def SetMyCar(car):\n+    # The idea is to make it so when the player drives their car\n+    # ( which could be very expencive and, into which, a lot of\n+    # effor was put in ), to an event away from the garage. This\n+    # car should be remained un-despawnable.\n+    # I think the best way is to record whether the car belongs\n+    # to the player. If the player gets into said car in the\n+    # garage.\n+    carsInGarage = Garage.Inside()\n+    if car in carsInGarage and str(car.get(\"driver\")) == \"Dani_Box\":\n+        if not IsMyCar(car):\n+            print(consoleForm(car), \"Set as My Car\")\n+            car[\"my_car\"] = True\n+def IsMyCar(car):\n+    try:\n+        return car.get(\"my_car\", False)\n+    except: return False\n+def UnsetMyCar(car):\n+    if IsMyCar(car):\n+        car[\"my_car\"] = False\n+        print(consoleForm(car), \"is no longer My Car\")\n def JoystickControl(car):\n",
                        "comment": "The 3 functions for my car logic."
                    },
                    {
                        "diff": "@@ -4427,7 +4457,7 @@\n         # print()\n         # We should never take cars from the garage\n-        if car in Garage.Inside():\n+        if car in Garage.Inside() or IsMyCar(car):\n             continue\n         # If we need a specific model skip anything else\n",
                        "comment": "When safe-despawning ( for spawning of cars on the road ) avoid despawning my car."
                    }
                ]
            },
            "text": "Don't despawn MY CAR"
        },
        "1784591752": {
            "comment": "For the longest time car attachments were recorded ( into save files and alike ) in world space. Which was not ideal for multitude of reasons. Now I finally figured out the math to make it all relative instead.",
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Main_update.py",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//assembly.blend": [],
                "/Scripts/Main_update.py": [
                    {
                        "diff": "@@ -166,6 +166,8 @@\n                          camSurroundCars)\n     Vehicle.UnspawnLogic()\n+    Vehicle.SpawnMyCar()\n     # Logic reducing hints rendered on the screens.\n     Hints.UnshowLogic()\n",
                        "comment": "This function spawns your car, after it despawns ( if needed by the spawn system )"
                    }
                ],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -926,7 +926,35 @@\n         car[\"my_car\"] = False\n         print(consoleForm(car), \"is no longer My Car\")\n+def SpawnMyCar():\n+    scene = bge.logic.getCurrentScene()\n+    dani = scene.objects[\"Dani_Box\"]\n+    addr = Opt.Address(dani.position.copy())\n+    for n, cardata in enumerate(bge.logic.globalDict.get(\"my-cars\", {}).get(addr, [])):\n+        if dani.getDistanceTo( cardata.get(\"position\", (0,0,0)) ) < 100:\n+            car = Decode(cardata)\n+            bge.logic.globalDict[\"my-cars\"][addr].remove(cardata)\n+            print(consoleForm(car), \" my car has been restored.\")\n+def DespawnMyCar(car):\n+    if \"my-cars\" not in bge.logic.globalDict:\n+        bge.logic.globalDict[\"my-cars\"] = {}\n+    addr = Opt.Address(car.position.copy())\n+    if addr not in bge.logic.globalDict[\"my-cars\"]:\n+        bge.logic.globalDict[\"my-cars\"][addr] = []\n+    cardata = Encode(car)\n+    bge.logic.globalDict[\"my-cars\"][addr].append(cardata)\n+    print(consoleForm(car), \" my car has been temporarely despawned.\")\n def JoystickControl(car):\n     # Controlling a car with a controller.\n",
                        "comment": "The functions of spawn and despawn of my car. The car is encoded like in the garage, but not saved into the save file. "
                    },
                    {
                        "diff": "@@ -4457,7 +4485,10 @@\n         # print()\n         # We should never take cars from the garage\n-        if car in Garage.Inside() or IsMyCar(car):\n+        if car in Garage.Inside():\n+            continue\n+        if IsMyCar(car) and dani.getDistanceTo(car) < 110:\n             continue\n         # If we need a specific model skip anything else\n",
                        "comment": "Changed the if statements to make sense with the new spawn and despawn stuff."
                    },
                    {
                        "diff": "@@ -4476,7 +4507,10 @@\n              and car.get(\"nodespawn\", 0) < 1      # Not just spawned\n              and car not in Script.Story.values() # Not a story related car\n             ) or bypass:\n+            # If it is my car do some preservatory magic.\n+            if IsMyCar(car):\n+                DespawnMyCar(car)\n             # Deleting the car in an inactive way.\n             Reuse.Delete(car, inactive=True)\n",
                        "comment": "On safe-despawn the car actually despawns"
                    },
                    {
                        "diff": "@@ -7371,13 +7405,63 @@\n #### SAVE / MULTIPLAYER FUNCTIONS #####\n+def FromRelativeObject(car, obj):\n+    # This function tries to record a relative position\n+    # and orientation of an object. Such that this relative\n+    # position and orientation could be later restored.\n+    # Primary use: Encoding and Decoding Car attachmetns.\n+    position = obj.position.copy()\n+    orientation = obj.orientation.copy()\n+    # We are not dealing with scale\n+    position -= car.worldPosition\n+    position.rotate( car.orientation.to_quaternion().inverted() )\n+    orientation.rotate( car.orientation.to_quaternion().inverted() )\n+    return position, orientation\n+def ObjectToRelativePoint(car, obj,\n+                          position=(0,0,0),\n+                          orientation=(0,0,0)):\n+    # This function will take an object, like the attachments, we\n+    # recorded in FromRelativeObject() and restore it as precisely\n+    # as it can.\n+    FPS = bge.logic.getAverageFrameRate()\n+    position = mathutils.Vector(position)\n+    if type(orientation) not in (mathutils.Vector, mathutils.Euler, mathutils.Matrix):\n+        orientation = mathutils.Euler(orientation)\n+    obj.orientation = orientation\n+    obj.position = position\n+    obj.orientation.rotate( car.orientation )\n+    obj.position.rotate( car.orientation )\n+    obj.position += car.position\n+    obj.position += car.worldLinearVelocity / FPS\n+    obj.orientation.rotate( mathutils.Euler( car.worldAngularVelocity / FPS ) )\n def EncodeRotation(car):\n     rot = list(car.worldOrientation)\n     for n, i in enumerate(rot):\n         rot[n] = list(i)\n     return rot\n+def EncodeMatrixRotation(matrix):\n+    rot = list(matrix)\n+    for n, i in enumerate(rot):\n+        rot[n] = list(i)\n+    return rot\n def Encode(car):\n     # This function will generate a copy of the car's\n",
                        "comment": "This is the realtive math stuff. A lot of matrixes and rotations and vectors and stuff to make it all work. Notice I add linear velocity divided by FPS on restoring the object. UPBE has quirks. "
                    },
                    {
                        "diff": "@@ -7442,10 +7526,13 @@\n     for obj in car.get(\"Attachments\", []):\n+        loc, rot = FromRelativeObject(car, obj)\n         objdata = {\n             \"name\":str(obj),\n-            \"position\":list(obj.worldPosition),\n-            \"orientation\":EncodeRotation(obj),\n+            \"relative-position\":list(loc),\n+            \"relative-orientation\":EncodeMatrixRotation(rot),\n             \"health\":obj.get(\"health\", 1)\n         }\n",
                        "comment": "Instead of writing position and orientation, we write relative-position and relative-orientation"
                    },
                    {
                        "diff": "@@ -7610,6 +7697,16 @@\n             obj = Reuse.Create(objdata.get(\"name\", \"Intake1_Attach\"))\n             obj.worldPosition = objdata.get(\"position\", [0,0,0])\n             obj.orientation = objdata.get(\"orientation\", [0,0,0])\n+            loc = objdata.get(\"relative-position\")\n+            rot = objdata.get(\"relative-orientation\")\n+            if loc and rot:\n+                try:\n+                    rot = mathutils.Matrix(rot)\n+                except: rot = [0,0,0]\n+                ObjectToRelativePoint(car, obj, loc, rot)\n             Attach(car, obj, True, objdata.get(\"health\", 1))\n             if objdata.get(\"colors\"):\n",
                        "comment": "For backward compatibility we keep the code that loads in the old way of doing it. But we also load in the relative loc and pos too."
                    }
                ]
            },
            "text": "Attatchments are now relative"
        },
        "1784634964": {
            "comment": "I was dumping the data about my car ( on despawn ) by simply appending it into a list. So it could have happened twice. And I saw at least one time when it spawned back 2 cars. Now I assing variables in a dict instead. Which insures it is one per.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -935,26 +936,29 @@\n     addr = Opt.Address(dani.position.copy())\n-    for n, cardata in enumerate(bge.logic.globalDict.get(\"my-cars\", {}).get(addr, [])):\n+    for n, ID in enumerate(list(bge.logic.globalDict.get(\"my-cars\", {}).get(addr, {}).keys())):\n+        cardata = bge.logic.globalDict[\"my-cars\"][addr][ID]\n         if dani.getDistanceTo( cardata.get(\"position\", (0,0,0)) ) < 100:\n             car = Decode(cardata)\n-            bge.logic.globalDict[\"my-cars\"][addr].remove(cardata)\n+            try:\n+                del bge.logic.globalDict[\"my-cars\"][addr][ID]\n+            except:\n+                pass\n             print(consoleForm(car), \" my car has been restored.\")\n def DespawnMyCar(car):\n     if \"my-cars\" not in bge.logic.globalDict:\n         bge.logic.globalDict[\"my-cars\"] = {}\n     addr = Opt.Address(car.position.copy())\n     if addr not in bge.logic.globalDict[\"my-cars\"]:\n-        bge.logic.globalDict[\"my-cars\"][addr] = []\n+        bge.logic.globalDict[\"my-cars\"][addr] = {}\n+    ID = id(car)\n     cardata = Encode(car)\n-    bge.logic.globalDict[\"my-cars\"][addr].append(cardata)\n+    bge.logic.globalDict[\"my-cars\"][addr][ID] = cardata\n     print(consoleForm(car), \" my car has been temporarely despawned.\")\n def JoystickControl(car):\n     # Controlling a car with a controller.\n",
                        "comment": "The change in question."
                    }
                ]
            },
            "text": "Fixed duplicating my car on respawn"
        },
        "1784806307": {
            "comment": "You should just be able to start the race in the story mode, without the need to have money for it or anything. If the story says you race, you race! So I made the app just give you a V button to start the race, if it is part of the story.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Phone.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/Scripts/Phone.py": [
                    {
                        "diff": "@@ -19,6 +19,7 @@\n from Scripts import Vehicle\n from Scripts import Racing\n from Scripts import Money\n+from Scripts import Script\n from Scripts.Multiplayer import client\n from Scripts.Common import *\n",
                        "comment": "Added Script ( the story module into Phone )"
                    },
                    {
                        "diff": "@@ -1301,141 +1302,145 @@\n             position=(0.0,0.0),\n             size=(1.5,1.8))\n-        R = \"No\"\n-        if race.get(\"reversed\"):\n-            R = \"Yes\"\n-        raceText = \"\"\n-        ghosts = [\"None\", \"Best\", \"Last\", \"Random\"]\n-        records = Racing.GetRecords(race)\n-        records_names = {}\n-        for n, r in enumerate(records):\n-            t = timestring(r.get(\"time\",0))\n-            u = r.get(\"username\", \"\")\n-            n = u+\" \"+t\n-            ghosts.append(n)\n-            records_names[n] = r\n-        if not records:\n-            race[\"ghost\"] = \"None\"\n-        if race.get(\"amount-racers\", 1):\n-            raceText = raceText + \"Bid: [$\"+str(int(round(race.get(\"reward\", 1000) / (race.get(\"amount-racers\", 1)+1))))+\"]\"\n-            raceText = raceText + \"\\nCars: [\"+str(race.get(\"amount-racers\", 1))+\"]\"\n-        else:\n-            ghostname = race.get(\"ghost\", \"None\")\n-            if len(ghostname) < 6:\n-                raceText = raceText + \"Ghost: [\"+ghostname+\"]\"\n+        during = race.get(\"during\")\n+        isDuring = Script.Story.get(during)\n+        if not isDuring:\n+            R = \"No\"\n+            if race.get(\"reversed\"):\n+                R = \"Yes\"\n+            raceText = \"\"\n+            ghosts = [\"None\", \"Best\", \"Last\", \"Random\"]\n+            records = Racing.GetRecords(race)\n+            records_names = {}\n+            for n, r in enumerate(records):\n+                t = timestring(r.get(\"time\",0))\n+                u = r.get(\"username\", \"\")\n+                n = u+\" \"+t\n+                ghosts.append(n)\n+                records_names[n] = r\n+            if not records:\n+                race[\"ghost\"] = \"None\"\n+            if race.get(\"amount-racers\", 1):\n+                raceText = raceText + \"Bid: [$\"+str(int(round(race.get(\"reward\", 1000) / (race.get(\"amount-racers\", 1)+1))))+\"]\"\n+                raceText = raceText + \"\\nCars: [\"+str(race.get(\"amount-racers\", 1))+\"]\"\n             else:\n-                raceText = raceText + \"[\"+ghostname+\"]  \"+(\" \"*int((len(ghostname)-6)))\n-            raceText = raceText + \"\\n[Time Trial]\"\n-        raceText = raceText + \"\\nLaps: [\"+str(race.get(\"laps\", 1))+\"]\"\n-        raceText = raceText + \"\\nReversed: [\"+R+\"]\"\n-        if race.get(\"amount-racers\", 1):\n-            raceText = raceText + \"\\nReward: [$\"+str(int(round(race.get(\"reward\", 1000))))+\"]\"\n-        Text(\"Racing_Race_settings\"+race.get(\"racename\"),\n-             raceText,\n-             position=(0.0,0.0),\n-             size=0.17)\n-        # Ghost setter\n-        if not race.get(\"amount-racers\", 1) and records:\n-            def AddGhost():\n-                try:\n-                    index = ghosts.index(race.get(\"ghost\", \"None\")) + 1\n-                    index = min(len(ghosts)-1, max(0, index))\n-                    race[\"ghost\"] = ghosts[index]\n-                except:\n-                    race[\"ghost\"] = \"None\"\n+                ghostname = race.get(\"ghost\", \"None\")\n+                if len(ghostname) < 6:\n+                    raceText = raceText + \"Ghost: [\"+ghostname+\"]\"\n+                else:\n+                    raceText = raceText + \"[\"+ghostname+\"]  \"+(\" \"*int((len(ghostname)-6)))\n+                raceText = raceText + \"\\n[Time Trial]\"\n+            raceText = raceText + \"\\nLaps: [\"+str(race.get(\"laps\", 1))+\"]\"\n+            raceText = raceText + \"\\nReversed: [\"+R+\"]\"\n+            if race.get(\"amount-racers\", 1):\n+                raceText = raceText + \"\\nReward: [$\"+str(int(round(race.get(\"reward\", 1000))))+\"]\"\n+            Text(\"Racing_Race_settings\"+race.get(\"racename\"),\n+                 raceText,\n+                 position=(0.0,0.0),\n+                 size=0.17)\n+            # Ghost setter\n+            if not race.get(\"amount-racers\", 1) and records:\n+                def AddGhost():\n+                    try:\n+                        index = ghosts.index(race.get(\"ghost\", \"None\")) + 1\n+                        index = min(len(ghosts)-1, max(0, index))\n+                        race[\"ghost\"] = ghosts[index]\n+                    except:\n+                        race[\"ghost\"] = \"None\"\n+                    Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n+                Icon(\"RacingApp_Ghost_Add\",\n+                     \"up\",\n+                     position=(0.2, -0.04),\n+                     size=0.2,\n+                     execute=AddGhost)\n+                def ReduceGhost():\n+                    try:\n+                        index = ghosts.index(race.get(\"ghost\", \"None\")) - 1\n+                        index = min(len(ghosts)-1, max(0, index))\n+                        race[\"ghost\"] = ghosts[index]\n+                    except:\n+                        race[\"ghost\"] = \"None\"\n+                    Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n+                Icon(\"RacingApp_Ghost_Reduce\",\n+                     \"down\",\n+                     position=(0.3, -0.04),\n+                     size=0.2,\n+                     execute=ReduceGhost)\n+            # Cars adjuster\n+            def AddCars():\n+                race[\"amount-racers\"] = race.get(\"amount-racers\", 1) + 1\n                 Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n-            Icon(\"RacingApp_Ghost_Add\",\n+            Icon(\"RacingApp_Racers_Add\",\n                  \"up\",\n-                 position=(0.2, -0.04),\n+                 position=(0.2, -0.13),\n                  size=0.2,\n-                 execute=AddGhost)\n-            def ReduceGhost():\n-                try:\n-                    index = ghosts.index(race.get(\"ghost\", \"None\")) - 1\n-                    index = min(len(ghosts)-1, max(0, index))\n-                    race[\"ghost\"] = ghosts[index]\n-                except:\n-                    race[\"ghost\"] = \"None\"\n+                 execute=AddCars)\n+            def ReduceCars():\n+                race[\"amount-racers\"] = max(0, race.get(\"amount-racers\", 1) - 1)\n                 Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n-            Icon(\"RacingApp_Ghost_Reduce\",\n+            Icon(\"RacingApp_Racers_Reduce\",\n                  \"down\",\n-                 position=(0.3, -0.04),\n+                 position=(0.3, -0.13),\n                  size=0.2,\n-                 execute=ReduceGhost)\n-        # Cars adjuster\n-        def AddCars():\n-            race[\"amount-racers\"] = race.get(\"amount-racers\", 1) + 1\n-            Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n-        Icon(\"RacingApp_Racers_Add\",\n-             \"up\",\n-             position=(0.2, -0.13),\n-             size=0.2,\n-             execute=AddCars)\n-        def ReduceCars():\n-            race[\"amount-racers\"] = max(0, race.get(\"amount-racers\", 1) - 1)\n-            Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n-        Icon(\"RacingApp_Racers_Reduce\",\n-             \"down\",\n-             position=(0.3, -0.13),\n-             size=0.2,\n-             execute=ReduceCars)\n-        # Laps adjuster\n-        def AddLaps():\n-            race[\"laps\"] = race.get(\"laps\", 1) + 1\n-            Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n-        Icon(\"RacingApp_Laps_Add\",\n-             \"up\",\n-             position=(0.2, -0.21),\n-             size=0.2,\n-             execute=AddLaps)\n-        def ReduceLaps():\n-            race[\"laps\"] = max(1, race.get(\"laps\", 1) - 1)\n-            Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n-        Icon(\"RacingApp_Laps_Reduce\",\n-             \"down\",\n-             position=(0.3, -0.21),\n-             size=0.2,\n-             execute=ReduceLaps)\n-        def ReverseRace():\n-            bge.logic.globalDict[\"races\"][race[\"racename\"]] = Racing.Reverse(race)\n-            Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n-        Icon(\"RacingApp_Reverse\",\n-             \"back\",\n-             position=(0.3, -0.28),\n-             size=0.2,\n-             execute=ReverseRace)\n-        if Money.Have(race.get(\"reward\", 1000) / (race.get(\"amount-racers\", 1)+1)) or not race.get(\"amount-racers\", 1):\n+                 execute=ReduceCars)\n+            # Laps adjuster\n+            def AddLaps():\n+                race[\"laps\"] = race.get(\"laps\", 1) + 1\n+                Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n+            Icon(\"RacingApp_Laps_Add\",\n+                 \"up\",\n+                 position=(0.2, -0.21),\n+                 size=0.2,\n+                 execute=AddLaps)\n+            def ReduceLaps():\n+                race[\"laps\"] = max(1, race.get(\"laps\", 1) - 1)\n+                Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n+            Icon(\"RacingApp_Laps_Reduce\",\n+                 \"down\",\n+                 position=(0.3, -0.21),\n+                 size=0.2,\n+                 execute=ReduceLaps)\n+            def ReverseRace():\n+                bge.logic.globalDict[\"races\"][race[\"racename\"]] = Racing.Reverse(race)\n+                Redraw(\"Racing_Race_settings\"+race.get(\"racename\"))\n+            Icon(\"RacingApp_Reverse\",\n+                 \"back\",\n+                 position=(0.3, -0.28),\n+                 size=0.2,\n+                 execute=ReverseRace)\n+        if Money.Have(race.get(\"reward\", 1000) / (race.get(\"amount-racers\", 1)+1)) or not race.get(\"amount-racers\", 1) or isDuring:\n             def SendRacers():\n                 if race.get(\"amount-racers\", 1):\n                     Racing.SpawnRacers(race, race[\"racename\"])\n",
                        "comment": "Moved the UI of setting up the race under an if statement. So it only shows up if you are not in the story."
                    }
                ]
            },
            "text": "Fixed starting races in story"
        },
        "1784809309": {
            "comment": "I updated the way bought items were handeled. Now scene 2 ( where you have to fix the car you broke ) works with the new system.",
            "added": [],
            "changed": [
                "//assembly.blend",
                "/Scripts/Script.py",
                "/Scripts/Garage.py"
            ],
            "changed_diffs": {
                "//assembly.blend": [],
                "/Scripts/Script.py": [
                    {
                        "diff": "@@ -1038,6 +1038,8 @@\n         if \"dialogue8\" not in Story and ( not Story[\"Jack\"].get(\"saying\") or not Story[\"Jack\"][\"saying\"].status ):\n             Story[\"dialogue8\"] = PlayDialogue(\"get_the_car_out_here\", Story[\"Jack\"])\n+            UI.Print(\"Unload the car here. And drive it into the garage.\", True)\n             Story[\"Jack\"][\"saying\"] = Story[\"dialogue8\"]\n         if \"dialogue8\" in Story:\n",
                        "comment": "Added a little note to the player in one area."
                    },
                    {
                        "diff": "@@ -1083,11 +1085,16 @@\n             Garage.inventory[\"Parts\" ] = max(Garage.inventory.get(\"Parts\" , 0), parts )\n             Garage.inventory[\"Wheels\"] = max(Garage.inventory.get(\"Wheels\", 0), wheels)\n             Garage.UpdateShelfs()\n+            # Since about July of 2026 the shelves are done differently\n+            Garage.UnloadLegacyShelves(area=[-760.1, -1041, 406], radius=2)\n             Money.Sound()\n             Story[\"stage\"] = 13\n-            UI.Print(\"Fix the car.\")\n+            UI.Print(\"Fix the car's outside shell.\")\n     if Story.get(\"stage\") == 13:\n",
                        "comment": "This is the fix. I run the Legacy Shelves convertor. Silly I know."
                    }
                ],
                "/Scripts/Garage.py": [
                    {
                        "diff": "@@ -757,20 +757,19 @@\n             else:\n                 model.visible = True\n-def UnloadLegacyShelves():\n+def UnloadLegacyShelves(area=[-741.6, -1048, 406], radius=5):\n     scene = bge.logic.getCurrentScene()\n-    area = [-741.6, -1048, 406]\n     for name in inventory:\n         amount = inventory[name]\n         if amount:\n             for i in range(amount):\n                 loc = mathutils.Vector(area)\n-                loc.x += random.uniform(-5, 5)\n-                loc.y += random.uniform(-5, 5)\n+                loc.x += random.uniform(-radius, radius)\n+                loc.y += random.uniform(-radius, radius)\n                 loc.z += 0.5\n                 model = shop.get(name, {}).get('usemodel')\n",
                        "comment": "Update the convertor itself to handle custom positions and radius."
                    }
                ]
            },
            "text": "Fixed scene 2 garage stuff"
        },
        "1784811628": {
            "comment": "A typo \"bitten\" is \"beaten\"",
            "added": [],
            "changed": [
                "/Scripts/Online.py"
            ],
            "changed_diffs": {
                "/Scripts/Online.py": [
                    {
                        "diff": "@@ -131,7 +131,7 @@\n         if regular_stats[stat].get(\"had_some\") and not regular_stats[stat].get(\"checked\"):\n             title = str(regular_stats[stat].get(\"title\", stat))\n-            UI.Print(\"You have bitten your own personal record \\n of \"+title+\".\",\n+            UI.Print(\"You have beaten your own personal record \\n of \"+title+\".\",\n                      important=True)\n             regular_stats[stat][\"checked\"] = True\n",
                        "comment": "THis"
                    },
                    {
                        "diff": "@@ -150,7 +150,7 @@\n                 if stat not in regular_stats[stat][\"online\"][user]:\n                     title = str(regular_stats[stat].get(\"title\", stat))\n-                    UI.Print(\"You have bitten a record of \\n \"+user+\" \\n of \"+title+\".\",\n+                    UI.Print(\"You have beaten a record of \\n \"+user+\" \\n of \"+title+\".\",\n                              important=True)\n                     regular_stats[stat][\"online\"][user].append(stat)\n",
                        "comment": "and this"
                    }
                ]
            },
            "text": "Typo fix"
        },
        "1784812551": {
            "comment": "Implemented a 10 second timer since the spawn of the other racers. If they are stuck or can't get to the race for one reason or another, you will still be able to start the race. ",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Racing.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Racing.py": [
                    {
                        "diff": "@@ -729,6 +729,9 @@\n                 reached.append(racer)\n         if reached:\n             havespawned = True\n+    if race.get(\"spawned_at\") and race.get(\"spawned_at\", 0) + 10 < bge.logic.getRealTime():\n+        havespawned = True\n     SPAWNEDCHECK = ( havespawned or\n                      ( forspawn and not havespawned )\n",
                        "comment": "This is the if statement that does the thing."
                    },
                    {
                        "diff": "@@ -1095,6 +1098,7 @@\n         car[\"dist_to_race\"] = 10000\n         car[\"racing\"] = False\n         race[\"racers\"].append(car)\n+        race[\"spawned_at\"] = bge.logic.getRealTime()\n         # Making drive towards the race\n",
                        "comment": "And that is where the timer is set."
                    }
                ]
            },
            "text": "Made so you can start race even if the others are stuck arriving."
        },
        "1784813711": {
            "comment": "Now when driving at night you have headlights showing you the way.",
            "added": [],
            "changed": [
                "/Scripts/Character.py",
                "/Scripts/GameTime.py"
            ],
            "changed_diffs": {
                "/Scripts/Character.py": [
                    {
                        "diff": "@@ -1533,6 +1533,14 @@\n         scene.objects[\"Gage.001\"].visible = False\n         bge.render.showMouse(False)\n+        # Front lights\n+        if car.get(\"night-light\"):\n+            light = car.get(\"night-light\")\n+            light.removeParent()\n+            Reuse.Delete(light)\n+            car[\"night-light\"] = None\n         if not character.get(\"walkingtowardcar\"):\n             character[\"walking_started\"] = bge.logic.getRealTime()\n",
                        "comment": "Removing the headlights when getting out of the car."
                    }
                ],
                "/Scripts/GameTime.py": [
                    {
                        "diff": "@@ -114,6 +114,26 @@\n     timeIs = bge.logic.globalDict[\"time\"]\n+    # The light of the car, to look forward.\n+    if not car.get(\"night-light\"):\n+        light = Reuse.Create(\"Area_Lamp\")\n+        light.scaling = [0.5,0.5,0.5]\n+        light.blenderObject.data = light.blenderObject.data.copy()\n+        light.blenderObject.data.energy = 1000\n+        light.blenderObject.data.shape = \"DISK\"\n+        light.position = Vehicle.RelativePoint(car, (0,-2.5,2))\n+        light.orientation = car.orientation.copy()\n+        light.applyRotation((-math.pi / 2,\n+                             0,\n+                             0), True)\n+        light.setParent(car)\n+        car[\"night-light\"] = light\n     # If it is day, do nothing\n     onTheRoad = Vehicle.NearRoad(car) < 50\n     if ( 7 < timeIs < 18 ) or not onTheRoad:\n",
                        "comment": "Adding headlights in the car."
                    }
                ]
            },
            "text": "Night light"
        },
        "1784813755": {
            "comment": "Mistake",
            "added": [],
            "changed": [
                "/Scripts/GameTime.py"
            ],
            "changed_diffs": {
                "/Scripts/GameTime.py": [
                    {
                        "diff": "@@ -114,6 +114,8 @@\n     timeIs = bge.logic.globalDict[\"time\"]\n+    if ( 7 < timeIs < 18 ):\n+        return\n     # The light of the car, to look forward.\n",
                        "comment": "Fix"
                    },
                    {
                        "diff": "@@ -136,7 +138,7 @@\n     # If it is day, do nothing\n     onTheRoad = Vehicle.NearRoad(car) < 50\n-    if ( 7 < timeIs < 18 ) or not onTheRoad:\n+    if not onTheRoad:\n         return\n     # Initilize 2 street lights\n",
                        "comment": "Fix"
                    }
                ]
            },
            "text": "Shit"
        },
        "1784813908": {
            "comment": "Forgot, scooters should not have that.",
            "added": [],
            "changed": [
                "/Scripts/GameTime.py"
            ],
            "changed_diffs": {
                "/Scripts/GameTime.py": [
                    {
                        "diff": "@@ -118,8 +118,8 @@\n         return\n     # The light of the car, to look forward.\n-    if not car.get(\"night-light\"):\n+    if not car.get(\"night-light\") and not car[\"specs\"].get(\"type\") == \"skating vehicle\":\n         light = Reuse.Create(\"Area_Lamp\")\n         light.scaling = [0.5,0.5,0.5]\n         light.blenderObject.data = light.blenderObject.data.copy()\n",
                        "comment": "Added an exception for scooters."
                    }
                ]
            },
            "text": "Night light no scooter"
        },
        "1784835920": {
            "comment": "There was a bug where on restore, object's attached to the car, would be placed a bit higher than they should. This fix seems to have fixed the bug.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -7425,7 +7425,8 @@\n def ObjectToRelativePoint(car, obj,\n                           position=(0,0,0),\n-                          orientation=(0,0,0)):\n+                          orientation=(0,0,0),\n+                          add_velocity=True):\n     # This function will take an object, like the attachments, we\n     # recorded in FromRelativeObject() and restore it as precisely\n",
                        "comment": "added an option to ignore velocity"
                    },
                    {
                        "diff": "@@ -7443,8 +7444,10 @@\n     obj.orientation.rotate( car.orientation )\n     obj.position.rotate( car.orientation )\n     obj.position += car.position\n-    obj.position += car.worldLinearVelocity / FPS\n-    obj.orientation.rotate( mathutils.Euler( car.worldAngularVelocity / FPS ) )\n+    if add_velocity:\n+        obj.position += car.worldLinearVelocity / FPS\n+        obj.orientation.rotate( mathutils.Euler( car.worldAngularVelocity / FPS ) )\n def EncodeRotation(car):\n",
                        "comment": "This is the option in action."
                    },
                    {
                        "diff": "@@ -7703,7 +7706,8 @@\n                 try:\n                     rot = mathutils.Matrix(rot)\n                 except: rot = [0,0,0]\n-                ObjectToRelativePoint(car, obj, loc, rot)\n+                ObjectToRelativePoint(car, obj, loc, rot,\n+                                      network)\n             Attach(car, obj, True, objdata.get(\"health\", 1))\n",
                        "comment": "And made it so velocity is ignored is this is not a network update."
                    }
                ]
            },
            "text": "Option to ignore velocity on restore"
        },
        "1784887616": {
            "comment": "Tweaked the position, rotation and power of the lamp, for the front lights, to make it easier to see where you are going at night.",
            "added": [],
            "changed": [
                "/Scripts/GameTime.py"
            ],
            "changed_diffs": {
                "/Scripts/GameTime.py": [
                    {
                        "diff": "@@ -119,16 +119,16 @@\n     # The light of the car, to look forward.\n-    if not car.get(\"night-light\") and not car[\"specs\"].get(\"type\") == \"skating vehicle\":\n+    if not car.get(\"night-light\") and not car[\"specs\"].get(\"type\") in ( \"skating vehicle\", \"kart\" ):\n         light = Reuse.Create(\"Area_Lamp\")\n-        light.scaling = [0.5,0.5,0.5]\n+        light.scaling = [5,5,5]\n         light.blenderObject.data = light.blenderObject.data.copy()\n-        light.blenderObject.data.energy = 1000\n+        light.blenderObject.data.energy = 10000\n         light.blenderObject.data.shape = \"DISK\"\n-        light.position = Vehicle.RelativePoint(car, (0,-2.5,2))\n+        light.position = Vehicle.RelativePoint(car, (0,-10,8))\n         light.orientation = car.orientation.copy()\n-        light.applyRotation((-math.pi / 2,\n+        light.applyRotation((-math.pi / 3,\n                              0,\n                              0), True)\n",
                        "comment": "Changes. ( notice, added Kart to ignored vehicles )"
                    }
                ]
            },
            "text": "Tweaked front-lights"
        },
        "1784980036": {
            "comment": "I realized that when My Car is despawned, to spawn in some NPCs car, that NPC car now has the My Car tag on it. And that populates the game with endless records of My Car.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -899,7 +899,7 @@\n     SetMyCar(car)\n-def SetMyCar(car):\n+def SetMyCar(car, now=False):\n     # The idea is to make it so when the player drives their car\n     # ( which could be very expencive and, into which, a lot of\n",
                        "comment": "Added an option to set my car on the spot."
                    },
                    {
                        "diff": "@@ -911,7 +911,7 @@\n     # garage.\n     carsInGarage = Garage.Inside()\n-    if car in carsInGarage and str(car.get(\"driver\")) == \"Dani_Box\":\n+    if ( car in carsInGarage and str(car.get(\"driver\")) == \"Dani_Box\" ) or now:\n         if not IsMyCar(car):\n             print(consoleForm(car), \"Set as My Car\")\n",
                        "comment": "This is the logic itself that allows for setting My Car on the spot."
                    },
                    {
                        "diff": "@@ -945,6 +945,7 @@\n             except:\n                 pass\n             print(consoleForm(car), \" my car has been restored.\")\n+            SetMyCar(car, now=True)\n def DespawnMyCar(car):\n",
                        "comment": "Setting My Car on the spot when re-spawning it."
                    },
                    {
                        "diff": "@@ -957,7 +958,7 @@\n     cardata = Encode(car)\n     bge.logic.globalDict[\"my-cars\"][addr][ID] = cardata\n     print(consoleForm(car), \" my car has been temporarely despawned.\")\n+    UnsetMyCar(car)\n def JoystickControl(car):\n",
                        "comment": "Unsetting My Car when despawning it."
                    }
                ]
            },
            "text": "Optimization of My Car"
        },
        "1785082677": {
            "comment": "Adding a code manager, to make a full documentation of the code-base.",
            "added": [
                "//docs.json",
                "/Scripts/CodeManager.py"
            ],
            "changed": [
                "//notgit.py",
                "//run.py",
                "//grabbed.txt"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -10,7 +10,10 @@\n import zlib\n import urllib.request\n+from Scripts import CodeManager\n from Scripts.Common import *\n fetchurl = \"https://blenderdumbass.org/danisrace/json/\"\n downloadurl = \"https://blenderdumbass.org/danisrace/download\"\n",
                        "comment": "Adding the CodeManager into notgit for testing."
                    },
                    {
                        "diff": "@@ -436,6 +439,15 @@\n             t = sys.argv[2]\n             Download(t)\n         except: pass\n+    if sys.argv[1] == \"cm\":\n+        tree = CodeManager.getCodeTree()\n+        for i in tree:\n+            print()\n+            print( i )\n+            print()\n+            print( tree[i] )\n",
                        "comment": "The test as of now is `cm`"
                    }
                ],
                "//run.py": [
                    {
                        "diff": "@@ -23,6 +23,7 @@\n from Scripts.Multiplayer import client\n from Scripts import Race_Manager\n+from Scripts import CodeManager\n #         V   E   R   S   I   O   N  \n #\n",
                        "comment": "Adding the CodeManager into the launcher."
                    },
                    {
                        "diff": "@@ -2130,6 +2131,12 @@\n ################### ACCOUNT MANAGER ####################\n+CodeButton = Gtk.Button(\"\ud83d\udcda Documentaion\")\n+CodeButton.connect(\"clicked\", CodeManager.DocsUI)\n+playbox.pack_start(CodeButton, 0,5,5)\n accountButton = Gtk.Button(\"\ud83d\udc71 Account\")\n accountButton.set_relief(Gtk.ReliefStyle.NONE)\n pannel.pack_end(accountButton)\n",
                        "comment": "Adding Code Manager UI into Launcher ( the UI is not even started development )"
                    }
                ],
                "//grabbed.txt": []
            },
            "text": "Adding code reviewer."
        },
        "1785097301": {
            "comment": "Now the UI of the code reviewer finally functions.",
            "added": [],
            "changed": [
                "//notgit.py",
                "//docs.json",
                "/Scripts/CodeManager.py"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -75,7 +75,7 @@\n def GETCWD():\n     return __file__[:__file__.rfind(\"/\")]+\"/\"\n-def ListFiles():\n+def ListFiles(checksum=True):\n     # Lists all Dani's Race files in the current folder.\n",
                        "comment": "Added an ability to not check checksums in notgit.py for faster files listing."
                    },
                    {
                        "diff": "@@ -97,7 +97,8 @@\n             if not fail:\n                 data[shortname] = {}\n-                data[shortname][\"md5\"] = hashlib.md5(open(fil,'rb').read()).hexdigest()\n+                if checksum:\n+                    data[shortname][\"md5\"] = hashlib.md5(open(fil,'rb').read()).hexdigest()\n                 data[shortname][\"timestamp\"] = os.path.getctime(fil)\n                 data[shortname][\"size\"] = os.path.getsize(fil)\n     return data\n",
                        "comment": "this is the code"
                    },
                    {
                        "diff": "@@ -443,11 +444,11 @@\n     if sys.argv[1] == \"cm\":\n         tree = CodeManager.getCodeTree()\n-        for i in tree:\n-            print()\n-            print( i )\n-            print()\n-            print( tree[i] )\n+        # for i in tree:\n+        #     print()\n+        #     print( i )\n+        #     print()\n+        #     print( tree[i] )\n",
                        "comment": "No longer doing tests in notgit.py"
                    }
                ],
                "//docs.json": [
                    {
                        "diff": "@@ -5089,27 +5643,50 @@\n             \"SendFile\": {\n                 \"type\": \"function\",\n                 \"description\": \"\",\n-                \"arguments\": {}\n+                \"arguments\": {\n+                    \"url\": {\n+                        \"description\": \"\"\n+                    },\n+                    \"filename\": {\n+                        \"description\": \"\"\n+                    }\n+                }\n             },\n             \"RecieveData\": {\n                 \"type\": \"function\",\n                 \"description\": \"\",\n-                \"arguments\": {}\n+                \"arguments\": {\n+                    \"url\": {\n+                        \"description\": \"\"\n+                    }\n+                }\n             },\n             \"SendAccount\": {\n                 \"type\": \"function\",\n                 \"description\": \"\",\n-                \"arguments\": {}\n+                \"arguments\": {\n+                    \"filename\": {\n+                        \"description\": \"\"\n+                    }\n+                }\n             },\n             \"SendRacingRecord\": {\n                 \"type\": \"function\",\n                 \"description\": \"\",\n-                \"arguments\": {}\n+                \"arguments\": {\n+                    \"filename\": {\n+                        \"description\": \"\"\n+                    }\n+                }\n             },\n             \"SendCustomRace\": {\n                 \"type\": \"function\",\n                 \"description\": \"\",\n-                \"arguments\": {}\n+                \"arguments\": {\n+                    \"filename\": {\n+                        \"description\": \"\"\n+                    }\n+                }\n             },\n             \"GetOnlineLeaderBoard\": {\n                 \"type\": \"function\",\n",
                        "comment": "\u001b[3~"
                    }
                ],
                "/Scripts/CodeManager.py": []
            },
            "text": "Code reviewer rendering / searching."
        },
        "1785100063": {
            "comment": "Made it so now I could populate the docs with valuable data.",
            "added": [],
            "changed": [
                "//notgit.py",
                "//docs.json",
                "/Scripts/CodeManager.py"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -161,7 +161,9 @@\n             if fil not in changed_diffs:\n                 changed_diffs[fil] = []\n+            if \"docs.json\" in fil:\n+                continue\n             try:\n                 f1 = open(GETCWD()+\".notgit/prevcopy/\"+copyname, \"r\").read()\n",
                        "comment": "Made it so I don't need to explain changed docs."
                    }
                ],
                "//docs.json": [],
                "/Scripts/CodeManager.py": [
                    {
                        "diff": "@@ -74,36 +74,18 @@\n             if thing.endswith(\".py\"):\n                 functions = getPythonFunctions(thing)\n-                old_functions = thing_data.get(\"fucntions\", {})\n+                old_functions = docs.get(thing, {}).get(\"functions\", {})\n                 # adding new stuff\n                 for func in functions:\n-                    if func not in old_functions:\n-                        old_functions[func] = functions[func]\n-                    else:\n-                        f_data = fuctions[func]\n-                        old_f_data = old_functions[func]\n-                        if \"arguments\" not in old_f_data:\n-                            old_f_data[\"arguments\"] = {}\n-                        for arg in f_data.get(\"arguments\", {}):\n-                            if arg not in old_f_data.get(\"arguments\", {}):\n-                                old_f_data[\"arguments\"][arg] = f_data[arg]\n-                for func in list(old_functions.keys()):\n-                    if func not in functions:\n-                        del old_functions[func]\n-                    else:\n-                        f_data = functions[func]\n-                        old_f_data = old_functions[func]\n-                        for arg in list(old_f_data.keys()):\n-                            if arg not in f_data:\n-                                del old_f_data[arg]\n-                thing_data[\"functions\"] = old_functions\n+                    desc = old_functions.get(func, {}).get(\"description\", \"\")\n+                    functions[func][\"description\"] = desc\n+                    for arg in functions[func].get(\"arguments\", {}):\n+                        desc = old_functions.get(func, {}).get(\"arguments\", {}).get(arg, {}).get(\"description\", \"\")\n+                        functions[func][\"arguments\"][arg][\"description\"] = desc\n+                thing_data[\"functions\"] = functions\n             docs[thing] = thing_data\n",
                        "comment": "Made a much better loading of docs data. Such that it will add new functions and arguments without destroying data about the old ones."
                    },
                    {
                        "diff": "@@ -211,6 +193,9 @@\n     return file_data\n+all_text_buffers = {}\n def DocsUI(w):\n     # This implements UI for the docs inside\n",
                        "comment": "A place to store GTK text buffers for editing to work."
                    },
                    {
                        "diff": "@@ -220,7 +205,8 @@\n     Window = Gtk.Dialog(\"Dani's Race Documentation\",\n-                               buttons=(Gtk.STOCK_OK, Gtk.ResponseType.OK),\n+                               buttons=(Gtk.STOCK_SAVE, Gtk.ResponseType.OK,\n+                                        Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL),\n                                )\n     Window.set_size_request(500, 400)\n",
                        "comment": "Added a Save button to the dialogue"
                    },
                    {
                        "diff": "@@ -260,10 +246,10 @@\n             thingBox = Gtk.VBox()\n             folexpander.add(thingBox)\n-            def onExpander(exp, data, thingBox):\n+            def onExpander(exp, thing, data, thingBox):\n                 was_expanded = exp.get_expanded()\n                 if not was_expanded:\n-                    w = RenderSingeFile(data)\n+                    w = RenderSingeFile(thing, data)\n                     thingBox.pack_start(w, 0,1,1,)\n                     thingBox.show_all()\n",
                        "comment": "Added a full path"
                    },
                    {
                        "diff": "@@ -272,7 +258,7 @@\n                         i.destroy()\n-            folexpander.connect(\"activate\", onExpander, docs_plus_search[thing], thingBox)\n+            folexpander.connect(\"activate\", onExpander, thing, docs_plus_search[thing], thingBox)\n",
                        "comment": "to"
                    },
                    {
                        "diff": "@@ -282,10 +268,14 @@\n     RefreshBox(box)\n     Window.show_all()\n-    Window.run()\n+    resp = Window.run()\n+    if resp == Gtk.ResponseType.OK:\n+        SaveFromUI()\n     Window.destroy()\n-def RenderSingeFile(filedata):\n+def RenderSingeFile(filename, filedata):\n     box = Gtk.VBox()\n",
                        "comment": "everying"
                    },
                    {
                        "diff": "@@ -295,18 +285,20 @@\n     thingBuffer = thingDescription.get_buffer()\n     thingBuffer.set_text(description)\n+    all_text_buffers[filename] = thingBuffer\n     box.pack_start(thingDescription, 0,1,1)\n     if \"functions\" in filedata:\n         for func in filedata[\"functions\"]:\n-            function = RenderFunction(func, filedata[\"functions\"][func])\n+            function = RenderFunction(filename, func, filedata[\"functions\"][func])\n             box.pack_start(function, 0,5,5)\n     return box\n-def RenderFunction(func, funcdata):\n+def RenderFunction(filename, func, funcdata):\n     box = Gtk.HBox()\n     expander = Gtk.Expander(label=func+\"()\")\n",
                        "comment": "everywhere"
                    },
                    {
                        "diff": "@@ -321,17 +313,19 @@\n     thingBuffer = thingDescription.get_buffer()\n     thingBuffer.set_text(description)\n+    all_text_buffers[filename+\"/\"+func] = thingBuffer\n     funcbox.pack_start(thingDescription, 0,1,1)\n     for arg in funcdata.get(\"arguments\", {}):\n-        w = RenderArgument(arg, funcdata[\"arguments\"][arg])\n+        w = RenderArgument(filename, func, arg, funcdata[\"arguments\"][arg])\n         funcbox.pack_start(w, 0,5,5)\n         funcbox.pack_start(Gtk.HSeparator(), 0,5,5)\n     return box\n-def RenderArgument(arg, argdata):\n+def RenderArgument(filename, func, arg, argdata):\n     box = Gtk.HBox()\n",
                        "comment": "so"
                    },
                    {
                        "diff": "@@ -351,11 +345,59 @@\n     thingBuffer = thingDescription.get_buffer()\n     thingBuffer.set_text(description)\n+    all_text_buffers[filename+\"/\"+func+\"/\"+arg] = thingBuffer\n     descbox.pack_start(thingDescription, 1,5,5)\n     return box\n+def SaveFromUI():\n+    docs = getCodeTree()\n+    for filename in list(docs.keys()):\n+        desc = all_text_buffers.get(filename)\n+        if desc:\n+            desc = desc.get_text(\n+                desc.get_start_iter(),\n+                desc.get_end_iter(),\n+                True\n+            )\n+            docs[filename][\"description\"] = desc\n+        for func in list(docs[filename].get(\"functions\", {}).keys()):\n+            url = filename+\"/\"+func\n+            desc = all_text_buffers.get(url)\n+            if desc:\n+                desc = desc.get_text(\n+                    desc.get_start_iter(),\n+                    desc.get_end_iter(),\n+                    True\n+                )\n+                docs[filename][\"functions\"][func][\"description\"] = desc\n+            for arg in list(docs[filename].get(\"functions\", {}).get(func, {}).get(\"arguments\", {}).keys()):\n+                url = filename+\"/\"+func+\"/\"+arg\n+                desc = all_text_buffers.get(url)\n+                if desc:\n+                    desc = desc.get_text(\n+                        desc.get_start_iter(),\n+                        desc.get_end_iter(),\n+                        True\n+                    )\n+                    docs[filename][\"functions\"][func][\"arguments\"][arg][\"description\"] = desc\n+    saveDocs(os.getcwd(), docs)\n def search_docs(docs, searchterm):\n     # Searching through the docs\n",
                        "comment": "This could be done."
                    }
                ]
            },
            "text": "Code reviewer editing comments."
        },
        "1785105081": {
            "comment": "Added some documentation",
            "added": [],
            "changed": [
                "//docs.json"
            ],
            "changed_diffs": {
                "//docs.json": []
            },
            "text": "Did some Documentation"
        },
        "1785105437": {
            "comment": "Now you can search though descriptions too.",
            "added": [],
            "changed": [
                "/Scripts/CodeManager.py"
            ],
            "changed_diffs": {
                "/Scripts/CodeManager.py": [
                    {
                        "diff": "@@ -411,7 +411,7 @@\n     newdocs = {}\n     for thing in docs:\n-        if searchterm.lower() in thing.lower():\n+        if searchterm.lower() in thing.lower() or searchterm.lower() in str(docs[thing].get(\"description\")).lower():\n             newdocs[thing] = docs[thing]\n         if docs[thing].get(\"functions\"):\n",
                        "comment": "This made it possible."
                    }
                ]
            },
            "text": "Code Search in Description"
        },
        "1785105825": {
            "comment": "Made the search less broken.",
            "added": [],
            "changed": [
                "/Scripts/CodeManager.py"
            ],
            "changed_diffs": {
                "/Scripts/CodeManager.py": [
                    {
                        "diff": "@@ -411,20 +411,27 @@\n     newdocs = {}\n     for thing in docs:\n         if searchterm.lower() in thing.lower() or searchterm.lower() in str(docs[thing].get(\"description\")).lower():\n             newdocs[thing] = docs[thing]\n-        if docs[thing].get(\"functions\"):\n-            docs[thing] = docs[thing].copy()\n-            docs[thing][\"functions\"] = search_docs(docs[thing][\"functions\"], searchterm)\n-            if docs[thing][\"functions\"]:\n-                newdocs[thing] = docs[thing]\n-        if docs[thing].get(\"arguments\"):\n-            docs[thing] = docs[thing].copy()\n-            docs[thing][\"arguments\"] = search_docs(docs[thing][\"arguments\"], searchterm)\n-            if docs[thing][\"arguments\"]:\n-                newdocs[thing] = docs[thing]\n+        else:\n+            if docs[thing].get(\"arguments\"):\n+                docs[thing] = docs[thing].copy()\n+                docs[thing][\"arguments\"] = search_docs(docs[thing][\"arguments\"], searchterm)\n+                if docs[thing][\"arguments\"]:\n+                    newdocs[thing] = docs[thing]\n+            if docs[thing].get(\"functions\"):\n+                docs[thing] = docs[thing].copy()\n+                docs[thing][\"functions\"] = search_docs(docs[thing][\"functions\"], searchterm)\n+                if docs[thing][\"functions\"]:\n+                    newdocs[thing] = docs[thing]\n     ranked = {}\n",
                        "comment": "This"
                    }
                ]
            },
            "text": "Rearanged Code Search for better search"
        },
        "1785122409": {
            "comment": "I was doing documentation of the codebase and stumbled upon a weird little quark in one of the functions.",
            "added": [],
            "changed": [
                "//docs.json",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//docs.json": [],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -1174,7 +1174,7 @@\n             getCarPhysics(car).applyBraking(0, n)\n     # Stablizing the brakes\n-    if stable and car[\"specs\"].get(\"stableBrake\", True):\n+    if stable and car[\"specs\"].get(\"stableBrake\", True) and not car.get(\"drifting\"):\n         r = car.localAngularVelocity[2]\n         car.applyTorque([0,0,-r*car.mass*20], True)\n",
                        "comment": "This stable thing. So I added a \"drifting\" into it. And it feels a bit less broken."
                    }
                ]
            },
            "text": "Fixed drifting?"
        },
        "1785127725": {
            "comment": "more docs",
            "added": [],
            "changed": [
                "//docs.json"
            ],
            "changed_diffs": {
                "//docs.json": []
            },
            "text": "More docs"
        },
        "1785220348": {
            "comment": "It has a problem. For optimization it doesn't render all the docs at once in GTK. So when you collaps and reopen something, it would delete all your changes to all of the file. Now its fixed. And the changes are preserved.",
            "added": [],
            "changed": [
                "//docs.json",
                "/Scripts/CodeManager.py"
            ],
            "changed_diffs": {
                "//docs.json": [],
                "/Scripts/CodeManager.py": [
                    {
                        "diff": "@@ -236,7 +236,7 @@\n         docs_plus_search = search_docs(docs, searchterm)\n-        for thing in docs_plus_search:\n+        for thing in SortedByLength(docs_plus_search):\n",
                        "comment": "First of all I made it sort the docs by the length of the data. This puts bigger ( potentially more important things ) to the top of the list."
                    },
                    {
                        "diff": "@@ -285,7 +285,7 @@\n     thingBuffer = thingDescription.get_buffer()\n     thingBuffer.set_text(description)\n-    all_text_buffers[filename] = thingBuffer\n+    SaveOrRetrieveTextBuffer(filename, thingBuffer)\n     box.pack_start(thingDescription, 0,1,1)\n",
                        "comment": "Change the way I store buffers for saving."
                    },
                    {
                        "diff": "@@ -313,7 +313,8 @@\n     thingBuffer = thingDescription.get_buffer()\n     thingBuffer.set_text(description)\n-    all_text_buffers[filename+\"/\"+func] = thingBuffer\n+    #all_text_buffers[filename+\"/\"+func] = thingBuffer\n+    SaveOrRetrieveTextBuffer(filename+\"/\"+func, thingBuffer)\n     funcbox.pack_start(thingDescription, 0,1,1)\n",
                        "comment": "in more than one place."
                    },
                    {
                        "diff": "@@ -345,12 +346,15 @@\n     thingBuffer = thingDescription.get_buffer()\n     thingBuffer.set_text(description)\n-    all_text_buffers[filename+\"/\"+func+\"/\"+arg] = thingBuffer\n+    SaveOrRetrieveTextBuffer(filename+\"/\"+func+\"/\"+arg, thingBuffer)\n     descbox.pack_start(thingDescription, 1,5,5)\n     return box\n+def SortedByLength(data):\n+    data = {k:data[k] for k in sorted(data, key=lambda y: len(str(data[y])), reverse=True)}\n+    return data\n def SaveFromUI():\n",
                        "comment": "This is the function that sorts the dict by the length of the data. It does basic comparison of length of the string-form of the data in question. "
                    },
                    {
                        "diff": "@@ -397,7 +401,24 @@\n     saveDocs(os.getcwd(), docs)\n+def SaveOrRetrieveTextBuffer(ID, TextBuffer):\n+    if not all_text_buffers.get(ID):\n+        all_text_buffers[ID] = TextBuffer\n+    else:\n+        desc = all_text_buffers[ID]\n+        text = desc.get_text(\n+            desc.get_start_iter(),\n+            desc.get_end_iter(),\n+            True\n+        )\n+        TextBuffer.set_text( text )\n+        all_text_buffers[ID] = TextBuffer\n def search_docs(docs, searchterm):\n     # Searching through the docs\n",
                        "comment": "This is the function that lets me retrieve text changes."
                    }
                ]
            },
            "text": "Made docs editing less broken"
        },
        "1785221468": {
            "comment": "Characters no longer have hair as a separate object ( for a long time ). Removed the hair from the code.",
            "added": [],
            "changed": [
                "/Scripts/Character.py"
            ],
            "changed_diffs": {
                "/Scripts/Character.py": [
                    {
                        "diff": "@@ -675,10 +675,10 @@\n     # world.\n     body = character.childrenRecursive.get(\"Body\")\n-    hair = character.childrenRecursive.get(\"Body.002\")\n+    #hair = character.childrenRecursive.get(\"Body.002\")\n     if body.visible != render:\n         body.visible = render\n-        hair.visible = render\n+        #hair.visible = render\n def hintAvailableCars(character, closest=10):\n",
                        "comment": "Here"
                    }
                ]
            },
            "text": "Removed a bug in Render."
        },
        "1785236527": {
            "comment": "More docs",
            "added": [],
            "changed": [
                "//docs.json"
            ],
            "changed_diffs": {
                "//docs.json": []
            },
            "text": "More docs"
        },
        "1785237061": {
            "comment": "Some lines of files have comments right inside of the line. I had a problem cleaning those up. So I removed thing after a space. But it rendered some arguments not full.",
            "added": [],
            "changed": [
                "//docs.json",
                "/Scripts/Race_Manager.py",
                "/Scripts/CodeManager.py"
            ],
            "changed_diffs": {
                "//docs.json": [],
                "/Scripts/Race_Manager.py": [],
                "/Scripts/CodeManager.py": [
                    {
                        "diff": "@@ -113,6 +113,9 @@\n     file_data = {}\n     for line in python_file.split(\"\\n\"):\n+        if \"#\" in line:\n+            line = line[:line.find(\"#\")]\n         if line.startswith(\"class \") or \"_class_\".replace(\"_\", \" \") in line: # the _ is to avoid it finding itself.\n             current_class = line[line.find(\"class \")+len(\"class \"):]\n",
                        "comment": "This removes all comments before parsing the lines. Ahead of everything."
                    },
                    {
                        "diff": "@@ -172,12 +175,12 @@\n                     if \"=\" in v:\n                         v, dv = v.split(\"=\")\n-                        if \" \" in v:\n-                            v = v[v.rfind(\" \"):]\n+                        #if \" \" in v:\n+                        #    v = v[v.rfind(\" \"):]\n                         v = v.strip()\n                         dv = dv.strip()\n-                        if \" \" in dv:\n-                            dv = dv[:dv.find(\" \")]\n+                        #if \" \" in dv:\n+                        #    dv = dv[:dv.find(\" \")]\n                     if v:\n",
                        "comment": "And so I removed the spacebar stuff."
                    }
                ]
            },
            "text": "Better docs cleanup"
        },
        "1785238812": {
            "comment": "I noticed that I can slighly optimize the animation of fire elements.",
            "added": [],
            "changed": [
                "//docs.json",
                "/Scripts/Destruction.py"
            ],
            "changed_diffs": {
                "//docs.json": [],
                "/Scripts/Destruction.py": [
                    {
                        "diff": "@@ -152,6 +152,9 @@\n     if type(obj) == bge.types.SCA_PythonController:\n         obj = obj.owner\n+    if obj in Reuse.reuse.get(str(obj), []):\n+        return\n     # Alighining object to camera\n     vect = obj.getVectTo(cam)\n",
                        "comment": "If they are deleted by Reuse.Delete() you can not run the funtion."
                    }
                ]
            },
            "text": "Tiny optimization"
        },
        "1785245789": {
            "comment": "Done code docs.",
            "added": [],
            "changed": [
                "//docs.json"
            ],
            "changed_diffs": {
                "//docs.json": []
            },
            "text": "Done documenting code."
        },
        "1785328974": {
            "comment": "Made a few improvements. Mainly made search find more things. And made everything organized into folders.",
            "added": [],
            "changed": [
                "//docs.json",
                "/Scripts/CodeManager.py"
            ],
            "changed_diffs": {
                "//docs.json": [],
                "/Scripts/CodeManager.py": [
                    {
                        "diff": "@@ -238,31 +238,51 @@\n         docs_plus_search = search_docs(docs, searchterm)\n+        folder_widgets = {}\n         for thing in SortedByLength(docs_plus_search):\n-            folexpander = Gtk.Expander(label=thing)\n-            box.pack_start(folexpander, 0,5,5)\n-            thingBox = Gtk.VBox()\n-            folexpander.add(thingBox)\n-            def onExpander(exp, thing, data, thingBox):\n-                was_expanded = exp.get_expanded()\n-                if not was_expanded:\n-                    w = RenderSingeFile(thing, data)\n-                    thingBox.pack_start(w, 0,1,1,)\n-                    thingBox.show_all()\n+            prefol = \"\"\n+            for n, folder in enumerate(thing.split(\"/\")):\n+                fulfol = prefol+\"/\"+folder\n+                if fulfol.startswith(\"/\"):\n+                    fulfol = fulfol[1:]\n+                if fulfol and fulfol not in folder_widgets:\n-                else:\n-                    for i in thingBox.get_children():\n-                        i.destroy()\n+                    folexpander = Gtk.Expander(label=folder)\n+                    folexpander.set_margin_left(10)\n-            folexpander.connect(\"activate\", onExpander, thing, docs_plus_search[thing], thingBox)\n+                    if folder_widgets.get(prefol):\n+                        folder_widgets[prefol].pack_start(folexpander, 0,5,5)\n+                    else:\n+                        box.pack_start(folexpander, 0,5,5)\n+                    thingBox = Gtk.VBox()\n+                    folexpander.add(thingBox)\n+                    if fulfol == thing:\n+                        def onExpander(exp, thing, data, thingBox):\n+                            was_expanded = exp.get_expanded()\n+                            if not was_expanded:\n+                                w = RenderSingeFile(thing, data)\n+                                thingBox.pack_start(w, 0,1,1,)\n+                                thingBox.show_all()\n+                            else:\n+                                for i in thingBox.get_children():\n+                                    i.destroy()\n+                        folexpander.connect(\"activate\", onExpander, thing, docs_plus_search[thing], thingBox)\n+                    folder_widgets[fulfol] = thingBox\n+                prefol = fulfol\n         box.show_all()\n",
                        "comment": "Organizing everything into folders."
                    },
                    {
                        "diff": "@@ -430,11 +450,18 @@\n     if not searchterm:\n         return docs\n+    if \".\" in searchterm:\n+        searchterm = searchterm[searchterm.rfind(\".\")+1:]\n+    searchterm = searchterm.replace(\"()\", \"\")\n     docs = docs.copy()\n     newdocs = {}\n     for thing in docs:\n         if searchterm.lower() in thing.lower() or searchterm.lower() in str(docs[thing].get(\"description\")).lower():\n             newdocs[thing] = docs[thing]\n",
                        "comment": "Making if find functions like Vehicle.UpdateCar() while only having access to `UpdateCar` portion of the text in the data."
                    }
                ]
            },
            "text": "Improvements to Documentation's UI"
        },
        "1785338069": {
            "comment": "Now you can poke at blend files in the docs too. It took a while to make right",
            "added": [
                "/Scripts/dumpBlend.py"
            ],
            "changed": [
                "//notgit.py",
                "//docs.json",
                "/Scripts/CodeManager.py"
            ],
            "changed_diffs": {
                "//notgit.py": [
                    {
                        "diff": "@@ -446,14 +446,7 @@\n     if sys.argv[1] == \"cm\":\n         tree = CodeManager.getCodeTree()\n-        # for i in tree:\n-        #     print()\n-        #     print( i )\n-        #     print()\n-        #     print( tree[i] )\n-#data = FetchReport(1778100040)\n-#print( json.dumps(data, indent=4))\n+    if sys.argv[1] == \"blend_tree\":\n+        tree = CodeManager.generate_blendfiles_data()\n",
                        "comment": "Dumped some old test code and added a `blend_tree` funtion to notgit.py to parse all blend files in the folder and generate JSON data about them."
                    }
                ],
                "//docs.json": [],
                "/Scripts/CodeManager.py": [
                    {
                        "diff": "@@ -64,6 +64,10 @@\n             thing_data = {\n                 \"description\":docs.get(thing, {}).get(\"description\", \"\")\n             }\n+            if docs.get(thing, {}).get(\"collections\", \"\"):\n+                thing_data[\"collections\"] = docs.get(thing, {}).get(\"collections\", \"\")\n+            if docs.get(thing, {}).get(\"texts\", \"\"):\n+                thing_data[\"texts\"] = docs.get(thing, {}).get(\"texts\", \"\")\n             if thing == fol:\n                 thing_data[\"files\"] = []\n",
                        "comment": "The global `docs.json` mentions of blend files now have `collections` and `text` data generated separately ( since it takes time ). This code makes sure the data is kept when generating the rest of the JSON."
                    },
                    {
                        "diff": "@@ -93,13 +97,16 @@\n     saveDocs(folder, docs)\n     return docs\n-def getPythonFunctions(filename=\"run.py\"):\n+def getPythonFunctions(filename=\"run.py\", text=\"\"):\n     # This function parses a python file to get a list of specific\n     # function in that file.\n-    with open(filename, \"r\") as o:\n-        python_file = o.read()\n+    if filename:\n+        with open(filename, \"r\") as o:\n+            python_file = o.read()\n+    else:\n+        python_file = text\n     # We need to find all the top level structures\n     # Classes, Functions.\n",
                        "comment": "Added an ability for the python document parser to recieved raw input of python code. Useful when you want to part code that is save inside of a blend file, and not as its own file."
                    },
                    {
                        "diff": "@@ -319,6 +326,39 @@\n             function = RenderFunction(filename, func, filedata[\"functions\"][func])\n             box.pack_start(function, 0,5,5)\n+    if \"collections\" in filedata:\n+        for collection in filedata[\"collections\"]:\n+            col = RenderCollection(filename, collection, filedata[\"collections\"][collection])\n+            box.pack_start(col, 0,5,5)\n+    if \"texts\" in filedata:\n+        for text in filedata[\"texts\"]:\n+            folexpander = Gtk.Expander(label=text)\n+            folexpander.set_margin_left(10)\n+            folbox = Gtk.VBox()\n+            folexpander.add(folbox)\n+            def onExpander(exp, thing, data, thingBox):\n+                was_expanded = exp.get_expanded()\n+                if not was_expanded:\n+                    w = RenderSingeFile(thing, data)\n+                    thingBox.pack_start(w, 0,1,1,)\n+                    thingBox.show_all()\n+                else:\n+                    for i in thingBox.get_children():\n+                        i.destroy()\n+            folexpander.connect(\"activate\", onExpander, filename+\"/\"+text, filedata[\"texts\"][text], folbox)\n+            box.pack_start(folexpander, 0,5,5)\n     return box\n def RenderFunction(filename, func, funcdata):\n",
                        "comment": "Added UI for `collections` and `texts` data."
                    },
                    {
                        "diff": "@@ -375,6 +415,31 @@\n     return box\n+def RenderCollection(filename, collection, collectiondata):\n+    expander = Gtk.Expander(label=collection+\" ( \"+str(collectiondata.get(\"objects\", 0))+\" objects )\")\n+    expander.set_margin_left(10)\n+    box = Gtk.VBox()\n+    expander.add(box)\n+    description = str(collectiondata.get(\"description\"))\n+    thingDescription = Gtk.TextView()\n+    thingDescription.set_wrap_mode(Gtk.WrapMode.WORD)\n+    thingBuffer = thingDescription.get_buffer()\n+    thingBuffer.set_text(description)\n+    SaveOrRetrieveTextBuffer(filename+\"/\"+collection, thingBuffer)\n+    if collectiondata.get(\"library\"):\n+        box.pack_start(Gtk.Label(\"Linked from: \"+str(collectiondata.get(\"library\"))), 0,5,5)\n+    box.pack_start(thingDescription, 1,5,5)\n+    return expander\n def SortedByLength(data):\n     data = {k:data[k] for k in sorted(data, key=lambda y: len(str(data[y])), reverse=True)}\n     return data\n",
                        "comment": "Added a funtion to render collections data."
                    },
                    {
                        "diff": "@@ -420,7 +485,64 @@\n                     )\n                     docs[filename][\"functions\"][func][\"arguments\"][arg][\"description\"] = desc\n+        for col in list(docs[filename].get(\"collections\", {}).keys()):\n+            url = filename+\"/\"+col\n+            desc = all_text_buffers.get(url)\n+            if desc:\n+                desc = desc.get_text(\n+                    desc.get_start_iter(),\n+                    desc.get_end_iter(),\n+                    True\n+                )\n+                docs[filename][\"collections\"][col][\"description\"] = desc\n+        for text in list(docs[filename].get(\"texts\", {}).keys()):\n+            url = filename+\"/\"+text\n+            desc = all_text_buffers.get(url)\n+            if desc:\n+                desc = desc.get_text(\n+                    desc.get_start_iter(),\n+                    desc.get_end_iter(),\n+                    True\n+                )\n+                docs[filename][\"texts\"][text][\"description\"] = desc\n+            textdata = docs[filename][\"texts\"][text]\n+            thisfilename = url\n+            for func in list(textdata.get(\"functions\", {}).keys()):\n+                url = thisfilename+\"/\"+func\n+                desc = all_text_buffers.get(url)\n+                if desc:\n+                    desc = desc.get_text(\n+                        desc.get_start_iter(),\n+                        desc.get_end_iter(),\n+                        True\n+                    )\n+                    textdata[\"functions\"][func][\"description\"] = desc\n+                for arg in list(textdata.get(\"functions\", {}).get(func, {}).get(\"arguments\", {}).keys()):\n+                    url = thisfilename+\"/\"+func+\"/\"+arg\n+                    desc = all_text_buffers.get(url)\n+                    if desc:\n+                        desc = desc.get_text(\n+                            desc.get_start_iter(),\n+                            desc.get_end_iter(),\n+                            True\n+                        )\n+                        textdata[\"functions\"][func][\"arguments\"][arg][\"description\"] = desc\n     saveDocs(os.getcwd(), docs)\n",
                        "comment": "Added ability to save changes to various texts prompts in blend data."
                    },
                    {
                        "diff": "@@ -482,6 +604,21 @@\n                 if docs[thing][\"functions\"]:\n                     newdocs[thing] = docs[thing]\n+            if docs[thing].get(\"collections\"):\n+                docs[thing] = docs[thing].copy()\n+                docs[thing][\"collections\"] = search_docs(docs[thing][\"collections\"], searchterm)\n+                if docs[thing][\"collections\"]:\n+                    newdocs[thing] = docs[thing]\n+            if docs[thing].get(\"texts\"):\n+                docs[thing] = docs[thing].copy()\n+                docs[thing][\"texts\"] = search_docs(docs[thing][\"texts\"], searchterm)\n+                if docs[thing][\"texts\"]:\n+                    newdocs[thing] = docs[thing]\n",
                        "comment": "Added an option to search for things in the blend file."
                    },
                    {
                        "diff": "@@ -499,3 +636,56 @@\n     return finaldocs\n+def generate_blendfiles_data():\n+    # Sorry I'm lazy\n+    UPBGE = \"/home/vcs/Software/upbge-0.36.1-linux-x86_64/blender\"\n+    docs  = getCodeTree()\n+    files = notgit.ListFiles(checksum=False)\n+    for fil in files:\n+        if fil.endswith(\".blend\"):\n+            os.system(UPBGE+\" \"+os.getcwd()+fil+\" -b -P Scripts/dumpBlend.py\")\n+            while fil.startswith(\"/\"):\n+                fil = fil[1:]\n+            if docs.get(fil):\n+                with open(\"/tmp/dump_blend.json\") as o:\n+                    blenddata = json.load(o)\n+                for col in blenddata.get(\"collections\", {}):\n+                    desc = docs[fil].get(\"collections\", {}).get(col, {}).get(\"description\", \"\")\n+                    if desc:\n+                        blenddata[\"collections\"][col][\"description\"] = desc\n+                for text in blenddata.get(\"texts\", {}):\n+                    desc = docs[fil].get(\"texts\", {}).get(text, {}).get(\"description\", \"\")\n+                    if desc:\n+                        blenddata[\"texts\"][text][\"description\"] = desc\n+                    textdata = blenddata[\"texts\"].get(text, {})\n+                    for func in textdata.get(\"functions\", {}):\n+                        desc = docs[fil].get(\"texts\", {}).get(text, {}).get(\"functions\", {}).get(func, {}).get(\"description\", \"\")\n+                        if desc:\n+                            textdata[\"functions\"][func][\"description\"] = desc\n+                        funcdata = textdata[\"functions\"][func]\n+                        for arg in funcdata.get(\"arguments\", {}):\n+                            desc = docs[fil].get(\"texts\", {}).get(text, {}).get(\"functions\", {}).get(func, {}).get(\"arguments\", {}).get(arg, {}).get(\"description\", \"\")\n+                            if desc:\n+                                funcdata[\"arguments\"][arg][\"description\"] = desc\n+                for key in blenddata:\n+                    docs[fil][key] = blenddata[key]\n+    saveDocs(os.getcwd(), docs)\n",
                        "comment": "Added a function that goes over all blend files and generates data about them. ( It also preserves the old descriptions of everything ). Note, I wrote a dumpBlend.py file with simple bpy code, that runs with each blend file to output the actuall JSON data."
                    }
                ]
            },
            "text": "Added a whole concept of looks through documentations of blend files."
        },
        "1785339941": {
            "comment": "Added some descriptions of thing in assebly.blend",
            "added": [],
            "changed": [
                "//docs.json"
            ],
            "changed_diffs": {
                "//docs.json": []
            },
            "text": "Added documentation for assembly.blend"
        },
        "1785346638": {
            "comment": "Did a few changes to how the game handles full-screen. Now you can toggle it with F11. And it is a bit less broken all over the place. ",
            "added": [],
            "changed": [
                "//run.py",
                "//grabbed.txt",
                "//assembly.blend",
                "/Scripts/Main_update.py",
                "/Scripts/Settings.py"
            ],
            "changed_diffs": {
                "//run.py": [
                    {
                        "diff": "@@ -178,10 +178,10 @@\n         command = ['stdbuf', '-o0', blenderplayer]\n-        if data.get(\"fullscreen\", True):\n-            command.append(\"-f\")\n-        else:\n-            command.append(\"-w\")\n+        # if data.get(\"fullscreen\", True):\n+        #     command.append(\"-f\")\n+        # else:\n+        command.append(\"-w\")\n         command.append(data.get(\"resolution\", \"1920:1080\").split(\":\")[0])\n",
                        "comment": "Made it so the launcer always starts it as windowed."
                    }
                ],
                "//grabbed.txt": [],
                "//assembly.blend": [],
                "/Scripts/Main_update.py": [
                    {
                        "diff": "@@ -70,6 +70,17 @@\n     Mouse.DeactivateToggler()\n     Input.UnpressSimulatedPresses()\n+    if 98 in keys:\n+        timer = bge.logic.globalDict.get(\"fs_timer\", 0)\n+        if timer + 1 < bge.logic.getRealTime():\n+            fullscreen = bge.render.getFullScreen()\n+            resolush   = bge.render.getDisplayDimensions()\n+            bge.render.setWindowSize(*resolush)\n+            bge.render.setFullScreen(not fullscreen)\n+            bge.logic.globalDict[\"fs_timer\"] = bge.logic.getRealTime() \n     # Phone\n     Phone.MainLoop()\n",
                        "comment": "Make it so F11 toggles fullscreen."
                    }
                ],
                "/Scripts/Settings.py": [
                    {
                        "diff": "@@ -189,6 +189,8 @@\n         except Exception as e:\n             print(\"Error assigning controls\",e)\n+    bge.render.setFullScreen( data.get(\"fullscreen\", False ) ) \n def SaveGame():\n",
                        "comment": "And when loading the settings ( on the first frame of the game ) is where the game actually goes into fullscreen. Meaning you will see the loading progress bar going into fullscreen."
                    }
                ]
            },
            "text": "F11 to toggle fullscreen."
        },
        "1785358320": {
            "comment": "Make taxi a bit more challenging. Which made it a lot more fun.",
            "added": [],
            "changed": [
                "//grabbed.txt",
                "/Scripts/Vehicle.py"
            ],
            "changed_diffs": {
                "//grabbed.txt": [],
                "/Scripts/Vehicle.py": [
                    {
                        "diff": "@@ -6724,16 +6724,22 @@\n                         # Find the target ( where the person is going )\n-                        point = random.choice(list(Navigation.NavMesh.values()))\n-                        distance = car.getDistanceTo(point[\"location\"])\n-                        while distance < 300:# or len(point[\"connected\"]) > 1:\n+                        points = []\n+                        for i in range(3):\n                             point = random.choice(list(Navigation.NavMesh.values()))\n                             distance = car.getDistanceTo(point[\"location\"])\n+                            while distance < 300:# or len(point[\"connected\"]) > 1:\n+                                point = random.choice(list(Navigation.NavMesh.values()))\n+                                distance = car.getDistanceTo(point[\"location\"])\n+                            points.append([distance, point])\n+                        points = list(sorted(points, reverse=True))\n+                        point = points[0][1]\n                         car[\"target\"] = point[\"location\"]\n+                        # Find what sound line to speak\n                         closest = None\n                         distance = 1000000000\n                         for loc in Map.places:\n",
                        "comment": "This"
                    },
                    {
                        "diff": "@@ -6753,7 +6760,8 @@\n                             car[\"target\"])\n                         Phone.State[\"apps\"][\"MapApp\"][\"waypoint\"][\"path\"] = path\n-                        distance = Navigation.CalculateLength(path)\n+                        #distance = Navigation.CalculateLength(path)\n+                        distance = car.getDistanceTo(car[\"target\"])\n                         reward = CalculateTaxiFare(distance)\n                         TEDTT = bge.logic.globalDict[\"taxi_estimated_distance_to_time\"]\n",
                        "comment": "And this"
                    }
                ]
            },
            "text": "Did a Taxi thing."
        }
    }
}
